mcp

package
v1.86.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 23, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package mcp provides OpenTelemetry instrumentation helpers that follow the OTel GenAI semantic conventions for the Model Context Protocol (https://opentelemetry.io/docs/specs/semconv/gen-ai/mcp/).

MCP attributes use the `mcp.*` namespace (separate from `gen_ai.*`). Trace context propagates through the MCP `params._meta` field so that requests crossing client/server boundaries chain into a single trace.

The package is structured so that callers describe what they are doing in MCP terms (method name, tool name, session id) and the helpers produce the spec-conformant spans, metrics, and propagation. All helpers are no-op-safe when telemetry is disabled.

Index

Constants

View Source
const (
	AttrMethodName      = "mcp.method.name"
	AttrProtocolVersion = "mcp.protocol.version"
	AttrResourceURI     = "mcp.resource.uri"
	AttrSessionID       = "mcp.session.id"
)

MCP attribute keys defined by the OTel semantic conventions (https://opentelemetry.io/docs/specs/semconv/registry/attributes/mcp/). All are Development stability.

View Source
const (
	AttrJSONRPCRequestID       = "jsonrpc.request.id"
	AttrJSONRPCProtocolVersion = "jsonrpc.protocol.version"
	AttrRPCResponseStatusCode  = "rpc.response.status_code"
)

JSON-RPC attribute keys used alongside MCP spans for request id and response status when applicable.

View Source
const (
	AttrGenAIOperationName = "gen_ai.operation.name"
	AttrGenAIToolName      = "gen_ai.tool.name"
	AttrGenAIPromptName    = "gen_ai.prompt.name"
)

gen_ai.* attribute keys that the MCP semconv overlays on MCP spans when applicable. These are duplicated here as constants so the MCP package doesn't depend on the genai package — keeping the two telemetry helpers compositional.

View Source
const (
	MethodInitialize         = "initialize"
	MethodPing               = "ping"
	MethodCompletionComplete = "completion/complete"
	MethodPromptsList        = "prompts/list"
	MethodPromptsGet         = "prompts/get"
	MethodResourcesList      = "resources/list"
	MethodResourcesRead      = "resources/read"
	MethodResourcesSubscribe = "resources/subscribe"
	MethodResourcesUnsub     = "resources/unsubscribe"
	MethodResourcesTemplates = "resources/templates/list"
	MethodRootsList          = "roots/list"
	MethodSamplingCreate     = "sampling/createMessage"
	MethodToolsList          = "tools/list"
	MethodToolsCall          = "tools/call"
	MethodLoggingSetLevel    = "logging/setLevel"
	MethodElicitationCreate  = "elicitation/create"
)

Well-known MCP method names (https://modelcontextprotocol.io/specification). These match the values listed in the OTel semconv registry.

View Source
const OperationExecuteTool = "execute_tool"

OperationExecuteTool is the gen_ai.operation.name value used on MCP tools/call spans per the spec.

Variables

This section is empty.

Functions

func ClassifyError

func ClassifyError(err error) string

ClassifyError maps an MCP error to a low-cardinality error.type value. MCP errors are often plain RPC errors; this helper picks reasonable labels for cancellation and falls back to the type name otherwise.

func ConversationIDFromBaggage

func ConversationIDFromBaggage(ctx context.Context) string

ConversationIDFromBaggage reads `gen_ai.conversation.id` from the context's W3C baggage. The MCP package mirrors the genai package's convention so MCP spans automatically carry the session id when the runtime has seeded it; the value also propagates across MCP server boundaries via the standard `baggage` header alongside `traceparent`.

Exported so adjacent code (e.g. the MCP OAuth transport) can attach the same attribute to spans it creates directly via `otel.Tracer`.

func EnsureMeta

func EnsureMeta(m map[string]any) map[string]any

EnsureMeta returns a metadata map suitable for InjectMeta to write trace context into. When m is non-nil it is shallow-copied so an upstream caller that reuses the same request struct (e.g. on retry) does not see stale `traceparent` keys from a previous span injected into the map they own. When m is nil a fresh map is allocated.

func ExtractMeta

func ExtractMeta(ctx context.Context, meta map[string]any) context.Context

ExtractMeta reads trace context from the given MCP `_meta` map and returns a context with the parent span attached. Use on the server side to chain incoming spans onto the client's caller.

func InjectMeta

func InjectMeta(ctx context.Context, meta map[string]any)

InjectMeta writes the active trace context into the given MCP `_meta` map so the receiving server can extract it and parent its SERVER span onto our CLIENT span. Per the MCP semconv, the keys written are `traceparent`, `tracestate`, and `baggage` (W3C TraceContext + Baggage).

If meta is nil, InjectMeta is a no-op — callers should ensure the map is non-nil before calling so the keys actually persist on the request.

Types

type CallOptions

type CallOptions struct {
	// Method is the MCP method name (e.g. "tools/call"). Required.
	Method string

	// Target is the low-cardinality target of the operation: tool name
	// for tools/call, prompt name for prompts/get, etc. When set the
	// span name becomes "{method} {target}"; otherwise just "{method}".
	Target string

	// ToolName, when set, is recorded as gen_ai.tool.name and used as
	// the default Target for tools/call.
	ToolName string

	// PromptName, when set, is recorded as gen_ai.prompt.name and used
	// as the default Target for prompts/get.
	PromptName string

	// ResourceURI, when set, is recorded as mcp.resource.uri and used
	// as the default Target for resources/* methods.
	ResourceURI string

	// SessionID identifies the MCP session and is recorded as
	// mcp.session.id when set.
	SessionID string

	// ProtocolVersion is recorded as mcp.protocol.version when set.
	ProtocolVersion string

	// JSONRPCRequestID is recorded as jsonrpc.request.id when set
	// (client-side requests; ignored for notifications).
	JSONRPCRequestID string

	// ServerAddress / ServerPort identify the MCP endpoint when known.
	ServerAddress string
	ServerPort    int
}

CallOptions describes an MCP request being made or handled. Used by both client- and server-side helpers so call sites depend on a single vocabulary.

type Span

type Span struct {
	// contains filtered or unexported fields
}

Span is the handle returned by StartClient / StartServer. It carries enough state to record `mcp.{client,server}.operation.duration` and to flush span attributes as the operation proceeds.

func StartClient

func StartClient(ctx context.Context, opts CallOptions) (context.Context, *Span)

StartClient begins a CLIENT-kind MCP span and returns a context carrying it. Callers MUST call Span.End to flush the span and metrics.

func StartServer

func StartServer(ctx context.Context, opts CallOptions) (context.Context, *Span)

StartServer begins a SERVER-kind MCP span. Use after extracting trace context from the incoming `params._meta` so the span chains onto the caller. Callers MUST call Span.End.

func (*Span) End

func (s *Span) End()

End closes the span and records the operation duration metric. Safe to call multiple times; subsequent calls are no-ops.

func (*Span) RecordError

func (s *Span) RecordError(err error, errType string)

RecordError marks the span as failed and stores error.type for the duration metric. errType should be a short, low-cardinality string; when empty, ClassifyError(err) supplies a value (one of "context_canceled", "deadline_exceeded", "rpc_error").

func (*Span) SetAttributes

func (s *Span) SetAttributes(attrs ...attribute.KeyValue)

SetAttributes adds extra attributes to the span. Use for MCP extensions or for response-side attributes the caller learns later (e.g. rpc.response.status_code).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL