> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnetra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Context Protocol (MCP)

> Trace Model Context Protocol (MCP) server operations with Netra. Monitor tool calls, resource access, and prompt requests across MCP-based AI apps.

<img src="https://mintcdn.com/netra/u6ajHWd7ki_9CRWQ/images/integration-logos/ai-frameworks/mcp.png?fit=max&auto=format&n=u6ajHWd7ki_9CRWQ&q=85&s=dc062a138575c09f8cc7b8e791a56f01" alt="MCP" width="254" height="80" data-path="images/integration-logos/ai-frameworks/mcp.png" />

## Installation

Install both the Netra SDK and MCP:

<CodeGroup>
  ```bash Python theme={null}
  pip install netra-sdk mcp
  ```

  ```bash Typescript theme={null}
  npm install netra-sdk @modelcontextprotocol/sdk
  ```
</CodeGroup>

## Usage

Initialize the Netra SDK to trace MCP server operations:

<CodeGroup>
  ```python Python theme={null}
  from netra import Netra
  from mcp.server import Server
  from mcp.server.stdio import stdio_server
  import os

  # Initialize Netra
  Netra.init(
      headers=f"x-api-key={os.environ.get('NETRA_API_KEY')}",
      trace_content=True
  )

  # Create MCP server - automatically traced
  server = Server("example-server")
  ```

  ```typescript Typescript theme={null}
  import { Netra } from "netra-sdk";
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

  // Initialize Netra
  await Netra.init({
    headers: `x-api-key=${process.env.NETRA_API_KEY}`,
    traceContent: true
  });

  // Create MCP server - automatically traced
  const server = new Server(
    {
      name: "example-server",
      version: "1.0.0"
    },
    {
      capabilities: {
        tools: {},
        resources: {}
      }
    }
  );
  ```
</CodeGroup>

### Tools

Trace MCP tool execution:

<CodeGroup>
  ```python Python theme={null}
  from netra.decorators import workflow, task
  from netra import SpanWrapper
  from mcp.server.models import Tool
  from mcp.types import TextContent

  @server.call_tool()
  async def execute_tool(name: str, arguments: dict):
      span = SpanWrapper("mcp-tool", {
          "tool.name": name
      }).start()
      
      try:
          result = await process_tool(name, arguments)
          span.set_attribute("tool.result", str(result))
          span.end()
          
          return [TextContent(
              type="text",
              text=str(result)
          )]
      except Exception as e:
          span.set_attribute("error", str(e))
          span.end()
          raise

  @task()
  async def process_tool(name: str, args: dict):
      # Tool implementation
      return {"status": "success"}
  ```

  ```typescript Typescript theme={null}
  import { workflow, task, SpanWrapper } from "netra-sdk";
  import { CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";

  // Register tool with tracing
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
    const span = new SpanWrapper("mcp-tool", {
      "tool.name": request.params.name
    }).start();
    
    try {
      const result = await executeTool(request.params);
      span.setAttribute("tool.result", JSON.stringify(result));
      span.end();
      
      return {
        content: [{ type: "text", text: JSON.stringify(result) }]
      };
    } catch (error) {
      span.setAttribute("error", String(error));
      span.end();
      throw error;
    }
  });

  @task()
  async function executeTool(params: any) {
    // Tool implementation
    return { status: "success" };
  }
  ```
</CodeGroup>

### Resources

Trace resource access:

<CodeGroup>
  ```python Python theme={null}
  from netra import SpanWrapper
  from mcp.server.models import Resource
  from mcp.types import TextResourceContents

  @server.list_resources()
  async def list_resources():
      return [
          Resource(
              uri="file:///example.txt",
              name="Example Resource"
          )
      ]

  @server.read_resource()
  async def read_resource(uri: str):
      span = SpanWrapper("mcp-resource", {
          "resource.uri": uri
      }).start()
      
      try:
          content = await load_resource(uri)
          span.set_attribute("resource.size", len(content))
          span.end()
          
          return TextResourceContents(
              uri=uri,
              mimeType="text/plain",
              text=content
          )
      except Exception as e:
          span.set_attribute("error", str(e))
          span.end()
          raise
  ```

  ```typescript Typescript theme={null}
  import { ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";

  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
    const span = new SpanWrapper("mcp-resource", {
      "resource.uri": request.params.uri
    }).start();
    
    try {
      const content = await loadResource(request.params.uri);
      span.setAttribute("resource.size", content.length);
      span.end();
      
      return {
        contents: [{
          uri: request.params.uri,
          mimeType: "text/plain",
          text: content
        }]
      };
    } catch (error) {
      span.setAttribute("error", String(error));
      span.end();
      throw error;
    }
  });
  ```
</CodeGroup>

### Prompts

Trace prompt handling:

<CodeGroup>
  ```python Python theme={null}
  from netra import SpanWrapper
  from mcp.server.models import Prompt, PromptMessage

  @server.list_prompts()
  async def list_prompts():
      return [
          Prompt(
              name="example-prompt",
              description="Example prompt template"
          )
      ]

  @server.get_prompt()
  async def get_prompt(name: str, arguments: dict):
      span = SpanWrapper("mcp-prompt", {
          "prompt.name": name
      }).start()
      
      messages = generate_prompt(name, arguments)
      span.set_attribute("prompt.messages", len(messages))
      span.end()
      
      return messages
  ```

  ```typescript Typescript theme={null}
  import { GetPromptRequestSchema } from "@modelcontextprotocol/sdk/types.js";

  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
    const span = new SpanWrapper("mcp-prompt", {
      "prompt.name": request.params.name
    }).start();
    
    const prompt = generatePrompt(request.params);
    span.setAttribute("prompt.messages", prompt.messages.length);
    span.end();
    
    return prompt;
  });
  ```
</CodeGroup>

## Configuration

Configure MCP server tracing:

<CodeGroup>
  ```python Python theme={null}
  from netra import Netra

  Netra.init(
      headers=f"x-api-key={os.environ.get('NETRA_API_KEY')}",
      trace_content=True,
      app_name="mcp-server"
  )
  ```

  ```typescript Typescript theme={null}
  import { Netra, NetraInstruments } from "netra-sdk";

  await Netra.init({
    headers: `x-api-key=${process.env.NETRA_API_KEY}`,
    traceContent: true,
    appName: "mcp-server"
  });
  ```
</CodeGroup>

## Next Steps

* [Quick Start Guide](https://docs.getnetra.ai/quick-start/python) - Complete setup and configuration
* [Decorators](https://docs.getnetra.ai/tracing/decorators) - Add custom tracing with `@workflow`, `@agent`, and `@task` decorators
* [MCP Documentation](https://modelcontextprotocol.io/) - Official Model Context Protocol documentation
