Skip to content

feat(ai-mcp): expose server instructions on MCPClient - #1567

Open
pltoledo wants to merge 1 commit into
TanStack:mainfrom
pltoledo:feat/ai-mcp-instructions
Open

pltoledo wants to merge 1 commit into
TanStack:mainfrom
pltoledo:feat/ai-mcp-instructions

Conversation

@pltoledo

@pltoledo pltoledo commented Sep 29, 2026 •

Copy link
Copy Markdown

An MCPClient now has instructions. It holds the text the server sends when the client connects, so a host can put it in the system prompt. The MCP spec defines these instructions for that use. Before this PR the SDK Client was private, so a host could not read them.

🎯 Changes

  • MCPClient.instructions?: string. MCPClientImpl sets it after connect, next to capabilities, from the SDK getInstructions(). The SDK fills it for the 2025 initialize handshake and for spec 2026 discover.
  • The interface member is optional. A hand-rolled MCPClient object (tests and user code have them) keeps compiling. getInfo().clientOptions uses the same rule.
  • MCPClients does not change. pool.clients.<key>.instructions already gives the value for each server.
  • Docs: a "Server instructions" section in docs/tools/mcp-manual.md, a updatedAt bump in docs/config.json, and two lines in the ai-mcp package skill.
  • Changeset: minor for @tanstack/ai-mcp.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.
  • Docs: I updated docs/ for this change, or this change is not user-facing.
  • Changeset: I added a changeset (pnpm changeset), or this PR does not change a published package.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Testing

Commands run:

  • pnpm test:pr: pass (sherif, knip, docs, kiira, oxlint, lib, types, build).
  • pnpm exec playwright test tests/mcp.spec.ts tests/mcp-typed.spec.ts tests/mcp-lifecycle.spec.ts in testing/e2e: 9 passed. The full E2E matrix was not run locally.

Manual test:

  1. Run pnpm --filter @tanstack/ai-mcp test:lib -- tests/client.test.ts.
  2. In testing/e2e, run pnpm exec playwright test tests/mcp.spec.ts -g instructions.

Tests on this branch:

  • Unit: client.test.ts checks the instructions from a test server, and undefined when the server sends none.
  • E2E: the mock server in api.mcp-server.ts now sends instructions. A new GET /api/mcp-test returns mcp.instructions, and mcp.spec.ts checks the value over HTTP.

Risk / rollback

Low. The change adds one optional read-only field. Revert the PR to undo it.

Public API change

Before

const mcp = await createMCPClient({ transport })
// The server instructions cannot be read.

After

const mcp = await createMCPClient({ transport })
chat({
  adapter,
  messages,
  systemPrompts: mcp.instructions ? [mcp.instructions] : [],
  tools: await mcp.tools(),
})

Summary by CodeRabbit

  • New Features

    • MCP clients now expose server-provided instructions after connecting. If the server sends none, the value is undefined.
    • Added guidance and examples for including server instructions in chat system prompts.
  • Tests

    • Added coverage for receiving server instructions and for servers that provide none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: TanStack/ai/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 09b10c3b-3bd2-4df2-90e5-65678f1164a5

📥 Commits

Reviewing files that changed from the base of the PR and between 62bec34 and 523d796.

📒 Files selected for processing (9)
  • .changeset/ai-mcp-server-instructions.md
  • docs/config.json
  • docs/tools/mcp-manual.md
  • packages/ai-mcp/skills/ai-mcp/SKILL.md
  • packages/ai-mcp/src/client.ts
  • packages/ai-mcp/tests/client.test.ts
  • testing/e2e/src/routes/api.mcp-server.ts
  • testing/e2e/src/routes/api.mcp-test.ts
  • testing/e2e/tests/mcp.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The MCP client now exposes instructions received during the server handshake. Unit and end-to-end tests check the provided and absent cases. Documentation describes adding the instructions to chat() system prompts.

Changes

MCP server instructions

Layer / File(s) Summary
Expose handshake instructions
packages/ai-mcp/src/client.ts, packages/ai-mcp/tests/client.test.ts, .changeset/ai-mcp-server-instructions.md
MCPClient exposes optional server instructions populated after connection. Unit tests check the exact instruction string and the undefined case.
Verify instructions through the HTTP route
testing/e2e/src/routes/api.mcp-server.ts, testing/e2e/src/routes/api.mcp-test.ts, testing/e2e/tests/mcp.spec.ts
The test server provides an instruction. The GET route returns the connected client’s instructions or null, then closes the client. The E2E test checks the response.
Document instructions usage
docs/tools/mcp-manual.md, packages/ai-mcp/skills/ai-mcp/SKILL.md, docs/config.json
The manual and skill guidance describe adding client instructions to chat() system prompts. The manual entry date is updated.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Suggested reviewers: alemtuzlak

Merge Risk: ⚪ Minimal · up to 523d7

The optional client field exposes server instructions to hosts, with coverage for their presence, absence, and HTTP delivery. No actionable merge-blocking risk is established; normal checks remain appropriate.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 523d7

The API change is additive and does not automatically inject instructions into chats. However, the documented example gives the selected MCP server system-prompt influence. Applications following it must trust that server for this purpose; any downstream effect depends on the conversation data and tools the application permits.

Retained concerns

  • Medium · security · inferred: The newly documented integration passes server-controlled handshake text directly into systemPrompts without stating a server-trust prerequisite. If a host follows this guidance with a malicious or compromised configured server, that server gains system-prompt influence over the conversation and potentially the tools already available to that run. This is conditional on explicit host adoption; automatic injection and an executable exploit were not established.
Security review details

Security Blast Radius

  • inferred — The independently attackable scope is a host chat run that explicitly adopts instructions from an attacker-controlled or compromised configured MCP server. Potential effects extend to that run's model-visible context and permitted tools, including other tools if the host combines them. Tenant, data-store, service, and environment exposure cannot be quantified without the consuming application's configuration.

Security Findings and Attack Paths

  • inferred — A server operator or attacker controlling the selected endpoint can supply instruction text that the documented host example places into system-prompt context. That creates a possible prompt-policy manipulation path, but no automatic adoption, demonstrated unauthorized tool execution, or verified data exfiltration was established.

Trust Boundaries and Controls

  • observed — The managed MCP integration discovers and merges tools but does not promote instructions into system prompts. The chat engine initializes system prompts from caller parameters. Thus the security-relevant trust transition remains an explicit host choice rather than a new default behavior.

Resilience and Maintainability Implications

  • observed — Connection failure is contained before the implementation is returned. A post-handshake tool-list subscription failure is deliberately tolerated without replacing the established client or its instructions, preserving the instruction-to-connection identity.

Hardening Proposals

  • proposed — Make server trust for prompt-policy influence an explicit prerequisite of this integration. Hosts can omit instructions from untrusted servers, preserve host-authored policy separately, and enforce tool permissions and approvals outside model prompts rather than treating server instructions as authorization.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (4 skipped: 4 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: exposing server instructions on MCPClient.
Description check ✅ Passed The description follows the repository template. It explains the change, documents testing and risk, identifies release impact, and confirms the documentation and changeset updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 5 files. (4 skipped: 4 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the PR, @pltoledo! 🙌 @tombeckenham will take a look.

Automated pre-review checks

  • ✅ CI passing
  • ✅ No merge conflicts
  • ✅ Changeset present
  • ✅ E2E test changes included

Automated triage — a human review follows.

@github-actions github-actions Bot added the waiting-on: maintainer The ball is in the maintainers’ court label Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on: maintainer The ball is in the maintainers’ court

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants