Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sedata-ai.tech/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through installing @sedata-ai/mcp, wrapping a basic MCP server, and verifying that traces are flowing.
You need Node.js ≥ 22.16 and @modelcontextprotocol/sdk ≥ 1.21.1. See Installation for compatibility details.

1. Install the package

npm install @sedata-ai/mcp @modelcontextprotocol/sdk zod

2. Get an API key

Sign in to the Sedata dashboard, open Settings → API keys, and create a new key scoped to your project. Set it as an environment variable:
export SEDATA_TOKEN="sk_live_xxx"

3. Wire up instrumentServer

Create a file server.ts:
server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { instrumentServer, safetyCheck } from '@sedata-ai/mcp'
import type { TelemetryConfig } from '@sedata-ai/mcp'
import { z } from 'zod'

const NAME = 'weather-mcp-server'
const VERSION = '1.0.0'

const server = new McpServer({ name: NAME, version: VERSION })

const telemetryConfig: TelemetryConfig = {
  serverName: NAME,
  serverVersion: VERSION,
  exporterEndpoint: 'https://otel.sedata-ai.tech/v1',
  exporterAuth: {
    type: 'bearer',
    token: process.env.SEDATA_TOKEN!,
  },
}

const telemetry = instrumentServer(server, telemetryConfig)
instrumentServer returns an ObservabilityInstance you can use later to record custom spans, histograms, and counters.

4. Register a tool — with optional safety check

server.ts (continued)
server.registerTool(
  'calculate-bmi',
  {
    title: 'BMI Calculator',
    description: 'Calculate Body Mass Index',
    inputSchema: { weightKg: z.number(), heightM: z.number() },
    outputSchema: { bmi: z.number() },
  },
  async ({ weightKg, heightM }) => {
    const bmi = weightKg / (heightM * heightM)
    return {
      content: [{ type: 'text', text: JSON.stringify({ bmi }) }],
      structuredContent: { bmi },
    }
  },
)

server.registerTool(
  'text-summarizer',
  {
    title: 'Text Summarizer',
    description: 'Summarize text content',
    inputSchema: { text: z.string() },
    outputSchema: { summary: z.string() },
  },
  // Wrap the handler so the `text` param is validated before the handler runs.
  safetyCheck(
    async ({ text }) => {
      const summary = text.substring(0, 100) + '...'
      return {
        content: [{ type: 'text', text: JSON.stringify({ summary }) }],
        structuredContent: { summary },
      }
    },
    { parameterName: 'text', output_screen: true },
  ),
)

const transport = new StdioServerTransport()
server.connect(transport)

5. Run it

npx ts-node server.ts
Within a few seconds you should see traces in your Sedata dashboard:
Trace appears in Sedata dashboard

What’s instrumented automatically

Every call to a tool registered via server.registerTool is wrapped in a span named tools/call <toolName> with attributes for tool metadata, request id, session id, and client address.
mcp.server.operation.duration records milliseconds per call, tagged by method, tool name, and success.
mcp.server.operation.count increments once per invocation.
mcp.server.session.duration is recorded when you call telemetry.shutdown() — capturing how long the process ran.

Next steps

Add custom spans

Record domain-specific operations alongside the auto-spans.

Tune sampling

Reduce volume in production while keeping signal in dev.

Configure auth

Bearer, API key, or basic auth against your own collector.

Production checklist

What to verify before shipping.