Skip to main content
Glama
proxy-spec.md12.8 kB
# MCP Proxy Extension Specification **Version**: 0.1.0 (Draft) **Status**: Proposed **Authors**: Magg Contributors ## Abstract This specification defines the Model Context Protocol (MCP) Proxy Extension, which enables dynamic access to MCP capabilities through a single, unified tool interface. The proxy pattern allows MCP servers to aggregate, gateway, and dynamically expose capabilities from other servers without requiring clients to manage multiple connections. This specification is based on the implementation in Magg (MCP Aggregator) and serves as a reference for other MCP servers that want to implement similar proxy functionality. The reference implementation can be found in the `magg.proxy` package. ## 1. Introduction The MCP Proxy Extension provides a standardized way for MCP servers to expose capabilities from other servers through a single tool. This enables powerful aggregation scenarios while maintaining the simplicity of the MCP protocol. ### 1.1 Requirements Notation The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. ### 1.2 Terminology - **Proxy Tool**: The MCP tool that provides unified access to capabilities - **Capability**: An MCP tool, resource, or prompt - **Query Action**: Operations that return metadata (list, info) - **Call Action**: Operations that execute capabilities ## 2. Proxy Tool Interface ### 2.1 Tool Name The proxy tool SHOULD be named `proxy`. Servers MAY use an alternative name (e.g., `mcp:proxy`) if documented. ### 2.2 Tool Parameters The proxy tool MUST accept the following parameters: #### 2.2.1 action (required) - **Type**: String enumeration - **Values**: `"list"` | `"info"` | `"call"` - **Description**: The operation to perform #### 2.2.2 type (required) - **Type**: String enumeration - **Values**: `"tool"` | `"resource"` | `"prompt"` - **Description**: The type of MCP capability to interact with - **Note**: Implementations MAY use parameter aliasing to avoid language keyword conflicts #### 2.2.3 path (conditional) - **Type**: String - **Description**: Name or URI of the specific capability - **Requirements**: - REQUIRED for `info` and `call` actions - MUST NOT be provided for `list` action #### 2.2.4 args (optional) - **Type**: Object (key-value pairs) - **Description**: Arguments for the capability being called - **Requirements**: - ONLY allowed for `call` action - MUST NOT be provided for `list` and `info` actions ### 2.3 Parameter Validation Servers MUST validate parameters and return clear error messages for: - Missing required parameters - Invalid parameter combinations - Unknown action or type values ## 3. Response Formats ### 3.1 Query Actions (list and info) Query actions MUST return a list containing a single embedded resource with: #### 3.1.1 Structure ```json [ { "type": "resource", "resource": { "uri": "<proxy-uri>", "mimeType": "application/json", "text": "<json-encoded-capability-data>" }, "annotations": { "proxyAction": "<action>", "proxyType": "<type>", "proxyPath": "<path>", // Only for info action "pythonType": "<type-identifier>", "many": <boolean> } } ] ``` #### 3.1.2 Annotations Query responses MUST include: - `proxyAction`: The action performed (`"list"` or `"info"`) - `proxyType`: The capability type (`"tool"`, `"resource"`, or `"prompt"`) - `proxyPath`: The specific capability path (ONLY for `info` action) Query responses SHOULD include type preservation annotations: - `pythonType`: A type identifier for deserialization (language-specific name to be generalized) - `many`: Boolean indicating if the data represents multiple objects ### 3.2 Call Actions Call actions MUST return the actual result from the called capability with proxy annotations. #### 3.2.1 Tool Calls Returns a list of content items (TextContent, ImageContent, or EmbeddedResource) with each item annotated: ```json [ { "type": "text", "text": "Result content", "annotations": { "proxyType": "tool", "proxyAction": "call", "proxyPath": "<tool-name>" } } ] ``` #### 3.2.2 Resource Reads Resource results MUST be converted to tool result format (EmbeddedResource) with annotations. ##### Resource Objectification When a text resource can be parsed as JSON, implementations SHOULD: 1. Parse the text content as JSON 2. Re-encode it with consistent formatting 3. Set `mimeType` to `"application/json"` 4. Preserve the original MIME type in a `contentType` field Example with objectification: ```json [ { "type": "resource", "resource": { "uri": "<original-resource-uri>", "mimeType": "application/json", "text": "{\"key\":\"value\"}", "contentType": "text/plain" // Original MIME type preserved }, "annotations": { "proxyType": "resource", "proxyAction": "call", "proxyPath": "<resource-uri>" } } ] ``` Example without objectification (binary or non-JSON): ```json [ { "type": "resource", "resource": { "uri": "<original-resource-uri>", "mimeType": "image/png", "blob": "<base64-encoded-data>" }, "annotations": { "proxyType": "resource", "proxyAction": "call", "proxyPath": "<resource-uri>" } } ] ``` #### 3.2.3 Prompt Gets Prompt results MUST be wrapped in an EmbeddedResource with the prompt data JSON-encoded: ```json [ { "type": "resource", "resource": { "uri": "<prompt-uri>", "mimeType": "application/json", "text": "<json-encoded-prompt-result>" }, "annotations": { "proxyType": "prompt", "proxyAction": "call", "proxyPath": "<prompt-name>", "pythonType": "GetPromptResult" } } ] ``` ## 4. Type Preservation ### 4.1 Type Annotations To enable proper deserialization, implementations SHOULD include type information in annotations. #### 4.1.1 Standard Type Annotation The current Magg implementation uses: - `pythonType`: String identifier for the data type - `many`: Boolean indicating if the data represents multiple objects Future revisions SHOULD generalize these to language-agnostic names such as: - `dataType` or `objectType` instead of `pythonType` - `isArray` or `multiple` instead of `many` #### 4.1.2 Type Identifiers Type identifiers SHOULD use one of these formats: 1. **Simple names**: `"Tool"`, `"Resource"`, `"Prompt"` 2. **Qualified names**: `"mcp.types.Tool"`, `"mcp.types.Resource"` 3. **Union types**: `"Resource|ResourceTemplate"` ### 4.2 MIME Type Preservation When converting resources to tool results, implementations MUST preserve type information: 1. **Original MIME Type**: If a resource is objectified (converted to JSON), the original MIME type SHOULD be preserved in a `contentType` field 2. **Objectification**: Text resources that parse as valid JSON SHOULD be re-encoded with `mimeType: "application/json"` 3. **Binary Resources**: Resources with binary content remain unchanged with their original MIME type This allows clients to understand both the current format and the original format of the resource. ### 4.3 Implementation-Specific Extensions Implementations MAY add additional type preservation mechanisms using custom annotations: - Python: `pythonType` annotation with Python type names - TypeScript: `typescriptType` with TypeScript type names - Other languages: `<language>Type` pattern ## 5. Error Handling The proxy tool SHOULD rely on standard MCP error handling mechanisms. Implementations SHOULD raise exceptions (or language-appropriate error mechanisms) that are automatically converted to MCP protocol errors. ### 5.1 Parameter Validation When the proxy tool receives invalid parameters, it SHOULD raise appropriate errors: - Missing required parameters (e.g., `path` for info/call actions) - Invalid parameter combinations (e.g., `args` provided for list action) - Unknown action or type values ### 5.2 Capability Errors Errors from proxied capabilities SHOULD be propagated naturally: - Tool not found - Resource access errors - Invalid arguments for the proxied capability These errors are handled the same way as any other MCP tool error - the implementation raises an exception which the MCP protocol layer converts to a proper error response. ## 6. Discovery ### 6.1 Proxy Tool Discovery Clients SHOULD check for proxy support by: 1. Looking for a tool named `proxy` in the tool list 2. Checking tool description for proxy-related keywords 3. Attempting to call the proxy tool with valid parameters ### 6.2 Capability Discovery The proxy tool enables dynamic capability discovery without maintaining persistent connections: 1. Use `action: "list"` to enumerate available capabilities 2. Use `action: "info"` to get detailed metadata 3. Cache results as appropriate for performance ## 7. Security Considerations ### 7.1 Access Control Proxy implementations SHOULD: - Respect access controls of proxied servers - Implement per-capability access policies - Log proxy operations for auditing ### 7.2 Information Disclosure Proxy tools MUST NOT: - Expose internal server details in error messages - Include sensitive information in annotations - Bypass authentication of proxied servers ## 8. Compatibility ### 8.1 Backward Compatibility The proxy extension is designed to be backward compatible: - Clients unaware of proxy tools can ignore them - Standard MCP operations continue to work normally - No changes required to existing MCP tools ### 8.2 Forward Compatibility Future extensions SHOULD: - Use new annotation namespaces for additional metadata - Add new capability types through the existing interface - Maintain the core parameter structure ## 9. Implementation Guidelines ### 9.1 Client Implementation Clients supporting proxy tools SHOULD: 1. Detect proxy tool availability 2. Provide convenience methods for proxy operations 3. Handle type preservation based on annotations 4. Support transparent mode for drop-in compatibility ### 9.2 Server Implementation Servers implementing proxy tools SHOULD: 1. Validate all parameters before processing 2. Include comprehensive annotations in responses 3. Handle errors gracefully with clear messages 4. Optimize for performance with connection pooling ## 10. Examples ### 10.1 List Tools Request arguments: ```json { "action": "list", "type": "tool" } ``` Response (tool result): ```json [ { "type": "resource", "resource": { "uri": "proxy:list/tool", "mimeType": "application/json", "text": "[{\"name\":\"calculator_add\",\"description\":\"Add two numbers\"}]" }, "annotations": { "proxyAction": "list", "proxyType": "tool", "pythonType": "Tool", "many": true } } ] ``` ### 10.2 Call Tool Request arguments: ```json { "action": "call", "type": "tool", "path": "calculator_add", "args": {"a": 5, "b": 3} } ``` Response (tool result): ```json [ { "type": "text", "text": "8", "annotations": { "proxyType": "tool", "proxyAction": "call", "proxyPath": "calculator_add" } } ] ``` ## 11. References - [Model Context Protocol Specification](https://modelcontextprotocol.io/docs) - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - [Magg Implementation](https://github.com/sitbon/magg) ## 12. Reference Implementation The reference implementation in Magg includes: 1. **Server-side proxy** (`magg/proxy/server.py` and `magg/proxy/mixin.py`): - `ProxyFastMCP` wrapper class that adds proxy capabilities to FastMCP instances - `ProxyMCP` mixin class for servers that want built-in proxy support - Automatic tool registration and capability aggregation - Result transformation and annotation 2. **Client-side wrapper** (`magg/proxy/client.py`): - `ProxyClient` class that provides transparent access to proxied servers - Automatic result unwrapping and type conversion - Lazy connection management ## Appendix A: Future Considerations ### A.1 Batch Operations Future versions MAY support batch operations: ```json { "action": "batch", "operations": [ {"action": "call", "type": "tool", "path": "tool1", "args": {}}, {"action": "call", "type": "tool", "path": "tool2", "args": {}} ] } ``` ### A.2 Streaming Support Large result sets could benefit from streaming: - Use HTTP streaming for progressive results - Add pagination parameters for list operations - Support partial result delivery ### A.3 Advanced Filtering Enhanced discovery through filtering: ```json { "action": "list", "type": "tool", "filter": { "prefix": "calculator_", "tags": ["math", "arithmetic"] } } ```

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sitbon/magg'

If you have feedback or need assistance with the MCP directory API, please join our Discord server