-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[TT-16492] json rpc mcp request handling #7719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…hnologies/tyk into TT-16492-mcp-request-handling-json-rpc-routing
…ting # Conflicts: # apidef/oas/linter_test.go # apidef/oas/mcp_primitive.go # apidef/oas/mcp_primitive_test.go # apidef/oas/mcp_test.go # apidef/oas/middleware.go
…to TT-16492-mcp-request-handling-json-rpc-routing
…to TT-16492-mcp-request-handling-json-rpc-routing
…to TT-16492-mcp-request-handling-json-rpc-routing
- Add constants for JSON-RPC parameter keys, primitive prefixes, and error messages - Replace magic strings throughout gateway/mw_mcp_jsonrpc.go - Update test to use constant for error message assertion - Use consistent key format in mcp_vem.go
- Add extractAndValidateParam helper to eliminate repeated validation pattern - Replace switch statement with methodPrefixMap for cleaner buildUnregisteredVEMPath - Simplify parameter extraction in routeRequest method
- Extract validateJSONRPCRequest to check request type - Extract readAndParseJSONRPC to handle parsing and validation - Extract setupJSONRPCRouting to configure context and routing - Simplify ProcessRequest to show high-level flow - Improve variable naming in matchResourceURI for better readability
- Add detailed precedence rules for matchResourceURI wildcard matching - Expand passthrough comment to explain discovery, notifications, and operations - Clarify which requests are handled by upstream MCP server
Operation-level rate limits were ignored after JSON-RPC routing to VEM paths. Fixed by extracting operation middleware using listenPath for MCP APIs and checking rate limits on both VEM and original paths.
…on-rpc-routing' into TT-16492-mcp-request-handling-json-rpc-routing
|
API Changes --- prev.txt 2026-02-01 06:26:57.357203288 +0000
+++ current.txt 2026-02-01 06:26:47.106221947 +0000
@@ -3766,6 +3766,12 @@
resources, prompts). It embeds Operation to reuse all standard middleware
(rate limiting, transforms, caching, etc.).
+func (m *MCPPrimitive) ExtractToExtendedPaths(ep *apidef.ExtendedPathsSet, path string, method string)
+ ExtractToExtendedPaths extracts middleware config, delegating to embedded
+ Operation but allowing MCPPrimitive-specific overrides. Methods without
+ overrides are promoted to Operation. Methods with empty overrides (like
+ extractTransformResponseBodyTo) are effectively disabled for MCP primitives.
+
type MCPPrimitives map[string]*MCPPrimitive
MCPPrimitives maps primitive names to their middleware configurations.
For tools: key is tool name (e.g., "get-weather"). For resources: key is
@@ -3796,6 +3802,10 @@
func (m *Middleware) Fill(api apidef.APIDefinition)
Fill fills *Middleware from apidef.APIDefinition.
+func (m *Middleware) HasMCPPrimitivesMocks() bool
+ HasMCPPrimitivesMocks checks if any MCP primitives (tools, resources,
+ prompts) have enabled mock responses.
+
type MockResponse struct {
// Enabled activates the mock response middleware.
Enabled bool `bson:"enabled" json:"enabled"`
@@ -5378,6 +5388,9 @@
}
ValidateRequest holds configuration required for validating requests.
+func (v *ValidateRequest) ExtractTo(meta *apidef.ValidateRequestMeta)
+ ExtractTo extracts *ValidateRequest into apidef.ValidateRequestMeta.
+
func (v *ValidateRequest) Fill(meta apidef.ValidatePathMeta)
Fill fills *ValidateRequest receiver from apidef.ValidateRequestMeta.
@@ -8367,8 +8380,13 @@
SelfLooping
// RequestStartTime holds the time when the request entered the middleware chain
RequestStartTime
- // MCPRouting indicates the request came via MCP JSON-RPC routing
- MCPRouting
+ // JsonRPCRouting indicates the request came via JSON-RPC routing (MCP, A2A, etc.)
+ JsonRPCRouting
+ // JSONRPCRequest stores parsed JSON-RPC request data for protocol routing (MCP, A2A, etc.)
+ JSONRPCRequest
+ // JSONRPCRoutingState stores the routing state for sequential MCP VEM processing.
+ // Used by MCPJSONRPCMiddleware and MCPVEMContinuationMiddleware.
+ JSONRPCRoutingState
)
# Package: ./dlpython
@@ -9444,9 +9462,28 @@
// Value: VEM path (e.g., "/mcp-tool:get-weather")
MCPPrimitives map[string]string
+ JSONRPCRouter jsonrpc.Router
+
+ // OperationsAllowListEnabled is true if any JSON-RPC operation (method-level) has
+ // an allow rule enabled. Pre-calculated during API loading.
+ OperationsAllowListEnabled bool
+
+ // ToolsAllowListEnabled is true if any MCP tool has an allow rule enabled.
+ // Pre-calculated during API loading.
+ ToolsAllowListEnabled bool
+
+ // ResourcesAllowListEnabled is true if any MCP resource has an allow rule enabled.
+ // Pre-calculated during API loading.
+ ResourcesAllowListEnabled bool
+
+ // PromptsAllowListEnabled is true if any MCP prompt has an allow rule enabled.
+ // Pre-calculated during API loading.
+ PromptsAllowListEnabled bool
+
// MCPAllowListEnabled is true if any MCP primitive (tool, resource, prompt) has an
// allow rule enabled. Pre-calculated during API loading to avoid iterating through
// all primitives on every JSON-RPC request that doesn't match a VEM.
+ // This is a convenience flag that combines ToolsAllowListEnabled, ResourcesAllowListEnabled, and PromptsAllowListEnabled.
MCPAllowListEnabled bool
// Has unexported fields.
}
@@ -10781,6 +10818,46 @@
Timestamp time.Time
}
+type JSONRPCError struct {
+ Code int `json:"code"`
+ Message string `json:"message"`
+ Data any `json:"data,omitempty"`
+}
+ JSONRPCError represents a JSON-RPC 2.0 error object.
+
+type JSONRPCErrorResponse struct {
+ JSONRPC string `json:"jsonrpc"`
+ Error JSONRPCError `json:"error"`
+ ID any `json:"id"`
+}
+ JSONRPCErrorResponse represents a JSON-RPC 2.0 error response.
+
+type JSONRPCMiddleware struct {
+ *BaseMiddleware
+}
+ JSONRPCMiddleware handles JSON-RPC 2.0 request detection and routing. When
+ a client sends a JSON-RPC request to a JSON-RPC endpoint, the middleware
+ detects it, extracts the method, routes to the correct VEM, and enables the
+ middleware chain to execute before proxying to upstream.
+
+func (m *JSONRPCMiddleware) EnabledForSpec() bool
+ EnabledForSpec returns true if this middleware should be enabled for the API
+ spec. It requires the API to use JSON-RPC 2.0 protocol.
+
+func (m *JSONRPCMiddleware) Name() string
+ Name returns the middleware name.
+
+func (m *JSONRPCMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, _ any) (error, int)
+ ProcessRequest handles JSON-RPC request detection and routing.
+
+type JSONRPCRequest struct {
+ JSONRPC string `json:"jsonrpc"`
+ Method string `json:"method"`
+ Params json.RawMessage `json:"params,omitempty"`
+ ID any `json:"id,omitempty"`
+}
+ JSONRPCRequest represents a JSON-RPC 2.0 request structure.
+
type JSVM struct {
Spec *APISpec
VM *otto.Otto `json:"-"`
@@ -10962,6 +11039,25 @@
Init initializes the LogMessageEventHandler instance with the given
configuration.
+type MCPVEMContinuationMiddleware struct {
+ *BaseMiddleware
+}
+ MCPVEMContinuationMiddleware handles sequential VEM routing for MCP
+ JSON-RPC requests. After each VEM stage completes its middleware chain,
+ this middleware checks the routing state and either continues to the next
+ VEM or allows the request to proceed to upstream.
+
+func (m *MCPVEMContinuationMiddleware) EnabledForSpec() bool
+ EnabledForSpec returns true if this middleware should run for the given API
+ spec. Only enabled for MCP APIs with JSON-RPC 2.0.
+
+func (m *MCPVEMContinuationMiddleware) Name() string
+ Name returns the middleware name for logging and debugging.
+
+func (m *MCPVEMContinuationMiddleware) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
+ ProcessRequest handles VEM chain continuation logic. This is GENERIC routing
+ - just follows the NextVEM chain, no protocol logic.
+
type MethodNotAllowedHandler struct{}
func (m MethodNotAllowedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) |
|
This PR introduces a significant architectural refactor for handling Model Context Protocol (MCP) requests over JSON-RPC. It replaces the previous direct routing mechanism with a new sequential, multi-stage middleware processing pipeline. This enables the granular application of policies, such as rate limiting and access control, at both the general operation level (e.g., for all Files Changed AnalysisThis is a substantial feature implementation, reflected in the 30 changed files with 4027 additions and 129 deletions. The changes are concentrated in a few key areas:
Architecture & Impact Assessment
Visualization of the New Request FlowsequenceDiagram
participant Client
participant Gateway as "Gateway (Listen Path)"
participant JSONRPCMiddleware
participant OpVEM as "Operation VEM Chain"
participant ContinuationMiddleware
participant PrimVEM as "Primitive VEM Chain"
participant Upstream
Client->>+Gateway: POST /mcp (JSON-RPC Request)
Gateway->>+JSONRPCMiddleware: ProcessRequest()
JSONRPCMiddleware-->>JSONRPCMiddleware: Parse body, build VEM chain: [OpVEM, PrimVEM]
JSONRPCMiddleware-->>Gateway: Internal redirect to OpVEM
Gateway->>+OpVEM: Execute operation-level middleware
OpVEM->>+ContinuationMiddleware: ProcessRequest()
ContinuationMiddleware-->>ContinuationMiddleware: Get next VEM from context (PrimVEM)
ContinuationMiddleware-->>Gateway: Internal redirect to PrimVEM
Gateway->>+PrimVEM: Execute primitive-level middleware
PrimVEM->>+ContinuationMiddleware: ProcessRequest()
ContinuationMiddleware-->>ContinuationMiddleware: VEM chain is complete
ContinuationMiddleware-->>Gateway: Allow request to proceed to upstream
Gateway->>+Upstream: Forward request
Upstream-->>-Gateway: Response
Gateway-->>-Client: Response
Scope Discovery & Context Expansion
Metadata
Powered by Visor from Probelabs Last updated: 2026-02-01T06:28:47.769Z | Triggered by: pr_updated | Commit: 7b5be86 💡 TIP: You can chat with Visor using |
Security Issues (2)
Architecture Issues (2)
Performance Issues (2)
Quality Issues (5)
Powered by Visor from Probelabs Last updated: 2026-02-01T06:28:50.694Z | Triggered by: pr_updated | Commit: 7b5be86 💡 TIP: You can chat with Visor using |
|



Description
Related Issue
Motivation and Context
How This Has Been Tested
Screenshots (if appropriate)
Types of changes
Checklist
Ticket Details
TT-16492
Generated at: 2026-02-01 06:26:09