Skip to main content
Get Surfa up and running in 5 minutes. This guide will walk you through installing the SDK, tracking your first events, and querying them with Claude Desktop.

Prerequisites

  • Python 3.10 or higher
  • A Surfa account (sign up at surfa.dev)
  • Your Surfa API key

Step 1: Install the SDK

Install the Surfa SDK in your MCP server project:
pip install surfa-ingest
Or with uv:
uv pip install surfa-ingest

Step 2: Track Your First Event

Add Surfa to your MCP server code:
from surfa_ingest import SurfaClient
import os

# Initialize analytics client
analytics = SurfaClient(
    ingest_key=os.getenv("SURFA_INGEST_KEY"),
    api_url=os.getenv("SURFA_API_URL", "https://surfa-web.vercel.app")
)

# Set runtime info once at startup
analytics.set_runtime(
    provider="anthropic",
    model="claude-3-5-sonnet",
    mode="stdio"
)

# Track events throughout your code
analytics.track({
    "kind": "tool",
    "subtype": "call_completed",
    "tool_name": "search",
    "status": "success",
    "latency_ms": 245
})
The SDK auto-captures client_id and request_id from MCP context when you pass ctx parameter. You don’t need to extract them manually!

Step 3: Configure Your API Key

Set your Surfa API key as an environment variable:
export SURFA_INGEST_KEY=sk_live_your_key_here
export SURFA_API_URL=https://surfa-web.vercel.app
Or add to your .env file:
SURFA_INGEST_KEY=sk_live_your_key_here
SURFA_API_URL=https://surfa-web.vercel.app
Get your API key from your Surfa dashboard.

Step 4: Run Your MCP Server

Start your MCP server and trigger some tool calls:
# Example with FastMCP
uv run fastmcp run server.py
Events will be automatically tracked and sent to Surfa in real-time.

Step 5: View Your Analytics

Go to your Surfa dashboard to see:
  • Total sessions
  • Success rate
  • Average execution time
  • Event timeline
  • Error tracking
Surfa Dashboard

Step 6: Test Your MCP Connection (Optional)

Want to validate your MCP is working correctly?
1

Navigate

Go to Settings → MCP in Surfa
2

Add MCP

Click Add New MCP
3

Configure

Enter your MCP details (endpoint, transport, headers)
4

Test

Click Test Connection
5

Success

See discovered tools ✅

MCP Testing Guide

Learn how to test and debug MCP connections

Next: Query with Natural Language (Optional)

Want to query your analytics by asking Claude questions in natural language?

Set Up Surfa MCP Server

Install the Surfa MCP Server to query analytics through Claude Desktop
What you can do:
  • Ask “What’s my success rate?” → Get instant answers
  • “Find all errors from yesterday” → Filtered results
  • “Analyze my product health” → AI-powered recommendations
No dashboards. No SQL. Just conversation.

Example: Complete MCP Server

Here’s a complete example of an MCP server with Surfa tracking:
from fastmcp import FastMCP, Context
from surfa_ingest import SurfaClient
import os

# Initialize analytics
analytics = SurfaClient(
    ingest_key=os.getenv("SURFA_INGEST_KEY"),
    api_url=os.getenv("SURFA_API_URL", "https://surfa-web.vercel.app")
)

# Set runtime info
analytics.set_runtime(
    provider="mcp",
    model="my-mcp-server",
    mode="stdio"
)

# Initialize MCP server
mcp = FastMCP("my-mcp-server")

@mcp.tool()
def search(query: str, ctx: Context) -> str:
    """Search for information."""
    
    # Track tool call start (ctx auto-extracts client_id, request_id)
    analytics.track({
        "kind": "tool",
        "subtype": "call_started",
        "tool_name": "search"
    }, ctx=ctx)
    
    try:
        # Your search logic here
        results = perform_search(query)
        
        # Track success
        analytics.track({
            "kind": "tool",
            "subtype": "call_completed",
            "tool_name": "search",
            "status": "success"
        }, ctx=ctx)
        analytics.flush()
        
        return results
        
    except Exception as e:
        # Track error
        analytics.track({
            "kind": "tool",
            "subtype": "call_failed",
            "tool_name": "search",
            "status": "error"
        }, ctx=ctx)
        analytics.flush()
        raise

if __name__ == "__main__":
    mcp.run()

What’s Tracked Automatically?

When you pass the ctx parameter, the Surfa SDK automatically extracts:
  • Client ID - Identifies the MCP client (e.g., Claude Desktop) from MCP context
  • Request ID - Tracks individual requests from MCP context
  • Timestamps - When events occurred
  • Sequence Numbers - Event ordering within a session
  • Runtime Metadata - Provider, model, mode (via set_runtime())
You need to provide:
  • kind - Event kind (e.g., “tool”, “session”, “runtime”)
  • subtype - Event subtype (e.g., “call_started”, “call_completed”)
  • tool_name - Name of the tool being called
  • Custom fields - Status, latency, error messages, etc.

Next Steps

Track Events

Learn how to track different types of events

Claude Desktop Setup

Full guide to setting up Claude Desktop integration

Available Tools

Explore all MCP server tools for querying analytics

Best Practices

Tips for getting the most out of Surfa

Troubleshooting

Check:
  • API key is correct (SURFA_INGEST_KEY)
  • API URL is set (SURFA_API_URL)
  • Your MCP server is actually running
  • No firewall blocking outbound requests
Debug:
import logging
logging.basicConfig(level=logging.DEBUG)
Check:
  • Config file path is correct
  • JSON syntax is valid (no trailing commas)
  • uv path is correct (run which uv to find it)
  • Surfa MCP directory path is absolute, not relative
Debug: Check Claude Desktop logs:
tail -f ~/Library/Logs/Claude/mcp*.log
Solution: Make sure you installed the SDK in the correct environment:
pip install surfa-ingest
# or
uv pip install surfa-ingest
Verify installation:
pip list | grep surfa

Need Help?

View Documentation

Browse the full documentation

Join Discord

Get help from the community

GitHub Issues

Report bugs or request features

Email Support

Contact our support team