Skip to content

context.mcp() – Model Context Protocol (MCP) API Reference

context.mcp() gives you access to the MCP service, which manages named MCP clients (stdio / WebSocket / HTTP), handles lifecycle (open/close), and offers thin call helpers.

Register clients after the sidecar starts. Example below uses the helper register_mcp_client().


1. MCP Clients

Three MCP clients can be established:

HttpMCPClient(name, client)

Bases: MCPClientProtocol

Initialize the HTTP client service with base URL, headers, and timeout.

This constructor sets up the base URL for all requests, applies default and custom headers, and configures the request timeout. It also initializes internal state for the asynchronous HTTP client and concurrency control.

Examples:

Basic usage with default headers:

from aethergraph.services.mcp import HttpMCPClient
client = HttpMCPClient("https://api.example.com")

Custom headers and timeout:

from aethergraph.services.mcp import HttpMCPClient
client = HttpMCPClient(
    "https://api.example.com",
    headers={"Authorization": "Bearer <token>"},
    timeout=30.0
)

Parameters:

Name Type Description Default
base_url str

The root URL for all HTTP requests (e.g., "https://api.example.com").

required
headers dict[str, str] | None

Optional dictionary of additional HTTP headers to include with each request.

None
The "Content-Type

application/json" header is always set by default.

required
timeout float

The maximum time (in seconds) to wait for a response before timing out.

60.0

Returns:

Name Type Description
None

Initializes the HttpMCPClient instance.

Notes
  • Ensure that the base_url does not have a trailing slash; it will be added automatically.
  • The client uses asynchronous HTTP requests for non-blocking operations.
WsMCPClient(name, client)

Bases: MCPClientProtocol

Initialize the WebSocket MCP client with URL, headers, and connection parameters. This class manages a WebSocket connection to an MCP (Modular Control Protocol) server, handling connection lifecycle, pinging for keepalive, and concurrency for sending JSON-RPC requests. It provides methods to list tools, call tools, list resources, and read resources via the MCP protocol.

Examples:

Basic usage with default headers:

from aethergraph.services.mcp import WsMCPClient
client = WsMCPClient("wss://mcp.example.com/ws")
await client.open()
tools = await client.list_tools()
await client.close()

Custom headers and ping interval:

from aethergraph.services.mcp import WsMCPClient
client = WsMCPClient(
    "wss://mcp.example.com/ws",
    headers={"Authorization": "Bearer <token>"},
    ping_interval=10.0,
    timeout=30.0
await client.open()

Parameters:

Name Type Description Default
url str

The WebSocket URL of the MCP server (e.g., "wss://mcp.example.com/ws").

required
headers dict[str, str] | None

Optional dictionary of additional HTTP headers to include in the WebSocket handshake.

None
timeout float

Maximum time (in seconds) to wait for connection and responses.

60.0
ping_interval float

Interval (in seconds) between WebSocket ping frames for keepalive.

20.0
ping_timeout float

Maximum time (in seconds) to wait for a ping response before considering the connection dead.

10.0

Returns:

Name Type Description
None

Initializes the WsMCPClient instance and prepares internal state.

StdioMCPClient(name, client)

Bases: MCPClientProtocol

Initialize the MCP client service to communicate with a subprocess over stdio using JSON-RPC 2.0.

This class launches a subprocess (typically an MCP server), manages its lifecycle, and provides asynchronous methods to interact with it using JSON-RPC 2.0 over standard input/output streams. It handles command execution, environment setup, request/response serialization, and concurrency control for safe multi-call usage.

Examples:

Basic usage with default environment:

from aethergraph.services.mcp import StdioMCPClient
client = StdioMCPClient(["python", "mcp_server.py"])
await client.open()
tools = await client.list_tools()
await client.close()

Custom environment and timeout:

from aethergraph.services.mcp import StdioMCPClient
client = StdioMCPClient(
    ["python", "mcp_server.py"],
    env={"MY_ENV_VAR": "value"},
    timeout=30.0
)

Parameters:

Name Type Description Default
cmd list[str]

Command to start the MCP server subprocess (list of str).

required
env dict[str, str] | None

Optional dictionary of environment variables for the subprocess.

None
timeout float

Timeout in seconds for each RPC call.

60.0

Returns:

Name Type Description
None

Initializes the StdioMCPClient instance.

Notes
  • The subprocess should adhere to the JSON-RPC 2.0 specification over stdio.
  • Ensure proper error handling in the subprocess to avoid deadlocks.

2. Registration

register_mcp_client(name, client)

Register a new MCP client with the current MCP service.

This function adds a client instance to the MCP service under the specified name, allowing it to be accessed and managed by the MCP infrastructure.

Examples:

from aethergraph.runtime import register_mcp_client
from aethergraph.services.mcp import HttpMCPClient
my_client = HttpMCPClient("https://mcp.example.com", ...)
register_mcp_client("myclient", my_client)

Parameters:

Name Type Description Default
name str

The unique name to associate with the MCP client.

required
client Any

The client instance to register.

required

Returns:

Type Description
None

None

Raises:

Type Description
RuntimeError

If no MCP service has been installed via set_mcp_service().

list_mcp_clients(name, client)

List all registered MCP client names in the current MCP service.

This function returns a list of all client names that have been registered with the MCP service, allowing for discovery and management of available clients.

Examples:

from aethergraph.runtime import list_mcp_clients
clients = list_mcp_clients()
print(clients)

Returns:

Type Description
list[str]

A list of strings representing the names of registered MCP clients.

list[str]

Returns an empty list if no MCP service is installed or no clients are registered.


3. Service Methods

register(name, client)

Register a new MCP client under a given name.

Examples:

context.mcp().register("myserver", my_client)

Parameters:

Name Type Description Default
name str

The name to register the client under.

required
client MCPClientProtocol

The MCPClientProtocol instance to register.

required
remove(name)

Remove a registered MCP client by name.

Examples:

context.mcp().remove("myserver")

Parameters:

Name Type Description Default
name str

The name of the client to remove.

required
has(name)

Check if a client with the given name is registered.

Examples:

if context.mcp().has("default"):
    print("Client exists")

Parameters:

Name Type Description Default
name str

The name to check.

required

Returns:

Name Type Description
bool bool

True if the client exists, False otherwise.

names()

Get a list of all registered client names.

Examples:

names = context.mcp().names()

Returns:

Type Description
list[str]

list[str]: List of registered client names.

list_clients()

List all registered client names.

Examples:

clients = context.mcp().list_clients()

Returns:

Type Description
list[str]

list[str]: List of registered client names.

get(name='default')

Retrieve a registered MCP client by name.

Examples:

client = context.mcp().get("default")

Parameters:

Name Type Description Default
name str

The name of the client to retrieve.

'default'

Returns:

Name Type Description
MCPClientProtocol MCPClientProtocol

The registered client.

Raises:

Type Description
KeyError

If the client is not found.

open(name)

Open the connection for a specific MCP client.

Examples:

await context.mcp().open("default")

Parameters:

Name Type Description Default
name str

The name of the client to open.

required
close(name)

Close the connection for a specific MCP client.

Examples:

await context.mcp().close("default")

Parameters:

Name Type Description Default
name str

The name of the client to close.

required
open_all()

Open all registered MCP client connections.

Examples:

await context.mcp().open_all()
close_all()

Close all registered MCP client connections.

Examples:

await context.mcp().close_all()
call(name, tool, params=None)

Call a tool on a specific MCP client, opening the connection if needed.

Examples:

result = await context.mcp().call("default", "sum", {"a": 1, "b": 2})

Parameters:

Name Type Description Default
name str

The name of the client to use.

required
tool str

The tool name to call.

required
params dict[str, Any] | None

Optional dictionary of parameters for the tool.

None

Returns:

Type Description
dict[str, Any]

dict[str, Any]: The result from the tool call.

list_tools(name)

List all tools available on a specific MCP client.

Examples:

tools = await context.mcp().list_tools("default")

Parameters:

Name Type Description Default
name str

The name of the client.

required

Returns:

Type Description
list[MCPTool]

list[MCPTool]: List of available tools.

list_resources(name)

List all resources available on a specific MCP client.

Examples:

resources = await context.mcp().list_resources("default")

Parameters:

Name Type Description Default
name str

The name of the client.

required

Returns:

Type Description
list[MCPResource]

list[MCPResource]: List of available resources.

read_resource(name, uri)

Read a resource from a specific MCP client.

Examples:

data = await context.mcp().read_resource("default", "resource://foo/bar")

Parameters:

Name Type Description Default
name str

The name of the client.

required
uri str

The URI of the resource to read.

required

Returns:

Type Description
dict[str, Any]

dict[str, Any]: The resource data.

set_header(name, key, value)

Set or override a header for a websocket client at runtime.

Examples:

context.mcp().set_header("default", "Authorization", "Bearer token")

Parameters:

Name Type Description Default
name str

The name of the client.

required
key str

The header key.

required
value str

The header value.

required

Raises:

Type Description
RuntimeError

If the client does not support headers.

persist_secret(secret_name, value)

Persist a secret using the configured secrets provider.

Examples:

context.mcp().persist_secret("API_KEY", "my-secret-value")

Parameters:

Name Type Description Default
secret_name str

The name of the secret.

required
value str

The value to persist.

required

Raises:

Type Description
RuntimeError

If the secrets provider is not writable.


Registering Clients (after sidecar starts)

Start the sidecar, then register one or more MCP clients:

from aethergraph import start_server
from aethergraph.runtime import register_mcp_client
from aethergraph.plugins.mcp import StdioMCPClient, WsMCPClient, HttpMCPClient
import sys

# 1) Start sidecar (choose your port/logging as you prefer)
start_server(port=0)

# 2) Register a local stdio MCP (no auth/network)
register_mcp_client(
    "local",
    client=StdioMCPClient(cmd=[sys.executable, "-m", "aethergraph.plugins.mcp.fs_server"]),
)

# 3) (Optional) Register a WebSocket MCP
register_mcp_client(
    "ws",
    client=WsMCPClient(
        url="wss://mcp.example.com/ws",
        headers={"Authorization": "Bearer <token>"},
        timeout=60.0,
    ),
)

# 4) (Optional) Register an HTTP MCP
register_mcp_client(
    "http",
    client=HttpMCPClient(
        base_url="https://mcp.example.com/api",
        headers={"Authorization": "Bearer <token>"},
        timeout=60.0,
    ),
)

Client types:

  • StdioMCPClient(cmd, env=None, timeout=60.0) – JSON‑RPC over stdio to a subprocess.
  • WsMCPClient(url, headers=None, timeout=60.0, ping_interval=20.0, ping_timeout=10.0) – JSON‑RPC over WebSocket.
  • HttpMCPClient(base_url, headers=None, timeout=60.0) – JSON‑RPC over HTTP.

Examples

# Get tool list and call a tool
mcp = context.mcp()

tools = await mcp.list_tools("local")
res = await mcp.call("local", tool="fs.read_text", params={"path": "/etc/hosts"})

# Read a resource listing from WS backend
await mcp.open("ws")
resources = await mcp.list_resources("ws")

# Set a header on the WS client (e.g., late‑bound token)
mcp.set_header("ws", "Authorization", "Bearer NEW_TOKEN")

# Clean up
await mcp.close_all()

Notes:

  • Clients lazy‑open for operations; you may still call open() explicitly.
  • Errors from the server propagate; inspect tool/resource contracts on the MCP server side for required params and shapes.