mcp

package
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CodeParseError     = -32700
	CodeInvalidRequest = -32600
	CodeMethodNotFound = -32601
	CodeInvalidParams  = -32602
	CodeInternalError  = -32603
	CodeServerError    = -32000

	// CodeHeaderMismatch identifies missing, malformed, or mismatched
	// 2026-07-28 Streamable HTTP routing headers.
	CodeHeaderMismatch = -32020
	// CodeMissingRequiredClientCapability identifies a 2026-07-28 request
	// whose per-request client capabilities cannot satisfy the result.
	CodeMissingRequiredClientCapability = -32021
	// CodeUnsupportedProtocolVersion identifies a request for a protocol
	// version that this server does not implement.
	CodeUnsupportedProtocolVersion = -32022
)

Standard JSON-RPC 2.0 error codes.

View Source
const ProtocolVersion20260728 = "2026-07-28"

ProtocolVersion20260728 is the stateless MCP protocol version.

Variables

View Source
var (
	ErrStreamNotFound      = errors.New("stream not found")
	ErrEventNotFound       = errors.New("event not found")
	ErrStreamEventTooLarge = errors.New("stream event too large")
)
View Source
var ErrSessionNotFound = errors.New("session not found")

ErrSessionNotFound is returned when a session ID does not exist in the store.

View Source
var ErrTaskNotFound = errors.New("task not found")

ErrTaskNotFound is returned when a task does not exist in the caller's session scope.

View Source
var ErrTaskTerminal = errors.New("task already terminal")

ErrTaskTerminal is returned when a mutation targets a task that is already in a terminal state.

Functions

func MarshalResponse

func MarshalResponse(resp *Response) ([]byte, error)

MarshalResponse serializes a JSON-RPC 2.0 response to bytes. It ensures the jsonrpc field is always set to "2.0".

Types

type CapabilityConfig

type CapabilityConfig struct {
	Tools       bool
	Resources   bool
	Prompts     bool
	Completions bool
	Tasks       bool
}

CapabilityConfig controls which implemented MCP server surfaces may be advertised during initialize.

The config is intentionally limited to surfaces that AppTheory currently implements. Unsupported MCP sub-capabilities such as listChanged and tasks are omitted until their concrete hooks exist. Resource subscription and logging are also omitted until AppTheory has a first-class outbound notification contract for notifications/resources/updated and notifications/message. Completion and task support are advertised only when their explicit hooks or stores are configured. That keeps capability negotiation fail-closed instead of allowing callers to overclaim unsupported behavior.

func DefaultCapabilityConfig

func DefaultCapabilityConfig() CapabilityConfig

DefaultCapabilityConfig returns the default MCP capability policy.

A surface is still advertised only when it is actually present on the server: tools require at least one registered tool, resources require at least one registered resource, and prompts require at least one registered prompt.

type Completion

type Completion struct {
	Values  []string `json:"values"`
	Total   *int     `json:"total,omitempty"`
	HasMore *bool    `json:"hasMore,omitempty"`
}

Completion contains completion values returned to the client.

type CompletionArgument

type CompletionArgument struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

CompletionArgument identifies the argument currently being completed.

type CompletionContext

type CompletionContext struct {
	Arguments map[string]string `json:"arguments,omitempty"`
}

CompletionContext carries optional previously-resolved arguments.

type CompletionHook

type CompletionHook func(ctx context.Context, req CompletionRequest) (*CompletionResult, error)

CompletionHook handles a prompt or resource completion request.

type CompletionRef

type CompletionRef struct {
	Type string `json:"type"`
	Name string `json:"name,omitempty"`
	URI  string `json:"uri,omitempty"`
}

CompletionRef identifies the prompt or resource template being completed.

type CompletionRequest

type CompletionRequest struct {
	SessionID string             `json:"sessionId"`
	Ref       CompletionRef      `json:"ref"`
	Argument  CompletionArgument `json:"argument"`
	Context   CompletionContext  `json:"context,omitempty"`
}

CompletionRequest is passed to completion hooks.

type CompletionResult

type CompletionResult struct {
	Completion Completion `json:"completion"`
}

CompletionResult is the MCP completion/complete result.

type ContentBlock

type ContentBlock struct {
	Type string `json:"type"` // "text", "image", "audio", "resource_link", "resource"

	// Text content (type = "text").
	Text string `json:"text,omitempty"`

	// Image/audio content (type = "image" or "audio").
	Data     string `json:"data,omitempty"`     // base64-encoded
	MimeType string `json:"mimeType,omitempty"` // e.g. "image/png"

	// Resource link content (type = "resource_link").
	URI         string `json:"uri,omitempty"`
	Name        string `json:"name,omitempty"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	Size        int64  `json:"size,omitempty"`

	// Embedded resource content (type = "resource").
	Resource *ResourceContent `json:"resource,omitempty"`
}

type CreateTaskResult

type CreateTaskResult struct {
	Meta map[string]any `json:"_meta,omitempty"`
	Task Task           `json:"task"`
}

CreateTaskResult is returned when AppTheory accepts a task-augmented request.

type DiscoverResult

type DiscoverResult struct {
	SupportedVersions []string       `json:"supportedVersions"`
	Capabilities      map[string]any `json:"capabilities"`
	Meta              map[string]any `json:"_meta"`
}

DiscoverResult is the result returned by server/discover.

type DynamoSessionStore

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

DynamoSessionStore implements SessionStore using DynamoDB via TableTheory.

func (*DynamoSessionStore) Delete

func (d *DynamoSessionStore) Delete(ctx context.Context, id string) error

Delete removes a session by ID.

func (*DynamoSessionStore) Get

func (d *DynamoSessionStore) Get(ctx context.Context, id string) (*Session, error)

Get retrieves a session by ID. Returns ErrSessionNotFound if the session does not exist.

func (*DynamoSessionStore) Put

func (d *DynamoSessionStore) Put(ctx context.Context, session *Session) error

Put stores a session. Upserts any existing session with the same ID so sliding session refreshes update the TTL instead of failing on duplicate keys.

type DynamoStreamStore

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

DynamoStreamStore implements StreamStore using DynamoDB via TableTheory.

Subscribe uses strongly consistent reads plus short polling so separate server instances can replay and continue an active stream from shared state. Replay is bounded by each event record's ExpiresAt value at runtime; DynamoDB TTL and S3 lifecycle cleanup are backstops, not access checks. The strongest DeleteSession/Append race protection is enabled when the provided TableTheory DB implements TransactWrite, which is the production TableTheory path.

func (*DynamoStreamStore) Append

func (d *DynamoStreamStore) Append(ctx context.Context, sessionID, streamID string, data json.RawMessage) (string, error)

func (*DynamoStreamStore) Close

func (d *DynamoStreamStore) Close(ctx context.Context, sessionID, streamID string) error

func (*DynamoStreamStore) Create

func (d *DynamoStreamStore) Create(ctx context.Context, sessionID string) (string, error)

func (*DynamoStreamStore) DeleteSession

func (d *DynamoStreamStore) DeleteSession(ctx context.Context, sessionID string) error

func (*DynamoStreamStore) StreamForEvent

func (d *DynamoStreamStore) StreamForEvent(ctx context.Context, sessionID, eventID string) (string, error)

func (*DynamoStreamStore) Subscribe

func (d *DynamoStreamStore) Subscribe(ctx context.Context, sessionID, streamID, afterEventID string) (<-chan StreamEvent, error)

type DynamoTaskStore

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

DynamoTaskStore implements TaskStore using DynamoDB via TableTheory.

func (*DynamoTaskStore) Cancel

func (d *DynamoTaskStore) Cancel(ctx context.Context, lookup TaskLookup) (*TaskRecord, error)

func (*DynamoTaskStore) Create

func (d *DynamoTaskStore) Create(ctx context.Context, task TaskRecord) (*TaskRecord, error)

func (*DynamoTaskStore) DeleteSession

func (d *DynamoTaskStore) DeleteSession(ctx context.Context, sessionID string) error

func (*DynamoTaskStore) Get

func (d *DynamoTaskStore) Get(ctx context.Context, lookup TaskLookup) (*TaskRecord, error)

func (*DynamoTaskStore) List

func (*DynamoTaskStore) Update

func (d *DynamoTaskStore) Update(ctx context.Context, task TaskRecord) (*TaskRecord, error)

type Icon

type Icon struct {
	Src      string   `json:"src"`
	MimeType string   `json:"mimeType,omitempty"`
	Sizes    []string `json:"sizes,omitempty"`
	Theme    string   `json:"theme,omitempty"` // "light" or "dark"
}

type InitialSessionListenerBudgetOptions

type InitialSessionListenerBudgetOptions struct {
	SafetyBuffer time.Duration
	MaxDuration  time.Duration
}

InitialSessionListenerBudgetOptions configures how the initial GET /mcp session listener is capped against the Lambda remaining-time budget.

The option is explicit opt-in and applies only when GET /mcp is used without Last-Event-ID (the keepalive listener path). Resume/replay GET requests keep their existing behavior.

Zero values use the framework defaults:

  • SafetyBuffer: 5s
  • MaxDuration: 25s

type InputRequest

type InputRequest struct {
	Method string `json:"method"`
	Params any    `json:"params,omitempty"`
}

InputRequest is a server-initiated request that a 2026-07-28 client must fulfill before retrying the original tool call.

type InputRequiredResult

type InputRequiredResult struct {
	ResultType    ResultType              `json:"resultType,omitempty"`
	InputRequests map[string]InputRequest `json:"inputRequests,omitempty"`
	RequestState  string                  `json:"requestState,omitempty"`
	Meta          map[string]any          `json:"_meta,omitempty"`
}

InputRequiredResult describes the client input needed before a request can complete. At least one of InputRequests or RequestState must be present.

type LoggingLevel

type LoggingLevel string

LoggingLevel is an MCP logging level.

const (
	LoggingLevelDebug     LoggingLevel = "debug"
	LoggingLevelInfo      LoggingLevel = "info"
	LoggingLevelNotice    LoggingLevel = "notice"
	LoggingLevelWarning   LoggingLevel = "warning"
	LoggingLevelError     LoggingLevel = "error"
	LoggingLevelCritical  LoggingLevel = "critical"
	LoggingLevelAlert     LoggingLevel = "alert"
	LoggingLevelEmergency LoggingLevel = "emergency"
)

type LoggingLevelHook

type LoggingLevelHook func(ctx context.Context, req LoggingLevelRequest) error

LoggingLevelHook handles a logging/setLevel request.

type LoggingLevelRequest

type LoggingLevelRequest struct {
	SessionID string       `json:"sessionId"`
	Level     LoggingLevel `json:"level"`
}

LoggingLevelRequest identifies a logging/setLevel request for a session.

type MemorySessionStore

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

MemorySessionStore is an in-memory SessionStore for testing and local development.

func NewMemorySessionStore

func NewMemorySessionStore(opts ...MemorySessionStoreOption) *MemorySessionStore

NewMemorySessionStore creates an in-memory session store.

func (*MemorySessionStore) Delete

func (m *MemorySessionStore) Delete(_ context.Context, id string) error

Delete removes a session by ID. It is a no-op if the session does not exist.

func (*MemorySessionStore) Get

Get retrieves a session by ID. It returns ErrSessionNotFound if the session does not exist or has expired.

func (*MemorySessionStore) Put

func (m *MemorySessionStore) Put(_ context.Context, session *Session) error

Put stores a session. It overwrites any existing session with the same ID.

type MemorySessionStoreOption

type MemorySessionStoreOption func(*MemorySessionStore)

MemorySessionStoreOption configures a MemorySessionStore.

func WithClock

WithClock sets the clock used for TTL expiration checks.

type MemoryStreamStore

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

MemoryStreamStore is an in-memory StreamStore for testing and local development.

It assigns monotonically increasing numeric event IDs per session (as strings).

func NewMemoryStreamStore

func NewMemoryStreamStore(opts ...MemoryStreamStoreOption) *MemoryStreamStore

func (*MemoryStreamStore) Append

func (m *MemoryStreamStore) Append(_ context.Context, sessionID, streamID string, data json.RawMessage) (string, error)

func (*MemoryStreamStore) Close

func (m *MemoryStreamStore) Close(_ context.Context, sessionID, streamID string) error

func (*MemoryStreamStore) Create

func (m *MemoryStreamStore) Create(_ context.Context, sessionID string) (string, error)

func (*MemoryStreamStore) DeleteSession

func (m *MemoryStreamStore) DeleteSession(_ context.Context, sessionID string) error

func (*MemoryStreamStore) StreamForEvent

func (m *MemoryStreamStore) StreamForEvent(_ context.Context, sessionID, eventID string) (string, error)

func (*MemoryStreamStore) Subscribe

func (m *MemoryStreamStore) Subscribe(ctx context.Context, sessionID, streamID, afterEventID string) (<-chan StreamEvent, error)

type MemoryStreamStoreOption

type MemoryStreamStoreOption func(*MemoryStreamStore)

type MemoryTaskStore

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

MemoryTaskStore is an in-memory TaskStore for testing and local development.

func NewMemoryTaskStore

func NewMemoryTaskStore() *MemoryTaskStore

NewMemoryTaskStore creates an empty in-memory task store.

func (*MemoryTaskStore) Cancel

func (m *MemoryTaskStore) Cancel(_ context.Context, lookup TaskLookup) (*TaskRecord, error)

func (*MemoryTaskStore) Create

func (m *MemoryTaskStore) Create(_ context.Context, task TaskRecord) (*TaskRecord, error)

func (*MemoryTaskStore) DeleteSession

func (m *MemoryTaskStore) DeleteSession(_ context.Context, sessionID string) error

func (*MemoryTaskStore) Get

func (m *MemoryTaskStore) Get(_ context.Context, lookup TaskLookup) (*TaskRecord, error)

func (*MemoryTaskStore) List

func (*MemoryTaskStore) Update

func (m *MemoryTaskStore) Update(_ context.Context, task TaskRecord) (*TaskRecord, error)

type OriginValidator

type OriginValidator func(origin string) bool

OriginValidator validates an HTTP Origin header value.

If a request includes an Origin header and the validator returns false, the server should reject the request (fail closed).

func AllowOrigins

func AllowOrigins(origins ...string) OriginValidator

type PromptArgument

type PromptArgument struct {
	Name        string `json:"name"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	Required    bool   `json:"required,omitempty"`
}

PromptArgument defines an argument a prompt can accept.

type PromptDef

type PromptDef struct {
	Name        string           `json:"name"`
	Title       string           `json:"title,omitempty"`
	Description string           `json:"description,omitempty"`
	Arguments   []PromptArgument `json:"arguments,omitempty"`
}

PromptDef defines an MCP prompt's metadata.

type PromptHandler

type PromptHandler func(ctx context.Context, args json.RawMessage) (*PromptResult, error)

PromptHandler renders a prompt given optional arguments.

type PromptMessage

type PromptMessage struct {
	Role    string       `json:"role"`
	Content ContentBlock `json:"content"`
}

PromptMessage is a single message returned from prompts/get.

type PromptRegistry

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

PromptRegistry manages registered MCP prompts.

func NewPromptRegistry

func NewPromptRegistry() *PromptRegistry

NewPromptRegistry creates an empty prompt registry.

func (*PromptRegistry) Get

func (r *PromptRegistry) Get(ctx context.Context, name string, args json.RawMessage) (*PromptResult, error)

Get resolves a prompt by name and renders it.

func (*PromptRegistry) Len

func (r *PromptRegistry) Len() int

Len returns the number of registered prompts.

func (*PromptRegistry) List

func (r *PromptRegistry) List() []PromptDef

List returns all registered prompt definitions in registration order.

func (*PromptRegistry) RegisterPrompt

func (r *PromptRegistry) RegisterPrompt(def PromptDef, handler PromptHandler) error

RegisterPrompt registers a prompt by name.

type PromptResult

type PromptResult struct {
	Description string          `json:"description,omitempty"`
	Messages    []PromptMessage `json:"messages"`
}

PromptResult is the result payload returned from prompts/get.

type ProtocolShape

type ProtocolShape string

ProtocolShape identifies the transport shape selected for one MCP request.

const (
	// ProtocolShape20251125 is the session-ful MCP 2025-11-25 transport shape.
	ProtocolShape20251125 ProtocolShape = protocolVersion
	// ProtocolShape20260728 is the stateless MCP 2026-07-28 transport shape.
	ProtocolShape20260728 ProtocolShape = ProtocolVersion20260728
	// ProtocolShapeUnknown means neither supported request shape was identified.
	ProtocolShapeUnknown ProtocolShape = "unknown"
)

func DetectProtocolVersion

func DetectProtocolVersion(headers map[string][]string, requestBody []byte) ProtocolShape

DetectProtocolVersion identifies the MCP transport shape for one request.

MCP-Protocol-Version takes precedence when present. Otherwise the detector reads io.modelcontextprotocol/protocolVersion from params._meta. Malformed requests and unrecognized versions return ProtocolShapeUnknown.

func DetectProtocolVersionForMessage

func DetectProtocolVersionForMessage(headers map[string][]string, message any) ProtocolShape

DetectProtocolVersionForMessage identifies the MCP transport shape for one already-parsed JSON-RPC message.

MCP-Protocol-Version takes precedence when present. Otherwise the detector reads io.modelcontextprotocol/protocolVersion from params._meta. Values that cannot be represented as a JSON object return ProtocolShapeUnknown.

type RPCError

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data,omitempty"`
}

RPCError is a JSON-RPC 2.0 error object.

type RelatedTaskMetadata

type RelatedTaskMetadata struct {
	TaskID string `json:"taskId"`
}

RelatedTaskMetadata is the MCP _meta entry that associates messages with a task.

type Request

type Request struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      any             `json:"id,omitempty"`
	Method  string          `json:"method"`
	Params  json.RawMessage `json:"params,omitempty"`
}

Request is a JSON-RPC 2.0 request message.

func ParseBatchRequest

func ParseBatchRequest(data []byte) ([]*Request, error)

ParseBatchRequest parses a JSON-RPC batch request (array of requests) from raw bytes. If the input is a single object (not an array), it returns a slice containing that single parsed request.

func ParseRequest

func ParseRequest(data []byte) (*Request, error)

ParseRequest parses a single JSON-RPC 2.0 request from raw bytes. It validates the required fields: jsonrpc must be "2.0" and method must be non-empty.

This function accepts both JSON-RPC requests and notifications: - Requests include an "id" field. - Notifications omit the "id" field.

If an "id" field is present, it MUST NOT be null.

type ResourceContent

type ResourceContent struct {
	URI      string `json:"uri"`
	MimeType string `json:"mimeType,omitempty"`
	Text     string `json:"text,omitempty"`
	Blob     string `json:"blob,omitempty"`
}

ResourceContent is a single content item returned from resources/read.

Exactly one of Text or Blob should be set. Blob is expected to be a base64-encoded payload (client-decoded).

type ResourceDef

type ResourceDef struct {
	URI         string `json:"uri"`
	Name        string `json:"name"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	MimeType    string `json:"mimeType,omitempty"`
	Size        int64  `json:"size,omitempty"`
}

ResourceDef defines an MCP resource's metadata.

type ResourceHandler

type ResourceHandler func(ctx context.Context) ([]ResourceContent, error)

ResourceHandler resolves and returns the content for a resource.

type ResourceRegistry

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

ResourceRegistry manages registered MCP resources.

func NewResourceRegistry

func NewResourceRegistry() *ResourceRegistry

NewResourceRegistry creates an empty resource registry.

func (*ResourceRegistry) Len

func (r *ResourceRegistry) Len() int

Len returns the number of registered resources.

func (*ResourceRegistry) List

func (r *ResourceRegistry) List() []ResourceDef

List returns all registered resource definitions in registration order.

func (*ResourceRegistry) ListTemplates

func (r *ResourceRegistry) ListTemplates() []ResourceTemplateDef

ListTemplates returns all registered resource template definitions in registration order.

func (*ResourceRegistry) Read

Read resolves a resource by URI and returns its content.

func (*ResourceRegistry) RegisterResource

func (r *ResourceRegistry) RegisterResource(def ResourceDef, handler ResourceHandler) error

RegisterResource registers a resource by URI.

func (*ResourceRegistry) RegisterResourceTemplate

func (r *ResourceRegistry) RegisterResourceTemplate(def ResourceTemplateDef) error

RegisterResourceTemplate registers a parameterized resource template.

type ResourceSubscription

type ResourceSubscription struct {
	SessionID string `json:"sessionId"`
	URI       string `json:"uri"`
}

ResourceSubscription identifies a resource subscription request for a session.

type ResourceSubscriptionHook

type ResourceSubscriptionHook func(ctx context.Context, sub ResourceSubscription) error

ResourceSubscriptionHook handles a resources/subscribe or resources/unsubscribe request.

type ResourceTemplateDef

type ResourceTemplateDef struct {
	URITemplate string `json:"uriTemplate"`
	Name        string `json:"name"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	MimeType    string `json:"mimeType,omitempty"`
}

ResourceTemplateDef defines an MCP resource template's metadata.

type Response

type Response struct {
	JSONRPC string    `json:"jsonrpc"`
	ID      any       `json:"id"`
	Result  any       `json:"result,omitempty"`
	Error   *RPCError `json:"error,omitempty"`
}

Response is a JSON-RPC 2.0 response message.

func NewErrorResponse

func NewErrorResponse(id any, code int, message string) *Response

NewErrorResponse creates a JSON-RPC error response with the given request ID and error details.

func NewResultResponse

func NewResultResponse(id any, result any) *Response

NewResultResponse creates a JSON-RPC success response with the given request ID and result value.

func ParseResponse

func ParseResponse(data []byte) (*Response, error)

ParseResponse parses a single JSON-RPC 2.0 response from raw bytes.

It validates: - jsonrpc must be "2.0" - id must be present (it may be null for certain error cases) - exactly one of result or error is present

type ResultType

type ResultType string

ResultType identifies whether a 2026-07-28 result is final or requires another client-input round trip.

const (
	ResultTypeComplete      ResultType = "complete"
	ResultTypeInputRequired ResultType = "input_required"
)

type SSEEvent

type SSEEvent struct {
	Data any
}

SSEEvent is a progress event emitted by a streaming tool handler.

type Server

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

Server is the MCP protocol handler. It dispatches JSON-RPC 2.0 messages to the appropriate MCP method handlers (initialize, tools/list, tools/call).

func NewServer

func NewServer(name, version string, opts ...ServerOption) *Server

NewServer creates an MCP server with the given name, version, and options.

func (*Server) Handler

func (s *Server) Handler() apptheory.Handler

Handler returns an apptheory.Handler that processes MCP JSON-RPC requests.

Streamable HTTP semantics:

  • POST /mcp accepts JSON-RPC requests, notifications, and responses.
  • MCP 2025-11-25 uses the session-ful GET and DELETE transport lifecycle.
  • MCP 2026-07-28 POST requests are stateless and never mint or require a Mcp-Session-Id.

Notes:

  • MCP 2025-11-25 clients must initialize first; the server issues Mcp-Session-Id on the initialize response and requires it thereafter.
  • Disconnects are not treated as cancellation. Streaming tool execution is decoupled from the connection and can be resumed with GET.

func (*Server) Prompts

func (s *Server) Prompts() *PromptRegistry

Prompts returns the server's prompt registry for registering prompts.

func (*Server) Registry

func (s *Server) Registry() *ToolRegistry

Registry returns the server's tool registry for registering tools.

func (*Server) Resources

func (s *Server) Resources() *ResourceRegistry

Resources returns the server's resource registry for registering resources.

type ServerIdentity

type ServerIdentity struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

ServerIdentity identifies the MCP server implementation.

type ServerOption

type ServerOption func(*Server)

ServerOption configures a Server.

func WithCapabilityConfig

func WithCapabilityConfig(config CapabilityConfig) ServerOption

WithCapabilityConfig sets the server capability policy used for initialize responses.

func WithCompletionHooks

func WithCompletionHooks(promptHook, resourceHook CompletionHook) ServerOption

WithCompletionHooks enables completion/complete support through explicit prompt and resource hooks. At least one hook must be non-nil before the completions capability is advertised.

func WithInitialSessionListenerBudget

func WithInitialSessionListenerBudget(opts InitialSessionListenerBudgetOptions) ServerOption

WithInitialSessionListenerBudget caps the initial GET /mcp keepalive listener against the Lambda remaining-time budget when RemainingMS is available.

This option is explicit opt-in and applies only to GET /mcp requests without Last-Event-ID. Resume/replay requests continue to use the existing stream replay path unchanged.

func WithLogger

func WithLogger(logger *slog.Logger) ServerOption

WithLogger sets the structured logger for the server.

func WithLoggingLevelHook

func WithLoggingLevelHook(hook LoggingLevelHook) ServerOption

WithLoggingLevelHook enables logging/setLevel support through an explicit hook.

func WithOriginValidator

func WithOriginValidator(v OriginValidator) ServerOption

WithOriginValidator sets the Origin validator for browser-based callers.

If an Origin header is present, the request is rejected unless it passes validation (fail closed).

func WithResourceSubscriptionHooks

func WithResourceSubscriptionHooks(subscribe, unsubscribe ResourceSubscriptionHook) ServerOption

WithResourceSubscriptionHooks enables resources/subscribe and resources/unsubscribe support through explicit hooks.

The methods fail closed if either hook is absent. The resource subscribe sub-capability remains omitted until AppTheory has an outbound resource update notification contract.

func WithServerIDGenerator

func WithServerIDGenerator(gen apptheory.IDGenerator) ServerOption

WithIDGenerator sets the ID generator for session IDs.

func WithSessionStore

func WithSessionStore(store SessionStore) ServerOption

WithSessionStore sets the session store for the server.

func WithStreamStore

func WithStreamStore(store StreamStore) ServerOption

WithStreamStore sets the stream store for the server.

func WithTaskRuntime

func WithTaskRuntime(opts TaskRuntimeOptions) ServerOption

WithTaskRuntime enables MCP task operations through an explicit TaskStore.

Tasks are experimental in MCP 2025-11-25 and remain opt-in. AppTheory only advertises task capabilities when this option supplies a store and at least one registered tool declares task support.

type Session

type Session struct {
	ID        string            `json:"id"`
	CreatedAt time.Time         `json:"createdAt"`
	ExpiresAt time.Time         `json:"expiresAt"`
	Data      map[string]string `json:"data,omitempty"`
}

Session holds per-session state for an MCP connection.

type SessionStore

type SessionStore interface {
	Get(ctx context.Context, id string) (*Session, error)
	Put(ctx context.Context, session *Session) error
	Delete(ctx context.Context, id string) error
}

SessionStore is the interface for session persistence backends.

func NewDynamoSessionStore

func NewDynamoSessionStore(db tablecore.DB) SessionStore

NewDynamoSessionStore creates a DynamoDB-backed session store.

type StreamEvent

type StreamEvent struct {
	ID   string
	Data json.RawMessage
}

StreamEvent is a single server->client JSON-RPC message framed as an SSE event.

ID is the SSE event id (used for resumability via Last-Event-ID). Data is the raw JSON payload (a single JSON-RPC message).

type StreamStore

type StreamStore interface {
	Create(ctx context.Context, sessionID string) (streamID string, err error)
	Append(ctx context.Context, sessionID, streamID string, data json.RawMessage) (eventID string, err error)
	Close(ctx context.Context, sessionID, streamID string) error

	// Subscribe streams events after afterEventID. If afterEventID is empty,
	// it streams from the beginning. If afterEventID is present, it must belong
	// to the requested stream.
	Subscribe(ctx context.Context, sessionID, streamID, afterEventID string) (<-chan StreamEvent, error)

	// StreamForEvent returns the stream id that the given event id belongs to.
	StreamForEvent(ctx context.Context, sessionID, eventID string) (streamID string, err error)

	// DeleteSession removes all stream state for a session.
	DeleteSession(ctx context.Context, sessionID string) error
}

StreamStore persists stream events so a disconnected client can replay them via GET + Last-Event-ID.

func NewDynamoStreamStore

func NewDynamoStreamStore(db tablecore.DB) StreamStore

NewDynamoStreamStore creates a DynamoDB-backed StreamStore.

type StreamingToolHandler

type StreamingToolHandler func(ctx context.Context, args json.RawMessage, emit func(SSEEvent)) (*ToolResult, error)

StreamingToolHandler is a tool handler that can emit progress events via SSE.

func WrapStreamingTool

func WrapStreamingTool[Args any](
	options ToolLifecycleOptions[Args],
	handler func(context.Context, Args, func(SSEEvent)) (*ToolResult, error),
) StreamingToolHandler

WrapStreamingTool adapts a typed MCP streaming tool handler to the raw StreamingToolHandler contract while applying the same lifecycle policy as WrapTool. It remains a registration-time adapter; streaming dispatch still goes through ToolRegistry.CallStreaming.

type Task

type Task struct {
	TaskID        string     `json:"taskId"`
	Status        TaskStatus `json:"status"`
	StatusMessage string     `json:"statusMessage,omitempty"`
	CreatedAt     time.Time  `json:"createdAt"`
	LastUpdatedAt time.Time  `json:"lastUpdatedAt"`
	TTL           *int64     `json:"ttl"`
	PollInterval  *int64     `json:"pollInterval,omitempty"`
}

Task is the MCP task state returned by task operations.

type TaskListRequest

type TaskListRequest struct {
	SessionID string `json:"sessionId"`
	Cursor    string `json:"cursor,omitempty"`
	Limit     int    `json:"limit,omitempty"`
}

TaskListRequest scopes a task listing to the active MCP session.

type TaskListResult

type TaskListResult struct {
	Tasks      []Task `json:"tasks"`
	NextCursor string `json:"nextCursor,omitempty"`
}

TaskListResult is the MCP tasks/list result.

type TaskLookup

type TaskLookup struct {
	SessionID string `json:"sessionId"`
	TaskID    string `json:"taskId"`
}

TaskLookup scopes a task lookup to the active MCP session.

type TaskMetadata

type TaskMetadata struct {
	TTL *int64 `json:"ttl,omitempty"`
}

TaskMetadata is the MCP request parameter used to request task-augmented execution.

type TaskRecord

type TaskRecord struct {
	SessionID string          `json:"sessionId"`
	Method    string          `json:"method"`
	ToolName  string          `json:"toolName,omitempty"`
	Task      Task            `json:"task"`
	Result    json.RawMessage `json:"result,omitempty"`
	Error     *RPCError       `json:"error,omitempty"`
}

TaskRecord is the durable representation stored by TaskStore implementations.

type TaskRuntimeOptions

type TaskRuntimeOptions struct {
	Store                  TaskStore
	DefaultTTL             time.Duration
	MaxTTL                 time.Duration
	PollInterval           time.Duration
	ListLimit              int
	ModelImmediateResponse string
}

TaskRuntimeOptions configures task-augmented MCP execution.

type TaskStatus

type TaskStatus string

TaskStatus is an MCP task lifecycle state.

const (
	TaskStatusWorking       TaskStatus = "working"
	TaskStatusInputRequired TaskStatus = "input_required"
	TaskStatusCompleted     TaskStatus = "completed"
	TaskStatusFailed        TaskStatus = "failed"
	TaskStatusCanceled      TaskStatus = "cancel" + "led"
)

type TaskStore

type TaskStore interface {
	Create(ctx context.Context, task TaskRecord) (*TaskRecord, error)
	Get(ctx context.Context, lookup TaskLookup) (*TaskRecord, error)
	Update(ctx context.Context, task TaskRecord) (*TaskRecord, error)
	List(ctx context.Context, req TaskListRequest) (*TaskListResult, error)
	Cancel(ctx context.Context, lookup TaskLookup) (*TaskRecord, error)
	DeleteSession(ctx context.Context, sessionID string) error
}

TaskStore persists MCP task state. Implementations must bind every operation to the supplied SessionID and fail closed if a task belongs to a different authorization context.

func NewDynamoTaskStore

func NewDynamoTaskStore(db tablecore.DB) TaskStore

NewDynamoTaskStore creates a DynamoDB-backed task store.

type TaskSupport

type TaskSupport string

TaskSupport declares whether a tool can be invoked through MCP task augmentation.

const (
	TaskSupportForbidden TaskSupport = "forbidden"
	TaskSupportOptional  TaskSupport = "optional"
	TaskSupportRequired  TaskSupport = "required"
)

type ToolAnnotations

type ToolAnnotations struct {
	Title           string `json:"title,omitempty"`
	ReadOnlyHint    *bool  `json:"readOnlyHint,omitempty"`
	DestructiveHint *bool  `json:"destructiveHint,omitempty"`
	IdempotentHint  *bool  `json:"idempotentHint,omitempty"`
	OpenWorldHint   *bool  `json:"openWorldHint,omitempty"`
}

type ToolDef

type ToolDef struct {
	Name        string           `json:"name"`
	Title       string           `json:"title,omitempty"`
	Description string           `json:"description,omitempty"`
	Annotations *ToolAnnotations `json:"annotations,omitempty"`

	Icons        []Icon          `json:"icons,omitempty"`
	Execution    *ToolExecution  `json:"execution,omitempty"`
	InputSchema  json.RawMessage `json:"inputSchema"`
	OutputSchema json.RawMessage `json:"outputSchema,omitempty"`
}

ToolDef defines an MCP tool's metadata and input schema.

type ToolExecution

type ToolExecution struct {
	// TaskSupport indicates if the tool supports task-augmented execution.
	// Values: "forbidden", "optional", "required".
	TaskSupport TaskSupport `json:"taskSupport,omitempty"`
}

type ToolHandler

type ToolHandler func(ctx context.Context, args json.RawMessage) (*ToolResult, error)

ToolHandler is the function signature for tool implementations.

func WrapTool

func WrapTool[Args any](options ToolLifecycleOptions[Args], handler func(context.Context, Args) (*ToolResult, error)) ToolHandler

WrapTool adapts a typed MCP tool handler to the raw ToolHandler contract while applying one lifecycle policy for argument binding, validation, timeout, handled product failures, sanitized unhandled failures, panic recovery, and telemetry.

type ToolInput

type ToolInput struct {
	InputResponses map[string]any
	RequestState   string
}

ToolInput contains client responses supplied when retrying a 2026-07-28 multi-round tool call.

func ToolInputFromContext

func ToolInputFromContext(ctx context.Context) ToolInput

ToolInputFromContext returns the multi-round client input associated with a tool invocation. It returns the zero value for ordinary calls.

type ToolLifecycleFinish

type ToolLifecycleFinish struct {
	Name              string               `json:"name"`
	StartedAt         time.Time            `json:"startedAt"`
	FinishedAt        time.Time            `json:"finishedAt"`
	Duration          time.Duration        `json:"duration"`
	Outcome           ToolLifecycleOutcome `json:"outcome"`
	JSONRPCErrorCode  int                  `json:"jsonrpcErrorCode,omitempty"`
	ResultMarkedError bool                 `json:"resultMarkedError,omitempty"`
}

ToolLifecycleFinish is emitted after a wrapped MCP tool handler finishes. It is a sanitized telemetry payload and intentionally excludes raw arguments, bearer tokens, panic values, and unhandled error text.

type ToolLifecycleOptions

type ToolLifecycleOptions[Args any] struct {
	Name        string
	Timeout     time.Duration
	NoArgs      bool
	StrictJSON  bool
	Validate    func(context.Context, Args) error
	HandleError func(context.Context, error) (*ToolResult, bool)
	Telemetry   ToolLifecycleTelemetry
	Clock       apptheory.Clock
}

ToolLifecycleOptions configures WrapTool and WrapStreamingTool. The wrapper is a handler adapter only: callers still register the returned handler through RegisterTool or RegisterStreamingTool, so all buffered, streaming, and task execution stays on the single registry dispatch path.

type ToolLifecycleOutcome

type ToolLifecycleOutcome string

ToolLifecycleOutcome describes the sanitized result class for a wrapped MCP tool invocation. Outcomes intentionally carry no raw tool arguments, bearer tokens, panic values, or unhandled error text.

const (
	ToolLifecycleOutcomeSuccess         ToolLifecycleOutcome = "success"
	ToolLifecycleOutcomeInvalidParams   ToolLifecycleOutcome = "invalid_params"
	ToolLifecycleOutcomeHandledError    ToolLifecycleOutcome = "handled_error"
	ToolLifecycleOutcomeTimeout         ToolLifecycleOutcome = "timeout"
	ToolLifecycleOutcomePanic           ToolLifecycleOutcome = "panic"
	ToolLifecycleOutcomeUnhandledError  ToolLifecycleOutcome = "unhandled_error"
	ToolLifecycleOutcomeContextCanceled ToolLifecycleOutcome = "context_canceled"
)

type ToolLifecycleStart

type ToolLifecycleStart struct {
	Name      string    `json:"name"`
	StartedAt time.Time `json:"startedAt"`
}

ToolLifecycleStart is emitted before a wrapped MCP tool handler runs. It is a sanitized telemetry payload and intentionally excludes raw arguments.

type ToolLifecycleTelemetry

type ToolLifecycleTelemetry struct {
	Start  func(context.Context, ToolLifecycleStart)
	Finish func(context.Context, ToolLifecycleFinish)
}

ToolLifecycleTelemetry configures sanitized lifecycle hooks for wrapped MCP tool handlers. Hook payloads are deliberately small and safe for logs or metrics; raw request arguments and raw error values are never supplied.

type ToolRegistry

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

ToolRegistry manages registered MCP tools.

func NewToolRegistry

func NewToolRegistry() *ToolRegistry

NewToolRegistry creates an empty tool registry.

func (*ToolRegistry) Call

func (r *ToolRegistry) Call(ctx context.Context, name string, args json.RawMessage) (*ToolResult, error)

Call looks up a tool by name and invokes its handler with the given arguments. It returns an error if the tool is not found.

func (*ToolRegistry) CallStreaming

func (r *ToolRegistry) CallStreaming(ctx context.Context, name string, args json.RawMessage, emit func(SSEEvent)) (*ToolResult, error)

CallStreaming looks up a tool by name and invokes its streaming handler if available, otherwise falls back to the regular handler (discarding emit).

func (*ToolRegistry) Len

func (r *ToolRegistry) Len() int

Len returns the number of registered tools.

func (*ToolRegistry) List

func (r *ToolRegistry) List() []ToolDef

List returns all registered tool definitions in registration order.

func (*ToolRegistry) RegisterStreamingTool

func (r *ToolRegistry) RegisterStreamingTool(def ToolDef, handler StreamingToolHandler) error

RegisterStreamingTool registers a tool that supports SSE streaming. When invoked by a strict Streamable HTTP POST with an Accept header that supports both application/json and text/event-stream, progress events are streamed. Buffered calls to the same tool still run to completion and return a JSON response when the server does not select the SSE path.

func (*ToolRegistry) RegisterTool

func (r *ToolRegistry) RegisterTool(def ToolDef, handler ToolHandler) error

RegisterTool adds a tool to the registry. It returns an error if a tool with the same name is already registered.

type ToolResult

type ToolResult struct {
	Content           []ContentBlock          `json:"content"`
	IsError           bool                    `json:"isError,omitempty"`
	StructuredContent map[string]any          `json:"structuredContent,omitempty"`
	ResultType        ResultType              `json:"resultType,omitempty"`
	InputRequests     map[string]InputRequest `json:"inputRequests,omitempty"`
	RequestState      string                  `json:"requestState,omitempty"`
}

ToolResult is the result of a tool invocation.

Jump to

Keyboard shortcuts

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