Skip to main content

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.

function safetyCheck(
  handler: (params: any) => Promise<any> | any,
  options: SafetyCheckOptions,
): (params: any) => Promise<any>
A higher-order function that wraps an MCP tool handler so that one of its input parameters is validated against Sedata’s safety API before the handler runs. Flagged input short-circuits with a structured “blocked” response.

Parameters

handler
(params: any) => Promise<any> | any
required
Your original tool handler, exactly as you’d pass to server.registerTool.
options
SafetyCheckOptions
required
Configuration for the wrapper.

SafetyCheckOptions

parameterName
string
required
Name of the parameter on the handler input to validate. Only string values are checked — non-string values are ignored.
output_screen
boolean
When true, prints a 🚨 Safety Check Alert: ... line to stdout when content is flagged. Useful for local debugging. Defaults to false.
endpoint
string
Reserved for a future override of the safety endpoint. Currently the wrapper always calls https://api.sedata-ai.tech/security/safety-check.

Returns

A new handler with the same signature. Internally:
  • Reads params[options.parameterName].
  • If it’s a string, calls checkSafety(value) and writes the result to params._safetyCheck so the instrumentation layer can attach mcp.safety_check.* attributes.
  • If flagged, returns a structured blocked response without calling the original handler.
  • Otherwise calls the original handler with params.

Blocked response

{
  "content": [
    {
      "type": "text",
      "text": "{ \"summary\": \"🚫 CONTENT BLOCKED: ...\", \"blocked\": true, \"reason\": \"Content flagged by safety check\", \"timestamp\": \"...\" }"
    }
  ],
  "structuredContent": {
    "summary": "🚫 CONTENT BLOCKED: ..."
  }
}
The structuredContent.summary field is what most tools surface to the caller. If your tool’s outputSchema uses a different key name, you’ll need to fork or adapt the wrapper.

Example

import { z } from 'zod'
import { safetyCheck } from '@sedata-ai/mcp'

server.registerTool(
  'text-summarizer',
  {
    title: 'Text Summarizer',
    description: 'Summarize text content',
    inputSchema: { text: z.string() },
    outputSchema: { summary: z.string() },
  },
  safetyCheck(
    async ({ text }) => {
      const summary = text.substring(0, 100) + '...'
      return {
        content: [{ type: 'text', text: JSON.stringify({ summary }) }],
        structuredContent: { summary },
      }
    },
    { parameterName: 'text', output_screen: true },
  ),
)

Authentication

The wrapper uses the API key set during instrumentServer(...). Both exporterAuth.apiKey and exporterAuth.token are forwarded as the x-api-key header. To override:
import { setTelemetryApiKey } from '@sedata-ai/mcp'
setTelemetryApiKey('different-key')

Failure modes

FailureBehavior
Network errorLogged. Handler runs. _safetyCheck.success = false.
Non-200 from safety APILogged. Handler runs. _safetyCheck.success = false.
parameterName not a string or missingHandler runs without check.
The wrapper fails open — telemetry should never break your tool.

Span attributes added

When the wrapper runs, the active tool span receives:
AttributeType
mcp.safety_check.contentstring
mcp.safety_check.flaggedboolean
mcp.safety_check.latency_msnumber
mcp.safety_check.successboolean

See also

checkSafety

The lower-level function that talks to the safety API.

Safety checks concept

What it means and when to use it.