Support MCP resources and prompts, not tools alone #118

Closed
opened 2026-08-11 23:05:24 +00:00 by coilyco-ops · 2 comments
Member

MCPProvider.Open discovers tools and nothing else (internal/community/mcp.go:82-114 at 3812935). ToolSession exposes Tools, Call, and Close. A server that publishes resources or prompts contributes none of it, so from Echo's side every MCP server is a bag of functions.

The two missing capabilities both have a direct use here.

Prompts

LocalSkillRoots is how Echo injects local policy and knowledge today, and it requires a tracked copy inside this repo. MCP prompts are the protocol's version of exactly that. A server could contribute its own operating guidance for its own surface rather than Echo carrying a checked-in description of someone else's tools that goes stale when they change.

This has a real design question attached: how a server-supplied prompt composes with LocalSkillRoots and with the response-style policy. A server must not be able to override Echo's voice, audit role, or grounding rules by shipping a prompt. Probable answer is that server prompts are admitted as capability description only, in a fixed slot, below local policy, never as instruction. That needs deciding before implementation rather than during.

Resources

Grounding documents a server can hand over directly, instead of Echo asking for them through a tool call and paying a round trip plus a tool result through the 8KB bound. Also the natural fit for anything a surface wants read rather than invoked.

Scope note

Sampling, roots, and elicitation are deliberately out of scope. Sampling in particular would let a server drive inference through Echo's Agent Proxy budget, which is a spend and authority boundary rather than a capability gap.

Lower priority than #114, #115, #116, and #117. This is capability breadth once the transport underneath it is sound.

`MCPProvider.Open` discovers tools and nothing else (`internal/community/mcp.go:82-114` at `3812935`). `ToolSession` exposes `Tools`, `Call`, and `Close`. A server that publishes resources or prompts contributes none of it, so from Echo's side every MCP server is a bag of functions. The two missing capabilities both have a direct use here. ## Prompts `LocalSkillRoots` is how Echo injects local policy and knowledge today, and it requires a tracked copy inside this repo. MCP prompts are the protocol's version of exactly that. A server could contribute its own operating guidance for its own surface rather than Echo carrying a checked-in description of someone else's tools that goes stale when they change. This has a real design question attached: how a server-supplied prompt composes with `LocalSkillRoots` and with the response-style policy. A server must not be able to override Echo's voice, audit role, or grounding rules by shipping a prompt. Probable answer is that server prompts are admitted as capability description only, in a fixed slot, below local policy, never as instruction. That needs deciding before implementation rather than during. ## Resources Grounding documents a server can hand over directly, instead of Echo asking for them through a tool call and paying a round trip plus a tool result through the 8KB bound. Also the natural fit for anything a surface wants read rather than invoked. ## Scope note Sampling, roots, and elicitation are deliberately out of scope. Sampling in particular would let a server drive inference through Echo's Agent Proxy budget, which is a spend and authority boundary rather than a capability gap. Lower priority than #114, #115, #116, and #117. This is capability breadth once the transport underneath it is sound.
Author
Member

Splitting this, because the spec gives prompts and resources different control models and I had lumped them together.

Prompts are user-controlled, so they never reach the system prompt

From the prompts spec: "Prompts are designed to be user-controlled, meaning they are exposed from servers to clients with the intention of the user being able to explicitly select them for use. Typically, prompts would be triggered through user-initiated commands in the user interface."

That is what shipped everywhere. Claude Code exposes them as /mcp__<server>__<prompt>, VS Code supports them, and Codex has an open request rather than an implementation (openai/codex#8342). A prompt becomes user-turn content when a person picks it, never system context on its own.

So the composition question I raised here is void: a server prompt should not compose with LocalSkillRoots because it should not be injected at all. The real question is smaller and different: Echo has no slash-command surface, so what counts as a user explicitly selecting a prompt? Candidates are a command syntax in a Discord message, or an explicit field on POST /v1/turn. That is a product decision about Echo's interface, not a prompt-composition decision, and it is not started.

Resources are application-driven, and automatic inclusion is sanctioned

From the resources spec: "Resources in MCP are designed to be application-driven, with host applications determining how to incorporate context based on their needs." The listed options include "Implement automatic context inclusion, based on heuristics or the AI model's selection." Resources also carry audience and priority annotations intended to "prioritize which resources to include in context."

So resources are the tractable half and are being built now:

  • Discovered per server alongside tools, cached, invalidated by notifications/resources/list_changed.
  • A resource is auto-included only when its audience names assistant. That makes inclusion an explicit server signal rather than an Echo assumption, so a server publishing a large catalogue does not flood the prompt.
  • Ordered by priority, bounded per document and in total, injected as reference material below the local policy and labelled as data rather than instruction.
  • Per-server degradation, matching tools: a server that fails resource discovery contributes none and the turn continues.

The prompts half stays open on this issue with the interface question named.

Splitting this, because the spec gives prompts and resources different control models and I had lumped them together. ## Prompts are user-controlled, so they never reach the system prompt From the [prompts spec](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts): "Prompts are designed to be **user-controlled**, meaning they are exposed from servers to clients with the intention of the user being able to explicitly select them for use. Typically, prompts would be triggered through user-initiated commands in the user interface." That is what shipped everywhere. Claude Code exposes them as `/mcp__<server>__<prompt>`, VS Code supports them, and Codex has an open request rather than an implementation (openai/codex#8342). A prompt becomes user-turn content when a person picks it, never system context on its own. So the composition question I raised here is void: a server prompt should not compose with `LocalSkillRoots` because it should not be injected at all. The real question is smaller and different: Echo has no slash-command surface, so what counts as a user explicitly selecting a prompt? Candidates are a command syntax in a Discord message, or an explicit field on `POST /v1/turn`. That is a product decision about Echo's interface, not a prompt-composition decision, and it is not started. ## Resources are application-driven, and automatic inclusion is sanctioned From the [resources spec](https://modelcontextprotocol.io/specification/2025-06-18/server/resources): "Resources in MCP are designed to be **application-driven**, with host applications determining how to incorporate context based on their needs." The listed options include "Implement automatic context inclusion, based on heuristics or the AI model's selection." Resources also carry `audience` and `priority` annotations intended to "prioritize which resources to include in context." So resources are the tractable half and are being built now: * Discovered per server alongside tools, cached, invalidated by `notifications/resources/list_changed`. * A resource is auto-included only when its `audience` names `assistant`. That makes inclusion an explicit server signal rather than an Echo assumption, so a server publishing a large catalogue does not flood the prompt. * Ordered by `priority`, bounded per document and in total, injected as reference material below the local policy and labelled as data rather than instruction. * Per-server degradation, matching tools: a server that fails resource discovery contributes none and the turn continues. The prompts half stays open on this issue with the interface question named.
Author
Member

Resources landed in 25c621e, and the prompt selection surface for HTTP landed in 4d5fb97. Both halves of this issue are now done for the ingress that could carry them.

POST /v1/turn takes an optional prompt object naming a server, prompt, and arguments. Naming it is the explicit selection the control model requires, so Echo never injects a prompt on its own. The server's messages keep their user and assistant roles and enter the turn as conversation rather than system instruction. With no caller content the prompt's final user message becomes the request and the rest becomes history, so a prompt alone is a complete call.

Required arguments are validated against the cached prompts/list before the fetch, so a missing one names itself. Prompt failures split by who can fix them: a caller-fixable error returns its text, a transport failure returns a generic message, because the wrapped error could carry an endpoint into a response body.

Discord is untouched and is now coilyco-gaming/sirens-echo#127. It is not a coding gap but an access-policy one: a slash command is a summon path that bypasses the mention gate by construction, and the channel allowlist, guild allowlist, admission keys, and DM stance all need answers first. That issue is labelled interactive for the same reason.

Closing this. The remaining Discord work lives on #127.

Resources landed in `25c621e`, and the prompt selection surface for HTTP landed in `4d5fb97`. Both halves of this issue are now done for the ingress that could carry them. `POST /v1/turn` takes an optional `prompt` object naming a server, prompt, and arguments. Naming it is the explicit selection the control model requires, so Echo never injects a prompt on its own. The server's messages keep their user and assistant roles and enter the turn as conversation rather than system instruction. With no caller `content` the prompt's final user message becomes the request and the rest becomes history, so a prompt alone is a complete call. Required arguments are validated against the cached `prompts/list` before the fetch, so a missing one names itself. Prompt failures split by who can fix them: a caller-fixable error returns its text, a transport failure returns a generic message, because the wrapped error could carry an endpoint into a response body. Discord is untouched and is now coilyco-gaming/sirens-echo#127. It is not a coding gap but an access-policy one: a slash command is a summon path that bypasses the mention gate by construction, and the channel allowlist, guild allowlist, admission keys, and DM stance all need answers first. That issue is labelled `interactive` for the same reason. Closing this. The remaining Discord work lives on #127.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#118
No description provided.