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:

Tools

List and call server-side functions

Resources

List and read data sources

Prompts

List and get message templates

Client capabilities (server → client)

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

Sampling

Handle LLM completion requests from servers

Elicitation

Gather user input during tool execution

Roots

Advertise filesystem boundaries to servers

Logging

Receive log messages from servers

Authentication

For protected MCP servers:

Bearer Auth

API keys and service tokens

OAuth

User consent and delegated access via browser flow

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)
Last modified on February 28, 2026