# Use Apideck with LangChain

Connect LangChain to your customer's accounting system, discover an operation and read one invoice. Start with a deterministic connection check; add a model once the integration works.

[Open the runnable Python sample](https://github.com/apideck-io/developer-docs/tree/Gdewilde/use-case-driven/examples/langchain-mcp). It includes pinned dependencies, a bounded read tool, tests and an optional agent example.

## Prepare one customer connection

Use Python 3.12 and an Apideck application with an API key. [Connect a sandbox customer through Vault](/guides/vault), then confirm your connector supports [listing invoices](/apis/accounting/reference/invoices/invoicesAll). Keep the key on your server.

Set `APIDECK_API_KEY`, `APIDECK_APP_ID`, `APIDECK_CONSUMER_ID` and `APIDECK_SERVICE_ID` in the sample process. The consumer identifies your customer; the service selects the connector, such as `xero`. Resolve that customer from your application's authenticated user, never from an agent prompt.

This guide uses the **Apideck MCP server**, `https://mcp.apideck.dev/mcp`, to access connected data. [Documentation MCP](/mcp) retrieves documentation and does not need your Apideck credentials.

## Discover before executing

From the sample directory, create a virtual environment, install the pinned requirements and run the default check:

```bash
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python main.py
```

The sample uses LangChain's `MCPAdapter` with a `StreamableHttpTransport`. It sends the MCP headers `x-apideck-api-key`, `x-apideck-app-id`, `x-apideck-consumer-id` and `x-apideck-service-id` from environment variables.

The sample connects with `?scopes=read&lock_identity=true` (server 0.20.1 or later). These server options restrict operations and lock customer/connector identity to your configured headers. They are separate from the `scope` filter on `list_tools`.

It loads the server's dynamic tools, searches with `list_tools`, then calls `describe_tool_input` with the exact discovered operation name. It validates the one-record input against the returned JSON schema. A successful discovery check does **not** prove that ledger access works.

LangChain's `langchain.mcp` namespace is beta. The sample pins LangChain 1.4.5 and FastMCP 4.1.0; do not combine it with older `MultiServerMCPClient` snippets. See [LangChain's current MCP documentation](https://docs.langchain.com/oss/python/langchain/mcp).

## Make the bounded read

After confirming the configured customer and connector, run:

```bash
python main.py --read
```

This executes `accounting-invoices-all` with `limit: 1` and `fields: "id"`. It prints only a success status, record count and whether another page exists. It does not print invoices or credentials, follow pagination, retry failures or write data.

Verify the request and connected account in [Logs](/logs). An empty successful page is valid; it does not establish that you selected the intended account.

## Give the agent one useful tool

The sample's `invoice_reader` returns a LangChain tool with no model-controlled arguments. Pass that tool to `create_agent` with your configured chat model. The agent can check for an invoice, while the application fixes the customer, connector, operation and page size. The README includes the complete wiring.

Do not pass unrestricted `execute_tool` to an agent expecting the discovery filter `scope: "read"` to enforce authorization. That filter selects search results. Enforce permissions and execution budgets in your application, and keep sensitive tool tracing disabled.

## Recover from a failed check

| Symptom | Next step |
| --- | --- |
| Missing configuration | Set all four environment variables in the process running Python. |
| Authentication or permission failure | Check the key/application pair, customer connection and provider permissions. |
| Operation unavailable | Check connector coverage and granted access; do not guess another tool name. |
| Rate limit | Stop and follow the returned retry guidance before trying again. |
| Timeout or unexpected response | Inspect parent and child requests in Logs; do not interpret discovery as read success. |

The console deliberately omits raw exceptions because upstream messages may contain sensitive data. Use the [MCP recovery guide](/guides/mcp-verification-and-recovery) for client checks, revocation and a safe issue report.

## Build a close review workflow

Extend the bounded-read pattern with the [month-end close agent guide](/guides/month-end-close-agent): collect dated reports, calculate checks in application code and route exceptions to a finance reviewer.

## Frequently asked questions

### Do I need an LLM key to test the connection?

No. Discovery and the one-record read use LangChain tools directly. A model provider key is needed only for the optional agent example.

### Does the example support every connector?

It requires an accounting connector that supports listing invoices. For another API, discover its operation, inspect its schema and build a separate bounded tool. Do not assume a unified operation is supported by every connector.

### Is removing the client enough to revoke access?

No. Removing a configuration stops that client from connecting. Revoke or rotate the API key and manage the downstream authorization separately when access must end.
