Documentation Index Fetch the complete documentation index at: https://sedataai.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
This is the canonical example shipped in the
sedata-ai-packages
repo at example-servers/typescript-mcp-server/. It instruments two tools:
calculate-bmi — pure math, no safety check.
text-summarizer — accepts free-form text, wrapped with safetyCheck.
Project setup
mkdir weather-mcp-server && cd weather-mcp-server
npm init -y
npm install @sedata-ai/mcp @modelcontextprotocol/sdk zod
npm install -D typescript ts-node @types/node
npx tsc --init
Set your token:
export SEDATA_TOKEN = "sk_live_xxx"
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.2.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 )
// 1. Math tool — no safety needed
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 output = { bmi: weightKg / ( heightM * heightM ) }
return {
content: [{ type: 'text' , text: JSON . stringify ( output ) }],
structuredContent: output ,
}
},
)
// 2. Text tool — wrap with safetyCheck
server . registerTool (
'text-summarizer' ,
{
title: 'Text Summarizer' ,
description: 'Summarize text content' ,
inputSchema: { text: z . string () },
outputSchema: { summary: z . string () },
},
safetyCheck (
async ({ text } : any ) => {
const summary = text . substring ( 0 , 100 ) + '...'
return {
content: [{ type: 'text' , text: JSON . stringify ({ summary }) }],
structuredContent: { summary },
}
},
{ parameterName: 'text' , output_screen: true },
),
)
// Graceful shutdown
const stop = async ( code = 0 ) => {
await telemetry . shutdown ()
process . exit ( code )
}
process . on ( 'SIGINT' , () => stop ( 0 ))
process . on ( 'SIGTERM' , () => stop ( 0 ))
// Connect transport
const transport = new StdioServerTransport ()
server . connect ( transport )
Run
Drive it with any MCP client (Claude Desktop, Inspector, your agent runtime).
After a few calls, traces appear at
app.sedata-ai.tech within ~5 seconds.
What you’ll see
Tool Span Notable attributes calculate-bmitools/call calculate-bmimcp.tool.name, mcp.operation.durationtext-summarizertools/call text-summarizerAbove + mcp.safety_check.flagged, mcp.safety_check.latency_ms
If the safety API flags an input, the response includes
structuredContent.summary === '🚫 CONTENT BLOCKED: ...' and the original
handler is not called.
Variations
BMI calculator only A minimal version with one tool, no safety.
Summarizer with safety Focused walkthrough of the safety wrapper.