Skip to main content

A decorator-based observability SDK for MCP (Model Context Protocol) tools with OpenTelemetry integration

Project description

MCP Observer SDK

PyPI version Python Versions License: MIT

A lightweight, decorator-based observability SDK for Model Context Protocol (MCP) tools. Add comprehensive telemetry and insights to your MCP servers with a single line of code.

Features

  • Zero-friction Integration: Add observability with a simple decorator
  • OpenTelemetry Support: Built-in tracing, metrics, and distributed context propagation
  • Privacy-First: Configurable I/O tracking with dual-consent system
  • Universal Compatibility: Works with all MCP tool function signatures
  • Dual Storage: Durable storage for analytics + real-time streaming via OpenTelemetry
  • Session Tracking: Automatic session and request correlation

Installation

From PyPI

pip install mcp-observer

Using uv (recommended)

uv pip install mcp-observer

For development

# Clone the repository
git clone https://github.com/yourusername/mcp-observer-sdk.git
cd mcp-observer-sdk

# Install in development mode
pip install -e ".[dev]"

Quick Start

from mcp_observer import MCPObserver
from fastmcp import FastMCP

# Initialize your MCP server
mcp = FastMCP("MyServer")

# Initialize the observer (project is automatically determined from your API key)
observer = MCPObserver(
    name="MyServer",
    version="1.0.0",
    api_key="your-generated-api-key"
)

# Decorate your tools
@mcp.tool()
@observer.track(track_io=True)
async def my_tool(data: dict) -> dict:
    # Your tool logic here
    return {"result": "success"}

Examples

Example 1: Simple Tool (No Context)

from mcp_observer import MCPObserver
from fastmcp import FastMCP

mcp = FastMCP("MathServer")
observer = MCPObserver(
    name="MathServer",
    version="1.0.0",
    api_key="your-api-key"
)

@mcp.tool(name="adder", description="Add two numbers")
@observer.track(track_io=True)
async def add(a: int, b: int) -> int:
    """Add two numbers together"""
    return a + b

Example 2: Tool with Session Context

from mcp_observer import MCPObserver
from fastmcp import FastMCP, Context
from typing import Optional

mcp = FastMCP("EchoServer")
observer = MCPObserver(
    name="EchoServer",
    version="1.0.0",
    api_key="your-api-key"
)

@mcp.tool(name="echo", description="Echo the input with session tracking")
@observer.track(track_io=True)
async def echo(message: str, ctx: Optional[Context] = None) -> str:
    """Echo input string with session ID"""
    if ctx:
        return f"{message} (Session: {ctx.session_id})"
    return message

Example 3: Fingerprint-Only Tracking (Default)

For tools that handle sensitive data, omit track_io=True to only store fingerprints:

@mcp.tool(name="process_sensitive_data")
@observer.track()  # Only fingerprints stored, no full I/O
async def process_sensitive_data(user_data: dict) -> dict:
    """Process sensitive user data"""
    # Only metadata is logged, not the actual data
    return {"status": "processed"}

Parameters on MCP Observer:

Constructor

  • name: Name of your server or application (This is what appears in logging)
  • version: Version of your server/application
  • api_key: Your API key for authentication (project is automatically determined from this key)

Decorator: @observer.track()

  • track_io (bool): If True, enables full input/output tracking (requires project consent)
    • Default: False (only fingerprints are stored)

Advanced Features

OpenTelemetry Integration

The SDK automatically integrates with OpenTelemetry for distributed tracing and metrics:

observer = MCPObserver(
    name="MyServer",
    version="1.0.0",
    api_key="your-api-key",
    otlp_endpoint="http://localhost:4317",  # Optional: Send to OTLP collector
    enable_console_export=True  # Optional: Enable console debugging
)

Environment Variables:

  • OTEL_EXPORTER_OTLP_ENDPOINT: Configure OTLP endpoint for production tracing
  • OTEL_CONSOLE_EXPORT: Set to "true" to enable console span/metric export

Automatic Metrics:

  • mcp.tool.calls: Counter for tool invocations
  • mcp.tool.duration: Histogram of tool execution times (ms)
  • mcp.tool.errors: Counter for tool errors

Automatic Spans:

  • Each tool call creates a span named mcp.tool.{function_name}
  • Spans include: call_id, session_id, latency, status, error details

Tracking Policy System

The SDK uses a dual-consent system for full I/O tracking:

  1. Developer declares safety: Use @observer.track(track_io=True)
  2. Project admin enables: Backend API controls per-tool policy
  3. Results are cached: Policy responses cached for 1 hour (configurable)

This ensures sensitive data is only stored when both developer and admin consent.

Custom Logging

Pass your own logger for integration with existing logging infrastructure:

import logging

my_logger = logging.getLogger("MyApp")
my_logger.setLevel(logging.DEBUG)

observer = MCPObserver(
    name="MyServer",
    version="1.0.0",
    api_key="your-api-key",
    logger=my_logger
)

Running the Example

# Install dependencies
uv pip install -e ".[dev]"

# Run the example server
python tests/simple_example.py

API Reference

MCPObserver(name, version, api_key, **kwargs)

Initialize the observer for your MCP server.

Parameters:

  • name (str): Your server/application name
  • version (str): Your server/application version
  • api_key (str): Authentication key (project is auto-determined)
  • otlp_endpoint (str, optional): OTLP collector endpoint
  • enable_console_export (bool, optional): Enable console span/metric output
  • logger (logging.Logger, optional): Custom logger instance

@observer.track(track_io=False)

Decorator to add observability to MCP tools.

Parameters:

  • track_io (bool, optional): Enable full I/O tracking (requires project consent). Default: False

Returns:

  • Decorated async function with telemetry

Development

Running Tests

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=mcp_observer --cov-report=html

Code Quality

# Format code
black src tests

# Type checking
mypy src

# Linting
ruff check src tests

Project Structure

mcp-observer-sdk/
├── src/
│   └── mcp_observer/
│       ├── __init__.py          # Package exports
│       ├── observer.py          # Main MCPObserver class
│       └── wrapper.py           # Decorator and telemetry logic
├── tests/
│   └── simple_example.py        # Example MCP server
├── pyproject.toml               # Package configuration
├── README.md                    # This file
└── LICENSE                      # MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_observer-0.1.0.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_observer-0.1.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file mcp_observer-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_observer-0.1.0.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for mcp_observer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d446ea1bc8b9bbd42c60f3ee5c0f4b95023b0d3c6202a6a6ae9ab2cc454d7f0a
MD5 f17d3c4e47fed305e777b97c33775125
BLAKE2b-256 90210046bfd25dbd17a541791fe58ed458a7f3f74ac647296964df96666a5c77

See more details on using hashes here.

File details

Details for the file mcp_observer-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_observer-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for mcp_observer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2729a05a3a9fbee4e6f0550a5f1a651fcc205d20a341120ac59fcc6911aa3e69
MD5 717437b117585882310fe6b014ba4d66
BLAKE2b-256 47be163325840fe76b7c9e1ac9630cb7c53f7eb875489463d6273cd14ef82b1a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page