Skip to content

feat(mcp): surface a server's own instructions when it has no description - #5321

Open
yh928 wants to merge 2 commits into
tinyhumansai:mainfrom
yh928:feat/mcp-server-instructions
Open

feat(mcp): surface a server's own instructions when it has no description#5321
yh928 wants to merge 2 commits into
tinyhumansai:mainfrom
yh928:feat/mcp-server-instructions

Conversation

@yh928

@yh928 yh928 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Connection now keeps the instructions an MCP server returns from initialize, and ConnectedServerOverview carries them through to the prompt.
  • The orchestrator's connected-server block falls back to those instructions only when the registry has no description, so nothing that reads well today changes.
  • The text is untrusted third-party input reaching a system prompt, so it is sanitized and capped before use.

Problem

An MCP server's initialize response carries instructions — the server's own statement of what it is for and how to drive it. We asked for it, discarded it, and told the agent nothing.

That was survivable while every connected server came from the registry inventory, which carries a curated description. Hand-entered custom servers (#5033) have no inventory entry, so the orchestrator prompt listed them by name and tool count alone and the agent had to infer the server's purpose from tool names.

Solution

A three-step ladder in format_connected_mcp_block: registry description → server instructions → tool count. The description keeps priority deliberately — it is curated, the instructions are whatever the server author wrote.

Instructions pass through sanitize_for_llm with a 600-character cap and flattened newlines. This is a third party's text landing in our system prompt, so it is treated as untrusted the same way skill descriptions are.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) — three cases: instructions used when there is no description, description preferred when there is one, and untrusted instructions sanitized
  • Diff coverage ≥ 80% — the ladder and the sanitize path are both covered by the new tests
  • N/A: behaviour-only change, no feature row added/removed/renamed — Coverage matrix updated
  • No new external network dependencies introduced
  • N/A: no release-cut surface touched — Manual smoke checklist updated
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Prompt-surface only. A server that already has a registry description renders byte-identically.
  • Security: the new text is untrusted and is sanitized on the way in; that is the only new data path.

Related

Closes #5317

Summary by CodeRabbit

  • New Features

    • Connected MCP server overviews now include server-provided instructions when available.
    • Tool discovery descriptions now fall back to sanitized server instructions when registry descriptions are unavailable.
    • Existing descriptions remain prioritized, with tool-count information used as a final fallback.
  • Bug Fixes

    • Added safeguards to prevent prompt-injection content in server instructions from affecting generated prompts.

@yh928
yh928 requested a review from a team August 2, 2026 12:39
@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: c4350e53-08c0-4774-a847-1dcf0295e09b

📥 Commits

Reviewing files that changed from the base of the PR and between d75b0a4 and 9f6dbe8.

📒 Files selected for processing (3)
  • src/openhuman/agent/registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp/registry/connections.rs
  • src/openhuman/mcp/registry/types.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/openhuman/mcp/registry/types.rs
  • src/openhuman/agent/registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp/registry/connections.rs

📝 Walkthrough

Walkthrough

MCP connections now retain initialization instructions from stdio and HTTP servers. Connected-server overviews expose them. Orchestrator prompts use sanitized, length-bounded instructions when registry descriptions are unavailable, while preserving description and tool-count fallback precedence.

Changes

MCP instruction flow

Layer / File(s) Summary
MCP metadata capture
src/openhuman/mcp/registry/types.rs, src/openhuman/mcp/registry/connections.rs
Connections store initialization instructions from stdio and HTTP clients. Connected-server overviews include the stored instructions.
Prompt fallback and validation
src/openhuman/agent/registry/agents/orchestrator/prompt.rs
The prompt uses sanitized and bounded server instructions after registry descriptions and before tool-count fallback. Tests cover precedence, sanitization, length bounding, and updated fixtures.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPServer
  participant Connection
  participant ConnectedServerOverview
  participant OrchestratorPrompt
  MCPServer->>Connection: Return initialize instructions
  Connection->>ConnectedServerOverview: Store and expose instructions
  ConnectedServerOverview->>OrchestratorPrompt: Provide server metadata
  OrchestratorPrompt->>OrchestratorPrompt: Sanitize, bound, and apply fallback precedence
Loading

Possibly related PRs

Suggested labels: feature, rust-core, agent

Suggested reviewers: m3ga-mind

Poem

I’m a rabbit with prompts in my paws,
MCP instructions now follow their cause.
Descriptions lead, clean guidance comes next,
Tool counts remain when no words are found in the text.
Hop, hop—sanitized context is bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: using MCP server instructions when no registry description exists.
Linked Issues check ✅ Passed The changes preserve instructions, apply the required fallback order, retain description precedence, and sanitize and cap untrusted instructions [#5317].
Out of Scope Changes check ✅ Passed All changes support MCP instruction preservation, prompt fallback behavior, precedence, sanitization, length limits, or related tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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 added agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Aug 2, 2026

@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: 3

🤖 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 `@src/openhuman/agent_registry/agents/orchestrator/prompt.rs`:
- Around line 669-686: Extend
connected_mcp_block_sanitizes_untrusted_instructions to use instructions
containing newline and tab characters plus content exceeding the 600-byte limit.
Assert the rendered server item is capped at the defined 600-byte boundary and
contains no newline or tab characters, while preserving the existing
instruction-fence sanitization and server-name assertions.

In `@src/openhuman/mcp_registry/connections.rs`:
- Around line 174-178: Add stdio and HTTP connection tests covering the
initialization-to-overview propagation: have each initialize branch return
distinct instructions, then assert the resulting connected_overview retains the
corresponding value from Connection.instructions. Update the existing connection
test coverage near the initialize and overview construction paths without
changing production behavior.

In `@src/openhuman/mcp_registry/types.rs`:
- Around line 75-78: Add focused tests for the Transport::is_http_remote
discriminator, asserting Transport::Stdio returns false and
Transport::HttpRemote returns true. Place the coverage alongside the existing
Transport tests and construct each variant with the required fields.
🪄 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: 64b7d89f-789d-449f-bb72-a85d2f13c6f5

📥 Commits

Reviewing files that changed from the base of the PR and between a52a599 and a80330c.

📒 Files selected for processing (3)
  • src/openhuman/agent_registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp_registry/connections.rs
  • src/openhuman/mcp_registry/types.rs

Comment thread src/openhuman/agent/registry/agents/orchestrator/prompt.rs
Comment thread src/openhuman/mcp/registry/connections.rs
Comment thread src/openhuman/mcp_registry/types.rs Outdated

@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: a80330cee1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openhuman/mcp_registry/types.rs Outdated
@greptile-apps

greptile-apps Bot commented Aug 2, 2026

Copy link
Copy Markdown

Greptile Summary

This PR surfaces MCP server instructions (from the initialize handshake) in the orchestrator prompt as a fallback for custom servers that have no registry description, sanitizing the text through sanitize_for_llm with a 600-byte cap. The three-step ladder (registry description → server instructions → tool-count) is a clean design and the security intent is sound.

  • Connection and ConnectedServerOverview now carry instructions: Option<String>, populated from both Stdio and HttpRemote initialize calls.
  • format_connected_mcp_block in prompt.rs adds the fallback branch and three well-scoped tests, but references crate::openhuman::mcp_client::sanitize::sanitize_for_llm — a module path that does not exist; the correct path used elsewhere is crate::openhuman::util::sanitize::sanitize_for_llm, and this will fail to compile.

Confidence Score: 2/5

Not safe to merge: the instructions sanitization in prompt.rs references crate::openhuman::mcp_client::sanitize, a module that does not exist, which will cause a compile failure.

The only changed file that is not straightforwardly correct is prompt.rs, where the new instructions sanitization call uses crate::openhuman::mcp_client::sanitize::sanitize_for_llm — a path that resolves to nothing in this codebase. Every other call site uses crate::openhuman::util::sanitize::sanitize_for_llm. The build will fail until this is corrected.

Files Needing Attention: src/openhuman/agent/registry/agents/orchestrator/prompt.rs — the wrong sanitize module path on the instructions branch.

Important Files Changed

Filename Overview
src/openhuman/agent/registry/agents/orchestrator/prompt.rs Adds instruction fallback and three tests; the instructions sanitization call references a non-existent module path (mcp_client::sanitize vs util::sanitize), causing a compile failure.
src/openhuman/mcp/registry/connections.rs Correctly captures init.instructions from both Stdio and HttpRemote branches and threads it through to Connection and connected_overview.
src/openhuman/mcp/registry/types.rs Adds instructions: Option<String> field to ConnectedServerOverview with clear documentation; straightforward and correct.

Reviews (3): Last reviewed commit: "feat(mcp): surface a server's own instru..." | Re-trigger Greptile

Comment thread src/openhuman/agent_registry/agents/orchestrator/prompt.rs Outdated
Comment thread src/openhuman/mcp_registry/types.rs Outdated
@yh928
yh928 force-pushed the feat/mcp-server-instructions branch from a80330c to 2073e7f Compare August 2, 2026 13:30

@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 `@src/openhuman/mcp_registry/types.rs`:
- Around line 195-208: Add coverage in the mcp_registry test module for
format_connected_mcp_block() and serializable ConnectedServerOverview data:
verify a non-empty description takes precedence over instructions, instruction
text is sanitized before rendering, and the rendered instruction fallback is
capped at 600 bytes.
🪄 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: ff9b3c43-077e-4751-8fb5-184232aec0ee

📥 Commits

Reviewing files that changed from the base of the PR and between a80330c and 2073e7f.

📒 Files selected for processing (3)
  • src/openhuman/agent_registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp_registry/connections.rs
  • src/openhuman/mcp_registry/types.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/openhuman/agent_registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp_registry/connections.rs

Comment thread src/openhuman/mcp/registry/types.rs
@yh928
yh928 force-pushed the feat/mcp-server-instructions branch from 2073e7f to 3c96df9 Compare August 5, 2026 01:54
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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: 2

🤖 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 `@src/openhuman/agent/registry/agents/orchestrator/prompt.rs`:
- Around line 207-232: Split the oversized files by extracting the connected-MCP
block formatting around prompt.rs lines 207-232 into a focused module, and move
its formatter tests from prompt.rs lines 613-686 alongside it; update prompt.rs
to call the extracted formatter while preserving current description,
instructions sanitization, and fallback behavior. Extract the connection
initialization workflow from connections.rs lines 404-481 into a focused MCP
registry module, updating callers and imports without changing its behavior.
Ensure the resulting files remain at or below 500 lines.

In `@src/openhuman/mcp/registry/connections.rs`:
- Around line 417-418: Update the initialize call in the active client setup
flow around stdio.initialize() and the corresponding additional transport path
to emit [rpc] debug events immediately before and after each RPC. Include
server_id and transport on both events, and include instructions_present on the
completion event without logging instruction contents; preserve the existing
initialization result and error propagation.
🪄 Autofix

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: a970da01-e469-4e8c-badc-9331f2b0fe6e

📥 Commits

Reviewing files that changed from the base of the PR and between d75b0a4 and 3c96df9.

📒 Files selected for processing (3)
  • src/openhuman/agent/registry/agents/orchestrator/prompt.rs
  • src/openhuman/mcp/registry/connections.rs
  • src/openhuman/mcp/registry/types.rs

Comment thread src/openhuman/agent/registry/agents/orchestrator/prompt.rs
Comment thread src/openhuman/mcp/registry/connections.rs
…tion

An MCP server returns `instructions` in its `initialize` response — the
server's own statement of what it is for and how to drive it. We asked for it,
threw it away, and told the agent nothing.

That was survivable while every connected server came from the registry
inventory, which carries a curated description. Hand-entered custom servers
have no such entry, so the orchestrator prompt listed them by name and tool
count alone.

`Connection` now keeps the `instructions` from `initialize`, and
`ConnectedServerOverview` carries them through. The prompt block falls back to
them only when the registry has no description — an existing description still
wins, so nothing that reads well today changes — and the text is untrusted
input from a third-party server, so it goes through `sanitize_for_llm` with a
600-character cap and flattened newlines before it can reach the prompt.

Three tests cover the ladder: instructions used when there is no description,
description preferred when there is one, and untrusted instructions sanitized.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SRSNnqQsokuGmkbpLoLCGy
@yh928
yh928 force-pushed the feat/mcp-server-instructions branch from 3c96df9 to 7e4201c Compare August 5, 2026 02:41

@greptile-apps greptile-apps 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.

yh928 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

…boundaries

Adds the one uncovered property of the new fallback: instructions are remote
free-form text with no length contract, so a verbose or hostile server must not
be able to spend the orchestrator's prompt budget. The test asserts the rendered
server line stays near the 600-byte bound for input several times that size.
Description precedence, the no-description fallback, and instruction
sanitization were already pinned.

Adds the `[rpc]` boundary events around both `initialize` calls with
`server_id`, transport, and `instructions_present`. The instruction content
stays out of the log — it is untrusted remote text, and the block already scrubs
it before the prompt sees it.

orchestrator::prompt connected_mcp 8 pass.

Reported by CodeRabbit on tinyhumansai#5321.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SRSNnqQsokuGmkbpLoLCGy

@greptile-apps greptile-apps 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.

yh928 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP server instructions are discarded, leaving custom servers undescribed in the prompt

1 participant