> For the complete documentation index, see [llms.txt](https://docs.moderncollections.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.moderncollections.io/clients/clients.md).

# Clients and MCP

The Python client, the mc-api CLI, the MCP server for agents, and generating your own client.

One package, `mc_api`, ships three front-ends over a single hardened HTTP client, so the library, the CLI and your agent tools all take the same code path:

| Front-end                | What it is                                     |
| ------------------------ | ---------------------------------------------- |
| `mc_api.client.MCClient` | A typed, synchronous Python client.            |
| `mc-api`                 | A CLI covering the same surface.               |
| `mc-api-mcp`             | An MCP stdio server exposing the API as tools. |

{% hint style="warning" %}
**Not on PyPI.** There is no `mc-api` or `moderncollections` package on the public index — do not install lookalikes. The package is distributed by Modern Collections during onboarding; the import name is `mc_api`.
{% endhint %}

```bash
pip install ./mc_api        # path to the provided package
```

There is **no JavaScript SDK** today and no `@moderncollections/*` package on npm. Use `fetch`, `axios` or `undici` against the REST API, or [generate a client](#generate-your-own-client).

## Configuration

All three front-ends read the same environment variables. Configuration never comes from command-line arguments or tool arguments, so your key stays out of shell history and MCP client config that may be logged.

| Variable          | Value                                                                                                                       |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `MC_API_ENV`      | `demo` or `prod`                                                                                                            |
| `MC_API_BASE_URL` | An explicit base URL — overrides `MC_API_ENV`                                                                               |
| `MC_API_KEY`      | `ca_<prefix>_<secret>` or `pa_<prefix>_<secret>`                                                                            |
| `MC_API_CREDITOR` | Which linked creditor a **partner** key acts on — a creditor UUID or its `external_creditor_ref`. Ignored for a `ca_…` key. |

**There is no production default.** A target must be selected explicitly, so a forgotten flag can never silently aim a test key at production. The CLI also accepts `--env` / `--base-url` as global options before the subcommand.

The key travels only in the `Authorization` header. It is never logged or printed, excluded from `repr()` output, and tool and CLI errors carry only the API's opaque `detail` and HTTP status.

## CLI

```bash
export MC_API_ENV=prod
export MC_API_KEY="ca_a3f8c0d1_..."

mc-api health
mc-api placements list --status in_outreach
mc-api placements create --company-name "Acme Inc." --invoice-amount 7500.00 --state TX
mc-api placements get <placement-id>
mc-api payments record <placement-id> --amount 2500.00 --idempotency-key pay-2026-08-03-01
mc-api disputes list --status open
```

The command tree mirrors the API surface — placements, payments, disputes, documents, evidence, remittances, statements, exports, settings, notifications, agreements, intake, analytics and the QuickBooks integration. Run `mc-api --help`, or `mc-api <group> --help`, for the current set of commands and flags; that output is generated from the client itself and cannot drift.

Add `--json` for machine-readable output. The CLI exits non-zero on API errors, so it composes in scripts.

Only idempotent `GET`s are auto-retried. `POST /v1/placements` is never auto-retried, by design, so a create cannot be duplicated.

## MCP server

`mc-api-mcp` is a **local stdio process** you run alongside your MCP client — there is no hosted MCP server at a public URL. It registers as `modern-collections` and exposes the creditor-API-key surface as `snake_case` tools — placements, documents and evidence, payments, disputes, remittances and statements, analytics and exports, settings and notifications, agreements, the QuickBooks integration, and intake.

**The server enumerates its own tools.** Point your client at it for the current list rather than working from a count on a documentation page.

### Register it

```json
{
  "mcpServers": {
    "modern-collections": {
      "command": "mc-api-mcp",
      "env": {
        "MC_API_ENV": "prod",
        "MC_API_KEY": "ca_REPLACE_WITH_YOUR_CREDITOR_KEY"
      }
    }
  }
}
```

An `mcp.example.json` template ships in the package. With Claude Code:

```bash
claude mcp add modern-collections -- mc-api-mcp
```

### The `creditor` parameter

A `ca_…` key is scoped to one creditor, so every call runs against it. A **partner** key is not — each call has to name the creditor it acts for. Every tool therefore accepts one extra optional parameter, `creditor`: a creditor UUID or the link's `external_creditor_ref`, defaulting to `MC_API_CREDITOR` and sent as the `X-MC-Creditor` header. It is ignored on a creditor key.

Set `MC_API_CREDITOR` when a server process works a single creditor; pass `creditor` per call to override it. That is how one server works across several of a partner's creditors:

```
placement_list(status="in_outreach", creditor="acme-freight")
placement_improve(placement_id="<uuid>", creditor="northwind-supply")
```

A partner key naming no creditor fails `400 X-MC-Creditor header required`; one naming a creditor with no active link fails `404 Creditor not found`.

### Tools that have real-world effects

{% hint style="warning" %}
These start **real debtor outreach**: `placement_create`, `intake_csv_commit`, `intake_file_confirm`, `intake_draft_resolve` (action `approve`), `intake_structured_submit`.

These are binding or destructive: `agreement_accept` (legally binding), `dispute_resolve`, `qbo_disconnect`, `intake_webhook_rotate_secret` (invalidates the previous secret), `notification_settings_replace` (replaces the whole grid).

Call any of them **only on an explicit instruction**, never to explore the API.
{% endhint %}

Two further notes. `POST /v1/settings/api-key/rotate` has no tool — it is gated on a dashboard session by design, so a leaked key cannot mint its own replacement. And two tools return binary payloads (`settings_agent_skills`, `agreement_certificate`), so they write to a local path and return that path rather than inlining bytes.

`document_upload` reads from local disk only when `MC_API_MCP_UPLOAD_ROOT` names a directory of user-approved documents; it otherwise takes `content_base64`.

### A worked loop

```
improve_overview()
→ ranks active placements by how much attention their file needs

placement_improve(placement_id="<uuid>")
→ { missing_documents: [ { document_type: "signed_delivery_receipt",
      where_to_look: "your dispatch system",
      search_hints: ["INV-4411", "Acme Freight", "7500.00"] } ], ... }

document_upload(file_path="~/ap/acme/POD-4411.pdf", placement_id="<uuid>",
                document_type="signed_delivery_receipt")
document_process(document_id="<doc-uuid>")

placement_improve(placement_id="<uuid>")
→ { evidence: { score: 78, grade: "B" }, missing_documents: [] }
```

## Generate your own client

The [OpenAPI 3.1 spec](https://github.com/knollmeyersam-dot/MC-Docs/tree/main/api-reference/rest-api/openapi.yaml) ships with these docs and is generated directly from the live application schema, so request and response shapes are field-accurate by construction.

```bash
openapi-generator-cli generate -i api-reference/rest-api/openapi.yaml -g typescript-fetch -o ./mc-client
# or
oapi-codegen -package mc api-reference/rest-api/openapi.yaml > client.go
```

{% hint style="info" %}
Always generate from the shipped `openapi.yaml`. It is curated and pruned to the supported external contract; the server's raw `/openapi.json` is not curated for codegen and is not a supported integration surface.
{% endhint %}

Regenerate whenever the spec version changes — it is regenerated whenever the API changes.

## See also

* [Quickstart](/getting-started/quickstart.md)
* [REST API](/rest-api/conventions.md)
* [Platform partners](/rest-api/partner-model.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.moderncollections.io/clients/clients.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
