Skip to main content
MCPClient is an async Python client for talking to any MCP server. It handles the MCP handshake (initialize), transport setup, and session management—so you can focus on the operations you want to perform. Use MCPClient when you want explicit, predictable control, like:
  • Testing MCP servers during development
  • Building applications that need reliable MCP interactions
  • Building higher-level clients (including “agentic” flows) on top of a typed protocol layer

Quick start

Connect → do work → close.
import asyncio
from dedalus_mcp.client import MCPClient

async def main():
    # Local dev default when running `await server.serve()`
    client = await MCPClient.connect("http://127.0.0.1:8000/mcp")
    try:
        tools = await client.list_tools()
        result = await client.call_tool("add", {"a": 5, "b": 3})
        print(result)
    finally:
        await client.close()

asyncio.run(main())
Prefer async with if you want guaranteed cleanup:
from dedalus_mcp.client import MCPClient

async with await MCPClient.connect("http://127.0.0.1:8000/mcp") as client:
    tools = await client.list_tools()

Connection

Connect

from dedalus_mcp.client import MCPClient

client = await MCPClient.connect("http://127.0.0.1:8000/mcp")

Protocol info

After connecting, initialize_result is populated:
print(f"Server: {client.initialize_result.serverInfo.name}")
print(f"Protocol: {client.initialize_result.protocolVersion}")
print(f"Session: {client.session_id}")

Close

await client.close()

Alternative: open_connection(...)

open_connection(...) is a convenience wrapper that yields a connected MCPClient and cleans up automatically:
from dedalus_mcp.client import open_connection

async with open_connection("http://127.0.0.1:8000/mcp") as client:
    tools = await client.list_tools()

Ping

await client.ping()

Operations

Most client code falls into one of these buckets:

Client capabilities (server → client)

Some MCP features are initiated by the server. If you want to support them, you configure handlers when connecting.

Authentication

For protected MCP servers:

DPoP authentication

For servers using DPoP (RFC 9449) sender-constrained tokens:
from dedalus_mcp.auth.dpop import generate_dpop_keypair
from dedalus_mcp.client import DPoPAuth, MCPClient

dpop_key, _ = generate_dpop_keypair()
auth = DPoPAuth(access_token="eyJ...", dpop_key=dpop_key)

# Local dev:
client = await MCPClient.connect("http://127.0.0.1:8000/mcp", auth=auth)

# Production:
# client = await MCPClient.connect("<your MCP endpoint URL>", auth=auth)