modelcontextprotocol / modelcontextprotocol/ext-apps
Standardize provenance for app-initiated server tool calls
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 387
- Avg merge
- 3h 21m
- Merged PRs (30d)
- 6
Description
Problem / motivation
For a server tool whose _meta.ui.visibility includes both "model" and "app", the server can receive tools/call requests initiated by either the model/agent or an embedded MCP App. Today those requests are indistinguishable at the server boundary.
A standardized, per-invocation provenance signal would help with observability, UX analytics, debugging, rate limiting, and policy decisions. It should be treated as provenance asserted by the MCP client/host, not as an authentication or authorization primitive.
Current spec behavior
The stable MCP Apps specification allows a View to send the core tools/call request to its Host, which may proxy that request to the MCP server.
Existing mechanisms answer related but different questions:
_meta.ui.visibilitycontrols whether a tool may be called by the model and/or App; it does not identify who initiated a particular call to a dual-visible tool.- MCP 2026-07-28 per-request
io.modelcontextprotocol/clientInfoidentifies the MCP client/Host; it does not distinguish whether that Host's model/agent or embedded App initiated the request. - Apps
ui/initializeappInfoidentifies the View to the Host, but it is not propagated to the MCP server on eachtools/call. - A custom App-supplied
_metamarker is non-interoperable, may be dropped by Hosts or gateways, can collide with other conventions, and should not be considered authoritative.
As a result, proxying preserves the call parameters but carries no normative per-call origin signal.
Concrete example
Both paths collapse to the same server request:
Agent -> Host -> Server
App -> Host -> Server
{
"method": "tools/call",
"params": {
"name": "refresh_dashboard",
"arguments": { "accountId": "123" }
}
}
The server cannot tell whether the Host emitted this request because the agent selected the tool or because a user clicked a control in the embedded App.
Proposal: host-attested metadata
Define an official Apps-owned request _meta entry, for example:
{
"_meta": {
"io.modelcontextprotocol/ui": {
"initiator": "app"
}
}
}
Normative behavior could be:
- The Host MUST add or overwrite this value when proxying a View-originated
tools/call. - The Host MUST NOT set
initiator: "app"for model/agent-originated calls. - Downstream proxies and gateways SHOULD preserve the standardized entry.
- Absence means unknown, not implicitly
"model". - The View should not be responsible for self-declaring this marker.
The smallest interoperable shape may only need an App-origin boolean/enum. Optional appInfo and/or resourceUri could be considered separately if their interoperability value outweighs privacy and cardinality concerns.
Alternatives considered
clientInfo/appInfo:clientInfoidentifies the Host, whileappInfoidentifies the View only within the Apps initialization boundary. Neither currently expresses per-invocation origin to the server.- Separate connections: A Host could use a distinct MCP connection for App traffic, but that complicates session/state sharing and still lacks a portable semantic signal across gateways.
- OpenTelemetry baggage: Useful inside a deployment, but it is not an interoperable MCP protocol contract and may not survive all transports or proxies.
- Custom vendor
_meta: Feasible for closed ecosystems, but merely relocates the custom semantics. Hosts may drop it, namespaces may diverge, and App-authored values are not authoritative.
Security and trust considerations
“Host-attested” means asserted by the MCP client/Host; it is not cryptographically verified. A server must not use this field for authorization unless it separately trusts and authenticates the Host making the assertion.
Hosts should overwrite any spoofed App-provided value when proxying the request. Provenance should remain low-cardinality. If identity-bearing fields such as appInfo or resourceUri are included, the specification should give explicit privacy, disclosure, and logging guidance.
Open questions
- What namespace and shape best fit current Apps and core
_metaconventions? - Is an App-only boolean sufficient, or should the field be a broader enum such as
app,model,user,host, orunknown? - Should
appInfoand/orresourceUribe included, optional, or intentionally excluded? - What preservation requirements should apply through gateways and nested proxies?
- How should provenance relate to
_meta.ui.visibilityenforcement without conflating the two? - Should the design align only with modern per-request metadata conventions, or also define legacy compatibility behavior?
The goal is to standardize the smallest interoperable shape; the options above are intended to invite maintainers to choose the least disruptive protocol contract.
Related specifications and issues
- Stable MCP Apps specification (2026-01-26)
- Current MCP request
_metadocumentation - #492: Provide a consistent way for MCP Apps to know which tool invoked them — related opposite direction (Host/tool identity to App), not a duplicate
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the stable MCP Apps specification and the current MCP request _meta documentation linked in the issue, then compare the model- and View-originated tools/call paths described here. Done means maintainers agree on the smallest provenance shape, namespace, trust semantics, and preservation requirements, with the specification updated accordingly.
Written by the indexing model from the issue text.
Assessment
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100