Repository navigation
feat(mcp-server): claim only the mcp discovery documents under .well-known - #1969
Conversation
|
Coverage Impact This PR will not change total coverage. Modified Files with Diff Coverage (1)
🛟 Help
|
…0035-impl-prd-1473-wellknown-root
nbouliol
left a comment
There was a problem hiding this comment.
Spec (PRD-1473): conforms to all five acceptance criteria.
Applies to: the Forest documentation, product/embed/mcp-server and reference/agent-api/nodejs
Claude Opus 5.5 (claude-opus-5-5): Should fix: once this ships, integrators read that a root-mounted MCP still breaks their own /.well-known/* routes, which stops being true.
Code
Both pages say the mounted MCP intercepts all of /.well-known/*, but mcp-paths.ts:29 now claims only the two discovery documents.
A way out: scope both mountAiMcpServer warnings to /oauth/* and /mcp in a docs change released alongside.
Reproduction
- Mount the MCP at the root basePath with this PR.
- Request
/.well-known/security.txton the agent and see the host answer it. - Read the
mountAiMcpServerwarning, which says that request breaks.
|
Confirmed, thanks. Both warnings are stale once this ships:
At the root basePath the MCP now claims The fix lives in the docs repo, outside this PR's scope. I've flagged it so a docs change ships alongside this release. |
|
@nbouliol the PR for the docs is here https://github.com/ForestAdmin/docs/pull/51 |
|
Closed: ForestAdmin/docs#51 scopes both root-mount warnings to How it was checkedPredicate: a docs sentence says a root-mounted MCP blocks a |
nbouliol
left a comment
There was a problem hiding this comment.
Approved after /verify-fixes run 1969-20261006121628-nbouliol-verify: 1 findings of 1969-20261006082101-nbouliol closed or accepted, none reopened.
# @forestadmin/mcp-server [1.27.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/mcp-server@1.26.0...@forestadmin/mcp-server@1.27.0) (2026-10-06) ### Features * **mcp-server:** claim only the mcp discovery documents under .well-known ([#1969](#1969)) ([fb8f000](fb8f000))
# @forestadmin/agent [1.106.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.105.6...@forestadmin/agent@1.106.0) (2026-10-06) ### Features * **mcp-server:** claim only the mcp discovery documents under .well-known ([#1969](#1969)) ([fb8f000](fb8f000)) ### Dependencies * **@forestadmin/mcp-server:** upgraded to 1.27.0

The started MCP now claims only its two discovery documents under
/.well-known/, so a host app keeps its ACME challenges andsecurity.txt. refs PRD-1473What
/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource/mcp, nothing else under/.well-known/./.well-known/oauth-protected-resource/<prefix>/other than.../mcpno longer go to the MCP./.well-known/*path now reaches the host instead of the MCP's 405. Gateway switch without a hostnext: 404 JSON instead of 405; the standaloneforest-mcp-serverCLI is unchanged. The bare/.well-known/oauth-protected-resourceandopenid-configurationfall to the host; the MCP never served them. Double-slash paths on the two documents (.../oauth-authorization-server//,.../oauth-protected-resource/mcp//) answered 200 onmainand now fall to the host.MCP_PATHS(public export) changes content: semver-minor.Why
buildMcpPaths('')returned the/.well-known/directory, soacme-challenge/<token>andsecurity.txthit the MCP'sallowedMethods(['POST'])and answered 405. Let's Encrypt renewals broke for any host serving the agent at the root while the MCP was up.How
oauth-authorization-server${prefix}andoauth-protected-resource${prefix}/mcp, matched by exact pathname (one trailing slash tolerated, nothing after)./oauth/and/mcpkeep their segment-boundary match./.well-known/.Verification
/ai, gateway-switch rows on'',/ai,/a/b, startedgetHttpCallback(GET, HEAD, OPTIONS), agent integration on 8 frameworks including Koa. 43 mcp-server and 16 agent tests fail onmain, pass here. Suites: mcp-server 1558/1558, agent 1742/1742. eslint andtscclean.3b43886ed3b43886ed: PASS, full matrix. 296 responses carry the loaded build's marker, the recompile diff proves which build served them, 88/88 regression lines identical, A/B diff confined to.well-known. Not measured: a base URL with a path and a trailing slash at the root basePath (review F3)30ffa70af(mainmerged in, PR diff unchanged): 29 pass, 3 skipped. Reruns covered a GitHub runner outage and a datasource-mongo test that also flakes onmainDefinition of Done
General
Security