---
title: "MCP integration · Finch Agent"
description: "Declaratively contribute MCP servers, loaded on demand"
source: https://finchwork.app/en/docs/minitools-mcp
---

# MCP integration

MCP integration is a textbook use of the capability mechanism: the official MCP Client mini tool provides `mcp.client`, and other mini tools consume it.

## When to choose MCP

-   The tool set is large (10+) and most of it isn't needed at once — you want Finch to load it on demand.
-   The target service already has an official MCP SDK, and you don't want to reimplement it.

## Two-layer design

The **static layer** (`finch.json`) holds only metadata, **never secrets**:

```json
{
  "requires": { "capabilities": ["mcp.client"] },
  "contributes": {
    "mcpServers": [
      { "name": "my-server", "description": "My MCP server." }
    ]
  }
}
```

The **runtime layer**, inside `activate()`, provides the actual transport configuration:

```ts
async function registerWhenReady(ctx: finch.MiniToolContext, apiKey: string) {
  // The MCP Client may activate after this tool, so poll briefly
  for (let i = 0; i < 20; i++) {
    if (ctx.capabilities.has('mcp.client')) break;
    await new Promise((r) => setTimeout(r, 250));
  }
  if (!ctx.capabilities.has('mcp.client')) return;

  const mcp = ctx.capabilities.get('mcp.client');
  await mcp.registerServer({
    name: 'my-server',
    command: 'npx',
    args: ['-y', 'my-mcp-server'],
    env: { API_KEY: apiKey },
    ownerExtensionId: ctx.minitool.id,
  });
}
```

Runtime registration is in-memory and must be redone on every activation.

## Where secrets come from

Standard pattern: provide a `setup_*` tool or a settings-menu item, collect the secret via a form, store it with `ctx.secrets`, then call `registerServer()`. See [Accounts, settings & OAuth login](/en/docs/minitools-oauth).
