Skip to content

feat(agent): connect the MCP spec docs server for protocol questions - #3631

Merged
chelojimenez merged 2 commits into
mainfrom
feat/agent-mcp-spec-docs-server
Aug 2, 2026
Merged

feat(agent): connect the MCP spec docs server for protocol questions#3631
chelojimenez merged 2 commits into
mainfrom
feat/agent-mcp-spec-docs-server

Conversation

@chelojimenez

@chelojimenez chelojimenez commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The gap

The in-app agent could search MCPJam's own docs (docs.mcpjam.com/mcp) and the web, but nothing gave it the MCP protocol spec. So "what does toolCalledWith match?" was answered from docs, and "does tools/list support cursor in 2025-11-25?" was answered from training data — which degrades across exactly the version range this debugger targets.

Why a second docs server (and not a prompt dump or RAG)

modelcontextprotocol.io/mcp runs the same Mintlify docs-server product as ours: unauthenticated streamable HTTP, stateless, so it drops into the existing config builder unchanged. It exposes search plus a read-only virtual filesystem over the .mdx sources, and:

$ ls /specification
2024-11-05  2025-03-26  2025-06-18  2025-11-25  2026-07-28  draft

That makes retrieval addressed, not similarity-based: the model has to name a version to read one, so it cannot silently answer a 2026-07-28 question out of the 2025-03-26 text. Four near-identical spec versions are the worst possible case for embedding retrieval and the best case for path addressing — which is also why this beats a pinned in-repo spec skill (build-static, needs a deploy to correct) and a prompt dump (paid every turn by every user, including the ones asking where the Connect button is).

Verified live through our own SDK, with our client capabilities:

TOOLS: search_model_context_protocol, query_docs_filesystem_model_context_protocol, submit_feedback

The submit_feedback problem

That third tool is a write (readOnlyHint: false, free-text feedback string), and both Mintlify docs servers ship it under the same unqualified name. Two independent problems, either sufficient on its own:

  1. It posts model-authored free text to a docs team — outward-facing, taken unattended (the agent's approval preference defaults off), invisible in the app the user is watching. Exactly the class of action this route dropped the platform worker to avoid.
  2. getToolsForAiSdk flattens selected servers last-in-wins on name collisions, so advertising it would have silently routed MCPJam docs feedback to the MCP project — with nothing at the call site to reveal it.

Fixed with a new excludeMcpToolNames option on prepareChatV2 / streamWebChatTurn, applied right after the SEP-1865 visibility filter. It is the mirror image of respectToolVisibility: that honors a policy the server declares, this is the host declining a tool the server is happy to offer. No default — a surface that wants nothing filtered omits it. Deleting by name resolves the collision too: neither copy survives.

Note this write tool was already reachable via our own docs server before this PR; the collision is what's new, and the fix covers both.

Other decisions

  • Preflight: the spec server joins the existing Promise.allSettled degrade-per-server path. This matters more now — one of the two knowledge servers is a third party we don't operate, and getToolsForAiSdk fails the whole turn if any selected server errors at connect/list time. Covered by a new test.
  • Unauthenticated: no accessToken, asserted in a test. Forwarding the caller's AuthKit bearer to a third party for a public docs search would be a leak.
  • Kill-switch scope: MCPJAM_AGENT_PLATFORM_TOOLS=1 restores the old action contract. It does not gate knowledge sources — the switch governs how the agent acts, not what it may read — so both docs servers connect in either mode, rather than giving the config two shapes. Docstring updated to say so, with a test.
  • Prompt: one new section routing protocol questions to the spec server, version-first ("ALWAYS establish which version… never generalize one version's behavior to another"). Static, so the cacheable prefix stays byte-stable — the existing stability test still passes.
  • MCPJAM_SPEC_MCP_URL overrides the URL, matching MCPJAM_DOCS_MCP_URL.

Testing

  • vitest run --project server303 files, 4068 tests, all passing (both shared files are widely consumed, so the full project was run, not just the touched suites).
  • New coverage: spec server connected + unauthenticated, both servers selected, per-server preflight degradation, submit_feedback declined, knowledge servers present under the kill-switch, version-first prompt rules, and three excludeMcpToolNames unit tests in chat-v2-orchestration.test.ts (declines, covers collisions, no-op when omitted).
  • ESLint clean on the touched route (one pre-existing logger.warn warning, untouched).

Follow-up (not in this PR)

The planned Slack app hits the same gap — its /api/v1/.../agent endpoint should connect these same two knowledge servers, and can reuse excludeMcpToolNames verbatim.

🤖 Generated with Claude Code


Note

Medium Risk
Changes agent MCP wiring, system prompts, and shared chat orchestration; behavior is well-tested but affects every agent turn and tool advertisement when both docs servers are selected.

Overview
Adds a second read-only knowledge MCP server (mcp-spechttps://modelcontextprotocol.io/mcp) alongside MCPJam docs so the in-app agent can answer protocol questions from versioned spec sources instead of training data. Preflight now considers both servers and degrades per server (a spec outage drops only that server and its prompt section, not the whole turn).

Introduces excludeMcpToolNames on prepareChatV2 / streamWebChatTurn so hosts can strip MCP tools by name after visibility filtering; the agent uses it to decline submit_feedback from both Mintlify docs servers (write tool + duplicate name collision when servers are flattened).

New SPEC_DOCS_PROMPT steers protocol Q&A to the spec server with version pinning; it stays enabled under MCPJAM_AGENT_PLATFORM_TOOLS=1 (read path) but is omitted when spec preflight fails. Docs config is refactored through a shared unauthenticated buildDocsServerConfig; optional MCPJAM_SPEC_MCP_URL override matches the docs URL env pattern.

Reviewed by Cursor Bugbot for commit d1d9d1a. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Connect the MCP spec docs server so the agent can answer protocol questions by version instead of from memory. Add a host-side filter to drop submit_feedback, preflight each server to degrade instead of fail, and emit spec guidance with the server so it survives the kill-switch.

  • New Features

    • Connect https://modelcontextprotocol.io/mcp as mcp-spec (unauthenticated).
    • Prompt: route protocol questions to the spec, version-first via /specification/<version>.
    • New excludeMcpToolNames to drop submit_feedback across servers; applied in prepareChatV2 and streamWebChatTurn.
    • Preflight all selected servers and degrade per server; turns continue with web_search if a docs server is down.
    • Kill-switch MCPJAM_AGENT_PLATFORM_TOOLS=1 restores actions only; docs servers stay connected. MCPJAM_SPEC_MCP_URL added to override the spec URL.
  • Bug Fixes

    • Spec guidance is now gated on mcp-spec preflight and emitted independently of the identity prompt, so it remains active under MCPJAM_AGENT_PLATFORM_TOOLS=1.

Written for commit d1d9d1a. Summary will update on new commits.

Review in cubic

The in-app agent could search MCPJam's own docs and the web, but nothing
gave it the MCP protocol spec — so protocol questions were answered from
training data, which degrades across exactly the version range this
debugger targets (2025-11-25, 2026-07-28/draft).

modelcontextprotocol.io runs the same Mintlify docs-server product as
docs.mcpjam.com: unauthenticated streamable HTTP, with search plus a
read-only virtual filesystem over the .mdx sources. `ls /specification`
returns 2024-11-05 … 2026-07-28 and draft, so retrieval is ADDRESSED —
the model must name a version to read one, and cannot silently answer a
2026-07-28 question out of the 2025-03-26 text. That property is why
this beats both a prompt dump and embedding-based retrieval, where four
near-identical spec versions are precisely the worst case.

Both docs servers also ship a `submit_feedback` WRITE tool, declined
here via a new `excludeMcpToolNames` prepare option. Two independent
reasons: it posts model-authored free text to a docs team unattended and
invisibly (the class of action this surface dropped the platform worker
to avoid), and `getToolsForAiSdk` flattens servers last-in-wins on
colliding names — so advertising it would have silently routed MCPJam
docs feedback to the MCP project.

The preflight already degrades per server, which now matters more: one
of the two knowledge servers is a third party we don't operate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Aug 2, 2026
@cursor

cursor Bot commented Aug 2, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_47601eab-5214-45d3-aa22-c70fa07ca3fe)

@dosubot

dosubot Bot commented Aug 2, 2026

Copy link
Copy Markdown

📄 Knowledge review

Dosu skipped reviewing this PR because your organization has used its 200 included credits for the month. Your usage will reset on 2026-09-01. To have Dosu review this PR before then, ask your organization admin to upgrade to a pro account.


Leave Feedback Ask Dosu about inspector Add Dosu to your team

@chelojimenez

chelojimenez commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 26f61ef8-e492-4bd8-979a-33b5fb043e66

📥 Commits

Reviewing files that changed from the base of the PR and between f64be3e and d1d9d1a.

📒 Files selected for processing (2)
  • mcpjam-inspector/server/routes/web/__tests__/mcpjam-agent.ui-only.test.ts
  • mcpjam-inspector/server/routes/web/mcpjam-agent.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • mcpjam-inspector/server/routes/web/tests/mcpjam-agent.ui-only.test.ts
  • mcpjam-inspector/server/routes/web/mcpjam-agent.ts

Walkthrough

The agent now uses separate MCPJam documentation and MCP specification servers with shared unauthenticated configuration. Preflight selects responsive servers and supports degraded operation. MCP protocol prompts require version-specific specification guidance. The submit_feedback MCP tool is excluded from advertised tools. Chat preparation accepts optional tool-name exclusions, applies them across selected servers, and forwards them through web chat turns. Tests cover server routing, degradation, rollback behavior, prompt guidance, and tool filtering.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

mcpjam-inspector/server/routes/web/__tests__/mcpjam-agent.ui-only.test.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: ESLint configuration in --config is invalid:

  • Unexpected top-level property "__esModule".

    at ConfigValidator.validateConfigSchema (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2177:19)
    at ConfigArrayFactory._normalizeConfigData (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:19)
    at ConfigArrayFactory._loadConfigData (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2984:21)
    at ConfigArrayFactory.loadFile (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2850:40)
    at createCLIConfigArray (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3660:35)
    at new CascadingConfigArrayFactory (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3735:29)
    at new CLIEngine (/soundcheck/node_modules/eslint/lib/cli-engine/cli-engine.js:617:36)
    at new ESLint (/soundcheck/node_modules/eslint/lib/eslint/eslint.js:430:27)
    at Object.execute (/soundcheck/node_modules/eslint/lib/cli.js:410:24)
    at async main (/soundcheck/node_modules/eslint/bin/eslint.js:152:22)

mcpjam-inspector/server/routes/web/mcpjam-agent.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: ESLint configuration in --config is invalid:

  • Unexpected top-level property "__esModule".

    at ConfigValidator.validateConfigSchema (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2177:19)
    at ConfigArrayFactory._normalizeConfigData (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:19)
    at ConfigArrayFactory._loadConfigData (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2984:21)
    at ConfigArrayFactory.loadFile (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2850:40)
    at createCLIConfigArray (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3660:35)
    at new CascadingConfigArrayFactory (/soundcheck/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3735:29)
    at new CLIEngine (/soundcheck/node_modules/eslint/lib/cli-engine/cli-engine.js:617:36)
    at new ESLint (/soundcheck/node_modules/eslint/lib/eslint/eslint.js:430:27)
    at Object.execute (/soundcheck/node_modules/eslint/lib/cli.js:410:24)
    at async main (/soundcheck/node_modules/eslint/bin/eslint.js:152:22)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mcpjam-inspector/server/routes/web/mcpjam-agent.ts`:
- Around line 160-161: The specification and knowledge-server guidance in the
agent prompt must remain active when platform tools are disabled. Separate that
guidance from the UI-only action guidance around AGENT_IDENTITY_PROMPT, include
the specification-routing text in both platform and rollback modes, and add a
rollback-mode test verifying that protocol questions require establishing the
specification version first.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 658376d0-2c12-44fd-8094-1ec69991034b

📥 Commits

Reviewing files that changed from the base of the PR and between c2a459a and f64be3e.

📒 Files selected for processing (7)
  • mcpjam-inspector/server/routes/web/__tests__/mcpjam-agent-widget-content.test.ts
  • mcpjam-inspector/server/routes/web/__tests__/mcpjam-agent.ui-only.test.ts
  • mcpjam-inspector/server/routes/web/__tests__/mcpjam-agent.uitools.test.ts
  • mcpjam-inspector/server/routes/web/mcpjam-agent.ts
  • mcpjam-inspector/server/utils/__tests__/chat-v2-orchestration.test.ts
  • mcpjam-inspector/server/utils/chat-v2-orchestration.ts
  • mcpjam-inspector/server/utils/web-chat-turn.ts

Comment thread mcpjam-inspector/server/routes/web/mcpjam-agent.ts Outdated
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Internal preview

Preview URL will appear in Railway after the deploy finishes.
Deployed commit: fe3b67a
PR head commit: d1d9d1a
Backend target: staging fallback.
Access is employee-only in non-production environments.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread mcpjam-inspector/server/routes/web/mcpjam-agent.ts Outdated
… prompt

Under MCPJAM_AGENT_PLATFORM_TOOLS=1 the spec server was connected but the
version-first routing instruction was dropped, because it lived inside
AGENT_IDENTITY_PROMPT and the kill-switch removes that whole section. The
result was the one combination with the feature's cost and none of its
value: the authoritative protocol source attached, and no instruction to
read it or to pin a version.

The stated principle — the switch governs how the agent ACTS, not what it
may READ — was applied to the server but not to its guidance. Extract
SPEC_DOCS_PROMPT and gate it on the spec server surviving preflight, the
same rule ambientContextPrompt follows, so the two can no longer disagree.

Reported by cubic on #3631.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 2, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_9b9f959f-e00a-4b12-a2b8-1cd9a1b74691)

@chelojimenez
chelojimenez merged commit b65bc5e into main Aug 2, 2026
12 of 13 checks passed
@chelojimenez
chelojimenez deleted the feat/agent-mcp-spec-docs-server branch August 2, 2026 22:48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1d9d1a61f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

? [DOCS_SERVER_ID, PLATFORM_SERVER_ID]
: [DOCS_SERVER_ID];
? [DOCS_SERVER_ID, SPEC_SERVER_ID, PLATFORM_SERVER_ID]
: [DOCS_SERVER_ID, SPEC_SERVER_ID];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound the spec preflight before serving unrelated turns

When the third-party spec server accepts a connection but stalls on tools/list, every agent request—including UI or MCPJam product questions that do not need protocol docs—waits for this preflight because Promise.allSettled blocks on all candidates. The shared config permits that request to run for up to 30 seconds, so the advertised degradation to MCPJam docs and web_search only happens after a long user-visible pause; use a short independent deadline or defer the spec connection until it is needed.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant