Add reusable JSON-RPC 2.0 server library (synapse.lib.jsrpc)#4967
Draft
invisig0th wants to merge 11 commits into
Draft
Add reusable JSON-RPC 2.0 server library (synapse.lib.jsrpc)#4967invisig0th wants to merge 11 commits into
invisig0th wants to merge 11 commits into
Conversation
Add a generic JSON-RPC 2.0 server that exposes a Python object with @s_jsrpc.method-decorated methods at a URL on the Tornado web server. Supports batch, notifications, and async-generator streaming via SSE, reuses s_httpapi.Handler auth with per-method perms, and carries the calling user via s_scope. Adds s_exc.JsonRpcError for app-defined errors.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4967 +/- ##
==========================================
- Coverage 97.81% 97.78% -0.04%
==========================================
Files 299 301 +2
Lines 63433 64126 +693
==========================================
+ Hits 62047 62703 +656
- Misses 1386 1423 +37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Users now extend JsonRpcHandler and implement @s_jsrpc.method decorated methods directly, rather than passing a shared item. The getMethInfo and descrMethods helpers move onto the class as classmethods (introspecting the class and caching per-class).
Add CellMcp, a Model Context Protocol server handler built on the jsrpc JsonRpcHandler, providing the MCP lifecycle (initialize/initialized), stateful user-bound sessions (Mcp-Session-Id), Bearer-as-API-key auth, an @s_mcp.tool decorator + registry, and tools/list + tools/call with SSE streaming for async generator tools. Add CortexMcp with storm, callStorm, and getModel tools. Cells opt in by setting the _mcp_ctor class attribute, which the base Cell mounts at /api/v1/mcp during HTTP init; Cortex sets it to CortexMcp.
Extend the MCP server with the remaining server capabilities, reusing the
decorator + class-cached-registry pattern:
- @s_mcp.resource (static + {var} templates) -> resources/list,
resources/templates/list, resources/read (text/blob/json contents).
- @s_mcp.prompt -> prompts/list, prompts/get (str or message-list).
- @s_mcp.completer + completion/complete for ref/prompt and ref/resource.
- logging/setLevel + notifications/message gated on streamed tool output
via an overridable _streamItemLevel hook.
Capabilities are advertised dynamically based on non-empty registries.
CortexMcp adds syn://model, syn://stormdocs, syn://model/form/{name}
resources, a storm-query prompt, and form/type name completers; CellMcp
adds a syn://cellinfo resource.
Tools, resources, and prompts no longer declare a perm on the decorator; a method that requires permissions enforces them itself in its body. Drops the decorator perm enforcement and the _reqPerm helper.
The jsrpc @method and mcp @tool/@resource/@prompt/@completer decorators now reject non-async functions at decoration time (raise BadArg), so dispatch awaits unconditionally instead of checking inspect.isawaitable at runtime.
Drops the per-method permission declaration and its enforcement in _dispatch (and the now-unused ACCESS_DENIED constant), consistent with the MCP decorators. Methods that require permissions enforce them themselves.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
synapse/lib/jsrpc.py, a generic, reusable JSON-RPC 2.0 server that exposes an arbitrary Python object (with decorated methods carrying metadata) at a URL on the existing Tornado web server. It is intentionally protocol-agnostic; future work (e.g. an MCP server) can be built on top of it as a consumer.Details
@s_jsrpc.method(name=, desc=, params=, returns=, perm=)— opt-in decorator + rich metadata. Thenameoverride allows non-identifier method names (e.g.tools/list).getMethInfo()/descrMethods()— reusable introspection over the decorated methods (instance-cached), for building discovery layers later.Handler(s_httpapi.Handler)— a single Tornado handler doing parse + dispatch + HTTP. Mounted viacell.addHttpApi(path, s_jsrpc.Handler, {'cell':..., 'item':obj}).Accept: text/event-stream; otherwise generator output is collected into an array).reqAuthUser()), enforces optional per-method permissions, and wraps dispatch inwith s_scope.enter({'user': user})so methods recover the caller vias_scope.get('user').s_exc.JsonRpcError(code=, mesg=, data=)(new) for application-defined errors; any other uncaught exception maps to-32603Internal error withSynErrerrinfo attached aserror.data(JSON-safety guarded).Testing
synapse/tests/test_lib_jsrpc.py— covers metadata/introspection, by-position & by-name params, all error codes, per-method perms (allow/deny/grant), notifications, batch (incl. empty + all-notifications), and SSE streaming (success + mid-stream failure). 100% coverage of the new module.Notes