Skip to content

[FEATURE][API]: Support _meta for all RPC methods #2332

@010gvr

Description

@010gvr

📋 Feature: Support _meta for All RPC Methods

Goal

Extend _meta support to all MCP RPC methods (tools/list, resources/list, prompts/list, resources/read, prompts/get) to achieve full compliance with MCP specification 2025-11-25. The gateway should propagate _meta from client requests to upstream MCP servers.

Why Now?

  1. MCP Compliance: Spec 2025-11-25 reserves _meta for protocol-level metadata on all methods
  2. User Context: Servers need user identity/context to filter results appropriately
  3. Dynamic Responses: Enable tools/resources that change based on _meta context
  4. Dependency: Issue [FEATURE]: Dynamic tools/resources based on user context and server-side signals #2171 (dynamic tools) and [FEATURE]: Bypass DB/cache lookup option for gateways #2344 (direct proxy) rely on _meta propagation

📖 User Stories

US-1: MCP Server Developer - Receive User Context in All Methods

As an MCP Server developer
I want to receive _meta in all RPC methods
So that I can customize responses based on user context

Acceptance Criteria:

Scenario: tools/list receives _meta
  Given a client sends tools/list with _meta containing user_id
  When the request reaches the upstream MCP server
  Then the server should receive the exact _meta object
  And can filter tools based on user_id

Scenario: resources/list receives _meta
  Given a client sends resources/list with _meta containing workspace_id
  When the request reaches the upstream MCP server
  Then the server should receive the _meta object
  And can return workspace-specific resources

Scenario: prompts/get receives _meta
  Given a client sends prompts/get with _meta containing locale
  When the request reaches the upstream MCP server
  Then the server should receive the _meta object
  And can return localized prompt content

Technical Requirements:

  • Accept _meta parameter in all list/get endpoints
  • Forward _meta to upstream MCP server in JSON-RPC request
  • Preserve all fields within _meta
US-2: Developer - Consistent _meta Handling

As a Developer using the gateway API
I want consistent _meta handling across all methods
So that I don't have to handle different methods differently

Acceptance Criteria:

Scenario: All methods accept _meta in same format
  Given these RPC methods:
    | Method | Params |
    | tools/list | {} |
    | tools/call | {name, arguments} |
    | resources/list | {} |
    | resources/read | {uri} |
    | prompts/list | {} |
    | prompts/get | {name, arguments} |
  When I add _meta to any method's params
  Then the gateway should accept it
  And forward it to the upstream server

Scenario: _meta is optional everywhere
  Given any RPC method
  When I omit _meta from params
  Then the request should succeed
  And no _meta should be forwarded (or empty object)
US-3: Platform - Inject Gateway-Level Context

As a Platform Operator
I want the gateway to optionally inject context into _meta
So that upstream servers receive gateway-level information

Acceptance Criteria:

Scenario: Gateway injects authenticated user info
  Given authentication is enabled
  And a client authenticates as user@example.com
  When the client sends tools/list without _meta
  Then the upstream should receive _meta with:
    | Field | Value |
    | gateway.user_email | user@example.com |
    | gateway.user_teams | ["team-1"] |

Scenario: Client _meta preserved alongside gateway injection
  Given client sends _meta with {custom_field: "value"}
  When request is processed
  Then upstream receives _meta with:
    | Field | Value |
    | custom_field | value |
    | gateway.user_email | user@example.com |
  And client fields are not overwritten

Technical Requirements:

  • Optional: Inject authenticated user info into _meta.gateway
  • Preserve client-provided _meta fields
  • Use gateway. prefix for injected fields to avoid collisions

🏗 Architecture

_meta Flow

sequenceDiagram
    participant Client
    participant Gateway
    participant MCP Server

    Client->>Gateway: tools/list {_meta: {user_id: "123"}}
    Gateway->>Gateway: Extract _meta from params
    Gateway->>Gateway: Optionally inject gateway context
    Gateway->>MCP Server: tools/list {_meta: {user_id: "123", gateway: {...}}}
    MCP Server->>MCP Server: Filter based on _meta
    MCP Server-->>Gateway: {tools: [...]}
    Gateway-->>Client: {tools: [...]}
Loading

Methods to Update

Method Current _meta Support Status
tools/call ✅ Partial (Issue #2094) Needs verification
tools/list ❌ Not implemented New
resources/list ❌ Not implemented New
resources/read ❌ Not implemented New
prompts/list ❌ Not implemented New
prompts/get ❌ Not implemented New
completion/complete ❌ Not implemented New

Schema Updates

# mcpgateway/schemas.py

class ToolsListRequest(BaseModel):
    _meta: Optional[Dict[str, Any]] = Field(None, alias="_meta")

class ResourcesListRequest(BaseModel):
    _meta: Optional[Dict[str, Any]] = Field(None, alias="_meta")

class PromptsListRequest(BaseModel):
    _meta: Optional[Dict[str, Any]] = Field(None, alias="_meta")

# Similar for read/get methods

📋 Implementation Tasks

Phase 1: Schema Updates

  • Add _meta field to ToolsListRequest schema
  • Add _meta field to ResourcesListRequest schema
  • Add _meta field to ResourcesReadRequest schema
  • Add _meta field to PromptsListRequest schema
  • Add _meta field to PromptsGetRequest schema
  • Add _meta field to CompletionCompleteRequest schema

Phase 2: RPC Handler Updates

  • Modify tools/list handler to accept and forward _meta
  • Modify resources/list handler to accept and forward _meta
  • Modify resources/read handler to accept and forward _meta
  • Modify prompts/list handler to accept and forward _meta
  • Modify prompts/get handler to accept and forward _meta
  • Verify tools/call forwards _meta correctly

Phase 3: Transport Layer

  • Ensure SSE transport forwards _meta
  • Ensure Streamable HTTP transport forwards _meta
  • Ensure WebSocket transport forwards _meta
  • Ensure stdio transport forwards _meta

Phase 4: Gateway Context Injection (Optional)

  • Add configuration: INJECT_USER_META=true
  • Inject authenticated user info into _meta.gateway
  • Preserve client _meta fields
  • Document injected fields

Phase 5: Testing

  • Unit tests for _meta schema fields
  • Integration tests for each method with _meta
  • Test _meta preservation through transports
  • Test gateway context injection
  • Test with missing _meta (should work)

⚙️ Configuration Example

# Optional: Inject gateway context into _meta
INJECT_USER_META=false

# When enabled, upstream receives:
# _meta: {
#   ...client_fields...,
#   gateway: {
#     user_email: "user@example.com",
#     user_teams: ["team-1"],
#     timestamp: "2026-01-25T10:00:00Z"
#   }
# }

✅ Success Criteria

  • All RPC methods accept _meta parameter
  • _meta is forwarded to upstream MCP server unchanged
  • Missing _meta doesn't break any method
  • All transports (SSE, HTTP, WS, stdio) forward _meta
  • Gateway context injection works when enabled
  • OpenAPI docs show _meta parameter on all methods
  • All tests passing

🏁 Definition of Done

  • Schemas updated with _meta fields
  • All RPC handlers forward _meta
  • All transports propagate _meta
  • Optional context injection implemented
  • Unit tests written and passing
  • Integration tests written and passing
  • Code passes make verify
  • API documentation updated
  • PR reviewed and approved

📝 Additional Notes

MCP Specification Reference

From MCP Base Protocol (2025-06-18):

"The _meta property/parameter is reserved by MCP to allow clients and servers to attach additional metadata to their interactions."

Compatibility Notes

  • _meta is optional in all methods
  • Servers that don't use _meta simply ignore it
  • Gateway should never fail if _meta is missing
  • Client-provided _meta takes precedence over gateway injection (except for gateway. prefix)

🔗 Related Issues

Metadata

Metadata

Labels

MUSTP1: Non-negotiable, critical requirements without which the product is non-functional or unsafeenhancementNew feature or requestmcp-protocolAlignment with MCP protocol or specificationpythonPython / backend development (FastAPI)readyValidated, ready-to-work-on itemswxowxo integration

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions