> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finalsay-hitl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mcp

# MCP (Model Context Protocol)

Use the **MCP server** when your client speaks the [Model Context Protocol](https://modelcontextprotocol.io/) (for example AI tooling that connects to tools over stdio) instead of calling the REST API directly.

The MCP layer is a thin bridge: it validates tool input and forwards requests to the same **FinalSay** Agent API as HTTP. Payloads and outcomes match the [Agent API](../api-reference/agent).

The adapter advertises **three** tools in `tools/list`: **`request_human_approval`** and **`create_approval`** (identical create semantics; choose the name that fits your prompt) plus **`get_approval_result`** for polling.

Tool metadata includes **per-field descriptions and limits** in the JSON Schema so MCP clients can surface them to models. Runtime validation matches `POST /v1/approvals` **except `timeout` is not accepted over MCP** — expiry policy always uses the agent’s dashboard defaults on the server. Use the REST Agent API directly if you need per-request timeout overrides.

There is no separate “MCP secret”—you use the same **Agent ID** and **workspace API key** as in [API keys & automations](../guide/credentials).

## Tools

### `request_human_approval`

Creates an approval request for an agent.

**Required inputs**

* `question`
* `context_markdown`
* `options`

**Optional inputs**

* `request_id` (omit to let the API assign a UUID; returned in the tool response JSON)
* `correlation_id`
* `notification_summary`
* Callback configuration (`url`, optional `headers`)

Field shapes and limits match `POST /v1/approvals` in the [Agent API](../api-reference/agent) for the fields exposed here (`timeout` is REST-only).

When **agent callback authentication** is enabled in the web dashboard, the integration API still adds that header to outbound callbacks at delivery time. Do **not** pass the auth secret through MCP tool parameters—there is no tool field for it by design.

### `create_approval`

Same request body, validation, and `POST /v1/approvals` behavior as **`request_human_approval`**. Use whichever name fits your prompt: this one is described for **fire-and-forget creates** where the client does not wait—your workflow supplies the pause (for example n8n **Wait** + `callback.url` such as `$execution.resumeUrl`, or a later step that calls **`get_approval_result`**).

### `get_approval_result`

Returns the current result for a request.

**Required inputs**

* `request_id`

The response is either still **pending** or the same final payload you would get from `GET /v1/approvals/:requestId/result`.

## Authentication

Your MCP client must send HTTP headers on the MCP transport (as your product’s MCP host allows):

* `x-agent-id: <your agent UUID>`
* `x-api-key: <your workspace API key>`

The adapter **forwards** these headers to the API and does **not** store or create credentials.

## n8n and Docker (Streamable HTTP)

When **n8n runs in Docker** and the MCP adapter runs on your **host** (e.g. `npm run dev:mcp`), n8n must call the host using a URL the container can resolve—commonly **`http://host.docker.internal:<port>/mcp`** (with or without a trailing slash). **`fetch failed`** almost always means the TCP connection never reached the adapter (not an MCP protocol error).

Checklist:

1. **Adapter listens on all interfaces** — use **`MCP_HTTP_HOST=0.0.0.0`** (the repo `dev:http` script sets this). If the process binds only to `127.0.0.1`, containers cannot connect via `host.docker.internal`.
2. **Port** — must match the running server (default **4009** for `npm run dev:mcp`).
3. **Linux Docker** — `host.docker.internal` is not defined by default. Add to the n8n service, for example:\
   `extra_hosts: ["host.docker.internal:host-gateway"]`\
   (or use your host LAN IP instead of `host.docker.internal`).
4. **Smoke test from the n8n container** — `curl -sS http://host.docker.internal:4009/` should return JSON with `"ok": true`. If this fails, fix networking before debugging MCP.
5. **Hosted n8n (n8n Cloud)** cannot reach `host.docker.internal` on your laptop—use a **public HTTPS URL** or run n8n locally.

The adapter process must also reach **`INTEGRATION_API_BASE_URL`** (usually `http://localhost:4000` when both run on the host). If you ever run the adapter inside Docker too, point that variable at the integration API using a Docker-reachable hostname (for example `http://host.docker.internal:4000`).

If you combine **MCP Client Tool** with **community** nodes as AI tools, n8n also needs **`N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true`** — see [n8n: AI Agent tools](./n8n#ai-agent-tools-and-hitltool).

## Environment

Your deployment configures where the adapter sends traffic:

| Variable                   | Purpose                                                                                             |
| -------------------------- | --------------------------------------------------------------------------------------------------- |
| `INTEGRATION_API_BASE_URL` | Base URL of the FinalSay API (for example `https://api.example.com`). Defaults vary by environment. |

If you self-host infrastructure, your operator supplies this value when running the MCP adapter.

## Errors

* **Validation errors** — Reported before any network call to the API.
* **Non-2xx API responses** — Surfaced as MCP tool errors. Examples mapped from the Agent API include **409** `idempotency_conflict`, **429** `rate_limited`, and **403** `USAGE_APPROVAL_LIMIT` when the team is over an approval quota (billing/plan limits when enabled).
* **Unknown tool names** — MCP error with `isError: true`.

## Other ways to integrate

* [Custom HTTP](./custom-http) — curl and generic clients
* [n8n](./n8n) — Community nodes package `n8n-nodes-finalsay`, HTTP Request, and webhooks
* [Zapier](./zapier) — Custom request / webhooks
* [Agent API](../api-reference/agent) — Direct REST reference
* [Automation limits & billing](../guide/automation-limits)
