Model Context Protocol (MCP) is an open protocol that lets agents call tools, fetch resources, and receive prompts from independent server processes. TheDocumentation Index
Fetch the complete documentation index at: https://arize-ax.mintlify.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
openinference-instrumentation-mcp package is unusual: it doesn’t emit any spans of its own. Instead, it propagates OpenTelemetry context across the MCP wire protocol so that spans created independently in the client and the server join into a single unified trace.
That means you need to install MCPInstrumentor alongside another instrumentor that does emit spans (one of the OpenInference framework or LLM instrumentors) in both processes, and have both write to the same Arize AX project.
Prerequisites
- Python 3.10+
- An Arize AX account (sign up)
- An
OPENAI_API_KEYfrom the OpenAI Platform (the example uses the OpenAI Agents SDK as the span-producing instrumentor)
Launch Arize AX
- Sign in to your Arize AX account.
- From Space Settings, copy your Space ID and API Key. You will set them as
ARIZE_SPACE_IDandARIZE_API_KEYbelow.
Install
Install the union of client and server dependencies into the same environment — the scripts below import each as needed:Configure credentials
ARIZE_PROJECT_NAME and write into the same Arize AX project.
Setup tracing
The setup is identical in both processes —register() then both instrumentors. Two important details for the server:
- Pass
verbose=Falsetoregister(). The default Arize AX banner prints to stdout, which is the MCP wire-protocol channel; any stray output corrupts the protocol and the client disconnects. - Run
register()and the instrumentors before importingmcp.server.fastmcpso the patches catch the FastMCP module load.
Run MCP
The client and server are two separate Python files. The client usesMCPServerStdio to launch the server as a subprocess and pipe MCP traffic over stdin/stdout. You only run python client.py — it spawns python server.py automatically.
Expected output
Verify in Arize AX
- Open your Arize AX space and select project
mcp-tracing-example. - You should see a single new trace within ~30 seconds containing both client- and server-side spans: an
Agent workflowroot span (AGENT) wrappingOcean Assistant,turn(CHAIN),mcp_tools(CHAIN),response(LLM) child spans from the client, and anexplain_ocean(TOOL) span emitted by the server. The server’s tool span is parented under the client’s agent — that unified parenting is the valueMCPInstrumentorprovides. - If no traces appear, see Troubleshooting.
Troubleshooting
- No traces in Arize AX. Confirm
ARIZE_SPACE_IDandARIZE_API_KEYare set in the same shell that runsclient.py. Enable OpenTelemetry debug logs withexport OTEL_LOG_LEVEL=debugand re-run. Connection closedfromMCPServerStdio. Almost always something the server wrote to stdout before the MCP handshake completed. Confirm the server’sregister()call usesverbose=False, and remove anyprint(...)statements from server module-level code.KeyError: 'ARIZE_PROJECT_NAME'(or any other env var) in the server. The client is not passing its environment through to the subprocess. Make sure theparamsdict inMCPServerStdio(...)includes"env": dict(os.environ).- Client and server show up as separate traces.
MCPInstrumentor().instrument(...)must run in both processes, beforemcp/agents.mcpis imported. If only one side is instrumented, context isn’t propagated and each side gets its own trace. 401from OpenAI. VerifyOPENAI_API_KEYis set and has access togpt-5. The client and the server’s tool both call OpenAI; both need the key. The singleexport OPENAI_API_KEY=...from Configure credentials covers both because the client passesenv=dict(os.environ)to the subprocess.- Different LLM provider on the server. Swap the server’s
openai.OpenAI()+ the model name for the provider you want, and add the corresponding OpenInference instrumentor toinstrumentation_server.py(e.g.openinference-instrumentation-anthropicfor Anthropic). The client’s instrumentation does not need to change.