Skip to main content
  1. Sign up — Create an account at platform.respan.ai
  2. Create an API key — Generate one on the API keys page
  3. Add credits or a provider key — Add credits on the Credits page or connect your own provider key on the Integrations page
Add the Docs MCP to your AI coding tool to get help building with Respan. No API key needed.
{
  "mcpServers": {
    "respan-docs": {
      "url": "https://docs.respan.ai/mcp"
    }
  }
}

What is MCP?

The Model Context Protocol (MCP) is Anthropic’s open protocol for connecting AI models to external tools and data sources. It standardizes how LLM applications interact with context providers through a server/client architecture.

Setup

1

Install packages

2

Set environment variables

export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
3

Initialize and run

4

View your trace

Open the Traces page to see your MCP server and client interactions with tool call spans.

Configuration

ParameterTypeDefaultDescription
api_keystr | NoneNoneFalls back to RESPAN_API_KEY env var.
base_urlstr | NoneNoneFalls back to RESPAN_BASE_URL env var.
instrumentationslist[]Plugin instrumentations to activate (e.g. MCPInstrumentor()).
is_auto_instrumentbool | NoneFalseAuto-discover and activate all installed instrumentors via OpenTelemetry entry points.
customer_identifierstr | NoneNoneDefault customer identifier for all spans.
metadatadict | NoneNoneDefault metadata attached to all spans.
environmentstr | NoneNoneEnvironment tag (e.g. "production").

Attributes

In Respan()

Set defaults at initialization — these apply to all spans.
from respan import Respan
from openinference.instrumentation.mcp import MCPInstrumentor

respan = Respan(
    instrumentations=[MCPInstrumentor()],
    customer_identifier="user_123",
    metadata={"service": "mcp-server", "version": "1.0.0"},
)

With propagate_attributes

Override per-request using a context manager.
from respan import Respan, workflow, propagate_attributes
from openinference.instrumentation.mcp import MCPInstrumentor

respan = Respan(instrumentations=[MCPInstrumentor()])

@workflow(name="handle_request")
async def handle_request(user_id: str):
    with propagate_attributes(
        customer_identifier=user_id,
        thread_identifier="conv_001",
        metadata={"plan": "pro"},
    ):
        # MCP server handles requests with attributes propagated
        pass
AttributeTypeDescription
customer_identifierstrIdentifies the end user in Respan analytics.
thread_identifierstrGroups related messages into a conversation.
metadatadictCustom key-value pairs. Merged with default metadata.

Decorators

Use @workflow and @task to create structured trace hierarchies.
from respan import Respan, workflow, task
from openinference.instrumentation.mcp import MCPInstrumentor

respan = Respan(instrumentations=[MCPInstrumentor()])

@task(name="call_mcp_tool")
async def call_tool(client, tool_name: str, args: dict) -> str:
    result = await client.call_tool(tool_name, args)
    return str(result)

@workflow(name="mcp_workflow")
async def pipeline(client):
    weather = await call_tool(client, "get_weather", {"city": "Paris"})
    print(weather)

Examples

MCP server

from mcp.server import Server
from mcp.server.stdio import stdio_server

server = Server("my-tools")

@server.tool()
async def get_weather(city: str) -> str:
    """Get the weather for a city."""
    return f"The weather in {city} is sunny, 72F"

@server.tool()
async def search_docs(query: str) -> str:
    """Search the documentation."""
    return f"Results for: {query}"

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            server.create_initialization_options(),
        )

MCP client

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

server_params = StdioServerParameters(
    command="python",
    args=["my_server.py"],
)

async def main():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # List available tools
            tools = await session.list_tools()
            print(f"Available tools: {[t.name for t in tools.tools]}")

            # Call a tool
            result = await session.call_tool("get_weather", {"city": "Paris"})
            print(result)