59
59
from mcpgateway .db import Prompt as DbPrompt
60
60
from mcpgateway .db import PromptMetric , refresh_slugs_on_startup , SessionLocal
61
61
from mcpgateway .handlers .sampling import SamplingHandler
62
- from mcpgateway .models import InitializeRequest , InitializeResult , ListResourceTemplatesResult , LogLevel , ResourceContent , Root
62
+ from mcpgateway .models import InitializeResult , ListResourceTemplatesResult , LogLevel , ResourceContent , Root
63
63
from mcpgateway .observability import init_telemetry
64
64
from mcpgateway .plugins import PluginManager , PluginViolationError
65
65
from mcpgateway .schemas import (
@@ -2225,39 +2225,57 @@ async def handle_rpc(request: Request, db: Session = Depends(get_db), user: str
2225
2225
logger .debug (f"User { user } made an RPC request" )
2226
2226
body = await request .json ()
2227
2227
method = body ["method" ]
2228
- # rpc_id = body.get("id")
2228
+ req_id = body .get ("id" ) if "body" in locals () else None
2229
2229
params = body .get ("params" , {})
2230
+ server_id = params .get ("server_id" , None )
2230
2231
cursor = params .get ("cursor" ) # Extract cursor parameter
2231
2232
2232
2233
RPCRequest (jsonrpc = "2.0" , method = method , params = params ) # Validate the request body against the RPCRequest model
2233
2234
2234
- if method == "tools/list" :
2235
- tools = await tool_service .list_tools (db , cursor = cursor )
2236
- result = [t .model_dump (by_alias = True , exclude_none = True ) for t in tools ]
2235
+ if method == "initialize" :
2236
+ result = await session_registry .handle_initialize_logic (body .get ("params" , {}))
2237
+ if hasattr (result , "model_dump" ):
2238
+ result = result .model_dump (by_alias = True , exclude_none = True )
2239
+ elif method == "tools/list" :
2240
+ if server_id :
2241
+ tools = await tool_service .list_server_tools (db , server_id , cursor = cursor )
2242
+ else :
2243
+ tools = await tool_service .list_tools (db , cursor = cursor )
2244
+ result = {"tools" : [t .model_dump (by_alias = True , exclude_none = True ) for t in tools ]}
2237
2245
elif method == "list_tools" : # Legacy endpoint
2238
- tools = await tool_service .list_tools (db , cursor = cursor )
2239
- result = [t .model_dump (by_alias = True , exclude_none = True ) for t in tools ]
2240
- elif method == "initialize" :
2241
- result = initialize (
2242
- InitializeRequest (
2243
- protocol_version = params .get ("protocolVersion" ) or params .get ("protocol_version" , "" ),
2244
- capabilities = params .get ("capabilities" , {}),
2245
- client_info = params .get ("clientInfo" ) or params .get ("client_info" , {}),
2246
- ),
2247
- user ,
2248
- ).model_dump (by_alias = True , exclude_none = True )
2246
+ if server_id :
2247
+ tools = await tool_service .list_server_tools (db , server_id , cursor = cursor )
2248
+ else :
2249
+ tools = await tool_service .list_tools (db , cursor = cursor )
2250
+ result = {"tools" : [t .model_dump (by_alias = True , exclude_none = True ) for t in tools ]}
2249
2251
elif method == "list_gateways" :
2250
2252
gateways = await gateway_service .list_gateways (db , include_inactive = False )
2251
- result = [g .model_dump (by_alias = True , exclude_none = True ) for g in gateways ]
2253
+ result = { "gateways" : [g .model_dump (by_alias = True , exclude_none = True ) for g in gateways ]}
2252
2254
elif method == "list_roots" :
2253
2255
roots = await root_service .list_roots ()
2254
- result = [r .model_dump (by_alias = True , exclude_none = True ) for r in roots ]
2256
+ result = { "roots" : [r .model_dump (by_alias = True , exclude_none = True ) for r in roots ]}
2255
2257
elif method == "resources/list" :
2256
- resources = await resource_service .list_resources (db )
2257
- result = [r .model_dump (by_alias = True , exclude_none = True ) for r in resources ]
2258
+ if server_id :
2259
+ resources = await resource_service .list_server_resources (db , server_id )
2260
+ else :
2261
+ resources = await resource_service .list_resources (db )
2262
+ result = {"resources" : [r .model_dump (by_alias = True , exclude_none = True ) for r in resources ]}
2263
+ elif method == "resources/read" :
2264
+ uri = params .get ("uri" )
2265
+ request_id = params .get ("requestId" , None )
2266
+ if not uri :
2267
+ raise JSONRPCError (- 32602 , "Missing resource URI in parameters" , params )
2268
+ result = await resource_service .read_resource (db , uri , request_id = request_id , user = user )
2269
+ if hasattr (result , "model_dump" ):
2270
+ result = {"contents" : [result .model_dump (by_alias = True , exclude_none = True )]}
2271
+ else :
2272
+ result = {"contents" : [result ]}
2258
2273
elif method == "prompts/list" :
2259
- prompts = await prompt_service .list_prompts (db , cursor = cursor )
2260
- result = [p .model_dump (by_alias = True , exclude_none = True ) for p in prompts ]
2274
+ if server_id :
2275
+ prompts = await prompt_service .list_server_prompts (db , server_id , cursor = cursor )
2276
+ else :
2277
+ prompts = await prompt_service .list_prompts (db , cursor = cursor )
2278
+ result = {"prompts" : [p .model_dump (by_alias = True , exclude_none = True ) for p in prompts ]}
2261
2279
elif method == "prompts/get" :
2262
2280
name = params .get ("name" )
2263
2281
arguments = params .get ("arguments" , {})
@@ -2269,31 +2287,52 @@ async def handle_rpc(request: Request, db: Session = Depends(get_db), user: str
2269
2287
elif method == "ping" :
2270
2288
# Per the MCP spec, a ping returns an empty result.
2271
2289
result = {}
2272
- else :
2290
+ elif method == "tools/call" :
2273
2291
# Get request headers
2274
2292
headers = {k .lower (): v for k , v in request .headers .items ()}
2293
+ name = params .get ("name" )
2294
+ arguments = params .get ("arguments" , {})
2295
+ if not name :
2296
+ raise JSONRPCError (- 32602 , "Missing tool name in parameters" , params )
2275
2297
try :
2276
- result = await tool_service .invoke_tool (db = db , name = method , arguments = params , request_headers = headers )
2298
+ result = await tool_service .invoke_tool (db = db , name = name , arguments = arguments , request_headers = headers )
2277
2299
if hasattr (result , "model_dump" ):
2278
2300
result = result .model_dump (by_alias = True , exclude_none = True )
2279
2301
except ValueError :
2280
2302
result = await gateway_service .forward_request (db , method , params )
2281
2303
if hasattr (result , "model_dump" ):
2282
2304
result = result .model_dump (by_alias = True , exclude_none = True )
2305
+ # TODO: Implement methods
2306
+ elif method == "resources/templates/list" :
2307
+ result = {}
2308
+ elif method .startswith ("roots/" ):
2309
+ result = {}
2310
+ elif method .startswith ("notifications/" ):
2311
+ result = {}
2312
+ elif method .startswith ("sampling/" ):
2313
+ result = {}
2314
+ elif method .startswith ("elicitation/" ):
2315
+ result = {}
2316
+ elif method .startswith ("completion/" ):
2317
+ result = {}
2318
+ elif method .startswith ("logging/" ):
2319
+ result = {}
2320
+ else :
2321
+ raise JSONRPCError (- 32000 , "Invalid method" , params )
2283
2322
2284
- response = result
2285
- return response
2323
+ return {"jsonrpc" : "2.0" , "result" : result , "id" : req_id }
2286
2324
2287
2325
except JSONRPCError as e :
2288
- return e .to_dict ()
2326
+ error = e .to_dict ()
2327
+ return {"jsonrpc" : "2.0" , "error" : error ["error" ], "id" : req_id }
2289
2328
except Exception as e :
2290
2329
if isinstance (e , ValueError ):
2291
2330
return JSONResponse (content = {"message" : "Method invalid" }, status_code = 422 )
2292
2331
logger .error (f"RPC error: { str (e )} " )
2293
2332
return {
2294
2333
"jsonrpc" : "2.0" ,
2295
2334
"error" : {"code" : - 32000 , "message" : "Internal error" , "data" : str (e )},
2296
- "id" : body . get ( "id" ) if "body" in locals () else None ,
2335
+ "id" : req_id ,
2297
2336
}
2298
2337
2299
2338
0 commit comments