# Use Apideck with Vercel AI SDK

Use a server-side AI SDK tool to check a connected ledger. Keep the MCP client and Apideck credentials out of browser components.

[Open the runnable Node.js example](https://github.com/apideck-io/developer-docs/tree/Gdewilde/use-case-driven/examples/ai-frameworks/vercel/main.mjs) · [Compare framework guides](/guides/ai-frameworks)

## Start with a local check

Use Node.js 22 or later and npm. Download or clone the [example directory](https://github.com/apideck-io/developer-docs/tree/Gdewilde/use-case-driven/examples/ai-frameworks) with its shared helper files. Python scripts declare exact dependency versions for uv; the Node example includes a lockfile. These dependencies belong to the example, not your frontend bundle.

```bash
cd examples/ai-frameworks/vercel
npm ci
node main.mjs
```

The default mode runs the framework wiring against a local fixture. It makes no Apideck request and needs no model key. Expected output:

```json
{"status":"fixture","records":1,"has_more":false}
```

This proves the example can load and invoke its tool or graph. It does **not** verify customer access or model behavior. See the [verification record](https://github.com/apideck-io/developer-docs/tree/Gdewilde/use-case-driven/examples/ai-frameworks/VERIFICATION.md) for the exact checks and limits.

## Connect a customer

[Create a Vault connection](/guides/vault) for your sandbox customer. Confirm the selected connector supports [listing accounting invoices](/apis/accounting/reference/invoices/invoicesAll). Set these server-side environment variables in the example process:

| Variable | Purpose |
| --- | --- |
| `APIDECK_API_KEY` | Your application API key; inject it through an untracked environment or secret manager |
| `APIDECK_APP_ID` | The application that owns the key |
| `APIDECK_CONSUMER_ID` | Your authenticated customer's consumer |
| `APIDECK_SERVICE_ID` | The connector, such as `xero` |

Resolve the consumer from your application's authenticated user. Do not let the model choose a consumer or put credentials in a prompt, public URL or browser bundle.

These examples use **Apideck MCP** at `https://mcp.apideck.dev/mcp?scopes=read&lock_identity=true`. The MCP-specific key header is `x-apideck-api-key`. Read scope and identity locking require server 0.20.1 or later. [Docs MCP](/mcp#docs-mcp) serves documentation; it does not execute connected API operations and needs no Apideck key.

## Discover and validate the operation

```bash
node main.mjs --discover
```

The helper loads the dynamic server tools, searches accounting invoices with `list_tools`, then checks `accounting-invoices-all` through `describe_tool_input`. It validates `limit: 1` and `fields: "id"` against the returned schema before execution. Discovery returns `schema_verified` with `ledger_access_verified: false`; a listed operation is not proof that your connector supports it.

## Read one invoice

After checking the customer and connector, explicitly run:

```bash
node main.mjs --read
```

This makes one bounded downstream request. The summary contains `status`, `records` (zero or one), and `has_more`. Invoice identifiers, payloads and cursors are not printed or passed to a model. The sample does not follow pagination or retry failures.

Verify the consumer, connector and request in [Logs](/logs). Zero records is a valid result, but does not prove you selected the intended account. The example has a 60-second CLI deadline; a timeout is not evidence that the server never executed the request.

## Add it to your agent

The sample uses `createMCPClient` to connect and `tool` to expose one fixed operation. Import `buildTool` into your server-side agent or `generateText` configuration. Create a fresh tool per authorized request; the closure allows one downstream read, including failed attempts. Do not expose the discovered `execute_tool` directly.

The following wiring uses files from the sample directory. Agent construction is shown separately from the offline check; model-driven execution needs provider configuration and has not been live-tested here.

```javascript
import { buildTool } from './main.mjs';

// Pass this tools map to your server-side AI SDK agent or generateText call.
// Build it once per authorized customer request, not once per model turn.
const tools = { read_one_invoice: buildTool() };
```

Keep the shared helper alongside the example. Its fixed operation and argument-free tool prevent the model from widening the requested fields or selecting another customer. The general MCP discovery `scope` filter only narrows search results; use server scope, identity controls and application authorization for execution restrictions.

The sample's one-attempt budget is in memory. A process restart resets it. Production workers need durable request state when retries or restarts could replay an operation. Keep raw MCP payloads out of provider tracing and logs; only the sanitized tool result should enter model context.

## Recover deliberately

| Result | Action |
| --- | --- |
| Missing environment | Set all four values in the same server process |
| Schema or tool mismatch | Check the server mode and pinned framework versions; do not guess input fields |
| 401 | Check key/application pairing and reconnect the customer where needed |
| 403 | Ask the customer's administrator to grant the required permission |
| 429 | Inspect retry guidance; this example stops rather than retrying automatically |
| Timeout or uncertain result | Inspect parent and child requests in Logs before starting another attempt |

See [MCP verification and recovery](/guides/mcp-verification-and-recovery) for discovery, execution and revocation checks. Removing a client config does not revoke the underlying key or provider connection.

## Frequently asked questions

### Does the default check use a model?

No. It exercises the framework's tool or graph interface with a fixture. A model-driven agent needs its provider configuration and separate evaluation.

### Can I use this with CRM or HRIS?

Yes, the architecture applies to other APIs. Discover the required operation, inspect its schema and create a separate bounded tool for it. This particular sample only reads accounting invoices; it is not a compatibility claim for every connector.

### Is this a benchmark result?

No. Connection checks establish integration behavior. Model accuracy, latency and token/cost comparisons need a separate controlled evaluation; the Experience Lab does not yet have scored runs for this framework example.

Continue with [the month-end close agent](/guides/month-end-close-agent), [security and data handling](/guides/security-and-data-handling), or the [official Vercel AI SDK documentation](https://ai-sdk.dev/docs/ai-sdk-core/mcp-tools).
