Skip to main content

DSPy

Connect a DSPy agent to Leadovaro by wrapping MCP tools as Python callables and passing them to dspy.ReAct. DSPy v2.6 does not include a built-in MCP client, so tools are discovered via the raw mcp package.

Prerequisites​

  • Python 3.11+
  • A Leadovaro account at app.leadovaro.com with a configured toolkit
  • A Leadovaro token and an Anthropic API key

Installation​

pip install dspy mcp python-dotenv

Environment Variables​

LEADOVARO_URL=/_sites/app.leadovaro.com/hub/mcp?profile=your-toolkit
LEADOVARO_TOKEN=your-leadovaro-token
ANTHROPIC_API_KEY=your-anthropic-key
Get Your Credentials

How to generate a Leadovaro token and configure toolkit URL parameters

Connecting to Leadovaro​

Discover tools via the raw mcp client and wrap each one as a Python callable for DSPy:

import os
import asyncio
from dotenv import load_dotenv
import dspy
from mcp.client.streamable_http import streamablehttp_client
from mcp import ClientSession

load_dotenv()

LEADOVARO_URL = os.environ["LEADOVARO_URL"]
LEADOVARO_TOKEN = os.environ["LEADOVARO_TOKEN"]

async def call_tool(name: str, args: dict) -> str:
"""Call a single MCP tool and return the result as a string."""
headers = {"Authorization": f"Bearer {LEADOVARO_TOKEN}"}
async with streamablehttp_client(LEADOVARO_URL, headers=headers) as (r, w, _):
async with ClientSession(r, w) as session:
await session.initialize()
result = await session.call_tool(name, args)
return str(result.content)

async def get_leadovaro_tools():
"""Discover all Leadovaro tools and wrap them as Python callables."""
headers = {"Authorization": f"Bearer {LEADOVARO_TOKEN}"}
async with streamablehttp_client(LEADOVARO_URL, headers=headers) as (r, w, _):
async with ClientSession(r, w) as session:
await session.initialize()
result = await session.list_tools()

def make_tool(name: str, desc: str):
def tool_fn(**kwargs):
return asyncio.run(call_tool(name, kwargs))
tool_fn.__name__ = name
tool_fn.__doc__ = desc or f"Call the {name} tool"
return tool_fn

return [make_tool(t.name, t.description or "") for t in result.tools]

# Configure DSPy with Claude
dspy.configure(lm=dspy.LM("anthropic/claude-sonnet-4-6"))

# Discover and wrap tools
tools = asyncio.run(get_leadovaro_tools())
print(f"{len(tools)} tools loaded")

# Create a ReAct agent
react = dspy.ReAct(signature="question -> answer", tools=tools)

Running the Agent​

result = react(question="What events do I have today?")
print(result.answer)
note

DSPy v2.6 has no built-in MCPClient. This pattern uses the raw mcp package for discovery and wraps each tool as a Python callable. Each tool call opens a new MCP connection — for production use, consider connection pooling.

Production Configuration​

For production agents, lock to a specific toolkit using the profile URL parameter:

LEADOVARO_URL=/_sites/app.leadovaro.com/hub/mcp?profile=your-production-toolkit

Reference Implementation​

dspy-reference-implementation-leadovaro

Complete implementation with FastAPI chat UI and deployment guide

Next Steps​