JSON-RPC & MCP client
About
The JSONRPC connector calls a JSON-RPC 2.0
endpoint from a flow. It builds on the REST connector's
engine-side HTTP transport — URL building, authentication, TLS, proxy and
timeouts all work the same way — and layers the JSON-RPC request/response
envelope on top.
Each this.connect(connector_type='JSONRPC', ...) call makes one method
call. The connector POSTs a {"jsonrpc": "2.0", "method": ..., "params": ..., "id": ...} envelope as application/json and parses the reply. The parsed
members are returned as connection outputs:
| Output | What it holds |
|---|---|
result | The JSON-RPC result member (present on success). |
error | The JSON-RPC error object, if the server returned one. |
id | The request id echoed by the server. |
json | The full response envelope as parsed JSON. |
status_code | The HTTP status code of the transport. |
headers | The HTTP response headers. |
A JSON-RPC error member in the reply ends the connection with ENDED_ERROR
(the error object is still returned in the error output, so an error handler
can inspect it). An HTTP status code outside expected_status_code ends the
connection with ENDED_ERROR before the envelope is parsed.
Making a call
The JSONRPC connector takes a structured input rather than a single URL
string — the same URL parts as the REST connector, plus the JSON-RPC members:
- URL —
scheme,host,port,base_pathandpath. The full request path is<base_path>/<path>. Unlike theRESTconnector,flow_api.split_url(...)is not a drop-in here: it emits only{'scheme': 'https'}, while theJSONRPCschemeinput expects the full TLS object (see below). Build the URL parts explicitly. scheme— for HTTPS pass an object:{'scheme': 'https', 'verify_ssl': True, 'check_hostname': True}(addserver_cato trust a self-signed certificate, orclient_cert/client_keyfor mutual TLS). For plain HTTP pass{'scheme': 'http'}.port— omit it (or passNone) to use the scheme default (443 for HTTPS, 80 for HTTP), or pass{'port_mode': 'port_number', 'port_number': 8443}.methodandparams— the JSON-RPC method name, and its params as a JSON array (positional) or object (named). Leaveparamsempty to omit the member.request_id— the JSON-RPCid. Leave it empty to auto-generate a unique id.authenticationandheaders— the same authentication methods as theRESTconnector (none,bearer_token,username_password_basic,secret_headers,oauth_grant), plus any extra request headers as{name, value}pairs.
import flow_api
def handler(system: flow_api.System, this: flow_api.Execution, inputs: dict):
rpc = this.connect(
connector_type='JSONRPC',
name='call JSON-RPC method',
scheme={'scheme': 'https', 'verify_ssl': True, 'check_hostname': True},
host='api.example.com',
base_path='/rpc',
path='/v1',
authentication={
'authentication_method': 'bearer_token',
'token': 'my-token',
},
method='ping',
params={'message': 'hello'},
).get('output_value')
this.log(result=rpc['result'])
return this.success('all done')
Each connection makes a single method call. To call several methods, make
several this.connect(...) calls — each is its own connection execution with its
own inputs and outputs.
Notifications
A JSON-RPC notification is a method call the server must not reply to. Set
notification=True to omit the id member and skip reading a response body:
this.connect(
connector_type='JSONRPC',
name='fire-and-forget notification',
scheme={'scheme': 'https', 'verify_ssl': True, 'check_hostname': True},
host='api.example.com',
path='/rpc',
method='log_event',
params={'event': 'started'},
notification=True,
)
The request_id input is ignored when notification is set.
Worked example: calling an MCP server
The Model Context Protocol (MCP) uses JSON-RPC 2.0 as its
transport, so the JSONRPC connector can drive an MCP server directly — compose
the initialize / tools/list / tools/call method calls from a flow. MCP over
HTTP needs one transport header: Accept: application/json, text/event-stream.
The example below points at this workspace's own MCP server
(/api/latest/mcp, stateless, plain application/json, Bearer api-key) and lists
its tools. It mirrors the permanent integration test
integrationtest-system-jsonrpc-mcp-tools-list.
import yarl
import flow_api
def handler(system: flow_api.System, this: flow_api.Execution, inputs: dict):
api_url = system.get_api_url()
url = yarl.URL(api_url)
rpc = this.connect(
connector_type='JSONRPC',
name='JSONRPC tools/list -> own MCP',
scheme={'scheme': 'https', 'verify_ssl': True, 'check_hostname': True},
host=url.host,
port={'port_mode': 'port_number', 'port_number': url.port},
base_path=url.path, # e.g. /api/latest
path='/mcp', # full path -> /api/latest/mcp
authentication={
'authentication_method': 'bearer_token',
'token': 'YOUR-API-KEY', # an api-key with MCP access
},
headers=[{
'name': 'Accept',
'value': 'application/json, text/event-stream',
}],
method='tools/list',
params={},
request_id='tools-list-1',
).get('output_value')
tools = rpc['result']['tools']
this.log(tool_count=len(tools))
return this.success(f'MCP exposes {len(tools)} tools')
To call a tool instead of listing, use method='tools/call' with
params={'name': '<tool>', 'arguments': {...}}. The same shape works against any
JSON-RPC-based MCP server — set the server's host, its bearer token (or other
authentication), and any session id it requires via the headers input.
Cloudomation's own MCP endpoint is stateless — no handshake or session id is
needed, just call tools/list / tools/call directly. A stateful MCP server
instead expects an initialize call first and returns a session id (commonly in
an Mcp-Session-Id response header) that you then send back on every following
call via the headers input.