Spanly Docs
TypeScript SDK

Quickstart

Instrument a TypeScript MCP server with @spanly/sdk in one line.

This walks through wiring the SDK into a typical TypeScript MCP server built with @modelcontextprotocol/sdk. The same pattern applies to any custom transport – monitor() only cares about the Server instance.

1. Install

npm install @spanly/sdk

2. Add monitoring

import { SpanlyClient } from "@spanly/sdk";const spanlyClient = new SpanlyClient({  apiKey: process.env.SPANLY_API_KEY,});// const mcpServer = new McpServer({ name: "your-mcp-server-name", version: "1.0.0" });// Monitor your MCP server (one line!)spanlyClient.monitor(mcpServer);// mcpServer.connect(transport);

That's it – all MCP traffic on mcpServer is now reported to your Spanly project.

The monitor() call hooks into the server's request/notification dispatch path before connect() runs, so all transport types (stdio, HTTP, SSE) are captured uniformly.

3. Set the API key

export SPANLY_API_KEY=spanly_us_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The SDK reads process.env.SPANLY_API_KEY via the apiKey option you pass to the constructor. The region is encoded in the key prefix (spanly_us_… / spanly_eu_…) and auto-detected.

Full example – stdio MCP server

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { SpanlyClient } from '@spanly/sdk';

async function main() {
  const mcpServer = new McpServer({
    name: 'demo-server',
    version: '1.0.0',
  });

  mcpServer.tool(
    'echo',
    { input: { type: 'string' } },
    async ({ input }) => ({
      content: [{ type: 'text', text: input }],
    }),
  );

  const spanly = new SpanlyClient({
    apiKey: process.env.SPANLY_API_KEY,
  });
  spanly.monitor(mcpServer);

  const transport = new StdioServerTransport();
  await mcpServer.connect(transport);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

Full example – HTTP MCP server

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { SpanlyClient } from '@spanly/sdk';

const mcpServer = new McpServer({
  name: 'demo-http-server',
  version: '1.0.0',
});

mcpServer.tool('ping', {}, async () => ({
  content: [{ type: 'text', text: 'pong' }],
}));

const spanly = new SpanlyClient({
  apiKey: process.env.SPANLY_API_KEY,
});
spanly.monitor(mcpServer);

const app = express();
const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: () => crypto.randomUUID(),
});
await mcpServer.connect(transport);

app.use('/mcp', transport.handler);
app.listen(3000);

Next steps

  • The API reference covers every option on SpanlyClient and monitor().
  • Examples show common integrations: Claude Desktop, Cursor, multi-tenant agents.
  • If you'd rather not change code, the CLI wraps the same server with the same capture behavior.

On this page