diff --git a/product/embed/mcp-server.mdx b/product/embed/mcp-server.mdx index 54169f6..960056c 100644 --- a/product/embed/mcp-server.mdx +++ b/product/embed/mcp-server.mdx @@ -84,6 +84,20 @@ Your Forest MCP Server URL will be `{your-agent-url}/mcp` Note that each Environment has its own Back-end URL, and therefore its own Forest MCP Server URL. + + When mounted, the MCP server intercepts the **entire** `/oauth/*` and `/.well-known/*` namespaces plus `/mcp` at your back-end's root. Any request in those namespaces is captured by the MCP server — if it doesn't serve that exact route (or your back-end already does), the request gets a 404/405 **instead of reaching your back-end**. So your own `/oauth/callback` or `/.well-known/apple-app-site-association` would break, not just OAuth. + + Pass a `basePath` to narrow the MCP server to a dedicated prefix so your routes are left untouched. The OAuth and protocol routes move under the prefix; the `.well-known` discovery documents stay at the root (as OAuth discovery requires) but are served at prefix-suffixed paths such as `/.well-known/oauth-authorization-server/ai`, narrowing the `.well-known` claim to just those two paths: + + ```text + const agent = createAgent(options).addDataSource(/* ... */).mountAiMcpServer({ basePath: '/ai' }); + ``` + + Your Forest MCP Server URL then becomes `{your-agent-url}/ai/mcp`. Because OAuth discovery must stay at the origin root, `basePath` requires your agent to be served at the domain root (it throws at startup if the agent URL already includes a path), and root `/.well-known/*` requests must still reach the agent. + + The prefix applies to every route, including the protocol endpoint — so `basePath: '/mcp'` would make the endpoint `/mcp/mcp`. Prefer a distinct prefix such as `/ai` to avoid the repetition. + + # Available tools The Forest MCP server exposes the following capabilities: diff --git a/reference/agent-api/nodejs.mdx b/reference/agent-api/nodejs.mdx index b9c12dd..140cf6d 100644 --- a/reference/agent-api/nodejs.mdx +++ b/reference/agent-api/nodejs.mdx @@ -250,6 +250,7 @@ Enable a Model Context Protocol (MCP) server on the agent, allowing AI assistant ```typescript agent.mountAiMcpServer(options?: { enabledTools?: ToolName[]; + basePath?: string; }): Agent; ``` @@ -258,6 +259,7 @@ agent.mountAiMcpServer(options?: { | Option | Type | Description | |--------|------|-------------| | `enabledTools` | `ToolName[]` | Restrict which MCP tools are exposed. Defaults to all tools. | +| `basePath` | `string` | Path prefix for the MCP OAuth and protocol routes (e.g. `'/ai'`); the `.well-known` discovery documents stay at the origin root (prefix-suffixed). Requires the agent at the domain root. Defaults to the host root. | **Available tool names:** `'describeCollection'`, `'list'`, `'listRelated'`, `'create'`, `'update'`, `'delete'`, `'associate'`, `'dissociate'`, `'getActionForm'`, `'executeAction'` @@ -269,14 +271,45 @@ agent.mountAiMcpServer({ }); ``` -The MCP server exposes HTTP endpoints for OAuth and protocol communication: +By default, the MCP server registers its endpoints at the host root: | Endpoint | Purpose | |----------|---------| | `POST /mcp` | Main MCP protocol endpoint (Bearer token required) | -| `POST /oauth/authorize` | OAuth authorization | +| `GET`, `POST /oauth/authorize` | OAuth authorization | | `POST /oauth/token` | Token exchange | -| `GET /.well-known/oauth-protected-resource/mcp` | OAuth discovery | +| `GET /.well-known/oauth-authorization-server` | Authorization server metadata | +| `GET /.well-known/oauth-protected-resource/mcp` | Protected resource metadata | + + +When mounted inside an existing application, the MCP server intercepts the **entire** `/oauth/*` and `/.well-known/*` namespaces plus `/mcp` at the host root. Any request in those namespaces is captured by the MCP server — if it doesn't serve that exact route (or your app already does), the request gets a 404/405 **instead of reaching your app**. For example, your own `/oauth/callback` or `/.well-known/apple-app-site-association` would break, not just OAuth. Set `basePath` to narrow the MCP server to a dedicated prefix (and just two suffixed `.well-known` paths) so your routes are left untouched. + + +**Scoping under a prefix:** + +```typescript +agent.mountAiMcpServer({ basePath: '/ai' }); +``` + +With `basePath: '/ai'`, the OAuth and protocol routes move under the prefix. The `.well-known` discovery documents stay at the host root (as required by OAuth discovery, RFC 8414/9728) but are served at prefix-suffixed paths, so they no longer collide with your application's own root `.well-known` routes: + +| Endpoint | Purpose | +|----------|---------| +| `POST /ai/mcp` | Main MCP protocol endpoint | +| `GET`, `POST /ai/oauth/authorize` | OAuth authorization | +| `POST /ai/oauth/token` | Token exchange | +| `GET /.well-known/oauth-authorization-server/ai` | Authorization server metadata (root, prefix-suffixed) | +| `GET /.well-known/oauth-protected-resource/ai/mcp` | Protected resource metadata (root, prefix-suffixed) | + +MCP clients discover these endpoints automatically from the metadata, so no client-side configuration is needed. + + +The prefix applies to **all** routes, including the protocol endpoint — so `basePath: '/mcp'` yields `/mcp/mcp`. Use a distinct prefix such as `/ai` to avoid the repetition. + + + +Because the `.well-known` discovery documents must stay at the origin root, `basePath` requires the agent to be served at the **domain root**. If your agent's URL already includes a path (e.g. `https://host/api`), setting `basePath` throws at startup. And root `/.well-known/*` requests must still reach the agent — a reverse proxy that forwards only `//*` will break discovery. + You can also configure enabled tools via the `FOREST_MCP_ENABLED_TOOLS` environment variable (comma-separated tool names), or set the server port with `MCP_SERVER_PORT` (default: `3931`).