Skip to main content
Version: 13 - TBD

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:

OutputWhat it holds
resultThe JSON-RPC result member (present on success).
errorThe JSON-RPC error object, if the server returned one.
idThe request id echoed by the server.
jsonThe full response envelope as parsed JSON.
status_codeThe HTTP status code of the transport.
headersThe 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:

  • URLscheme, host, port, base_path and path. The full request path is <base_path>/<path>. Unlike the REST connector, flow_api.split_url(...) is not a drop-in here: it emits only {'scheme': 'https'}, while the JSONRPC scheme input 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} (add server_ca to trust a self-signed certificate, or client_cert / client_key for mutual TLS). For plain HTTP pass {'scheme': 'http'}.
  • port — omit it (or pass None) to use the scheme default (443 for HTTPS, 80 for HTTP), or pass {'port_mode': 'port_number', 'port_number': 8443}.
  • method and params — the JSON-RPC method name, and its params as a JSON array (positional) or object (named). Leave params empty to omit the member.
  • request_id — the JSON-RPC id. Leave it empty to auto-generate a unique id.
  • authentication and headers — the same authentication methods as the REST connector (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')
One method call per connection

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.

Session-based MCP servers

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.

Learn More

ConnectorTypeJSONRPC (reference)
Connectors
MCP server
Connection Resilience