mcp

package
v0.0.0-...-5c6d8ba Latest Latest
Warning

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

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

Documentation

Overview

Package mcp implements a stateless, streamable-HTTP Model Context Protocol server and upstream client. It is transport- and storage-agnostic: the gateway adapts its auth/store/registry into the ToolSource interface and drives the Server, so this package stays below the gateway layer. All protocol constants live in this file so reconciling a future spec revision is a one-file change.

Index

Constants

View Source
const (
	ProtocolVersionLatest = "2025-06-18"
	ProtocolVersionLegacy = "2025-03-26"
)

Protocol revisions Polaris speaks. Latest is preferred on negotiation; Legacy is accepted from older clients and used as the upstream-client fallback.

View Source
const (
	MethodInitialize  = "initialize"
	MethodPing        = "ping"
	MethodToolsList   = "tools/list"
	MethodToolsCall   = "tools/call"
	MethodInitialized = "notifications/initialized"
	MethodCancelled   = "notifications/cancelled"
)

JSON-RPC method names (v1 surface: tools only).

View Source
const (
	ErrCodeParse          = -32700
	ErrCodeInvalidRequest = -32600
	ErrCodeMethodNotFound = -32601
	ErrCodeInvalidParams  = -32602
	ErrCodeInternal       = -32603
)

JSON-RPC 2.0 reserved error codes.

View Source
const ProtocolVersionHeader = "MCP-Protocol-Version"

ProtocolVersionHeader carries the negotiated version on every post-initialize request in streamable HTTP.

View Source
const ServerName = "polaris"

ServerName is the MCP serverInfo.name Polaris advertises.

Variables

View Source
var SupportedProtocolVersions = []string{ProtocolVersionLatest, ProtocolVersionLegacy}

SupportedProtocolVersions is the negotiation set, most-preferred first.

Functions

func ProtocolVersionSupported

func ProtocolVersionSupported(v string) bool

ProtocolVersionSupported reports whether v is a version Polaris speaks.

Types

type Aggregate

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

Aggregate merges several ToolSources into one. Upstream tools are namespaced `{prefix}:{tool}`; the local source (prefix "") stays bare. tools/list results are cached per source with a TTL and refreshed lazily; a failing upstream is skipped, never sinking the whole aggregate.

func NewAggregate

func NewAggregate(ttl time.Duration) *Aggregate

NewAggregate builds an aggregate with a per-source tools/list cache TTL (0 = no caching).

func (*Aggregate) Add

func (a *Aggregate) Add(prefix string, source ToolSource)

Add registers a source under a namespace prefix ("" for the local source).

func (*Aggregate) CallTool

func (a *Aggregate) CallTool(ctx context.Context, name string, arguments json.RawMessage) (ToolResult, error)

CallTool routes by the namespace prefix; a bare name goes to the local source.

func (*Aggregate) ListTools

func (a *Aggregate) ListTools(ctx context.Context, _ string) ([]Tool, string, error)

ListTools merges every source's tools, namespacing prefixed sources.

type Claims

type Claims struct {
	Subject string
	Issuer  string
	Scopes  []string
}

Claims are the validated token claims relevant to MCP authorization.

func (Claims) HasScope

func (c Claims) HasScope(scope string) bool

HasScope reports whether the token carries scope.

type Client

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

Client is an upstream MCP client speaking streamable HTTP. It implements ToolSource by calling a remote server's tools/list and tools/call. On a version-mismatch (4xx) it retries once pinned to the legacy protocol version, so older upstream servers keep working. Bearer tokens from downstream callers are never forwarded here — only the binding's configured headers are sent.

func NewClient

func NewClient(url string, headers map[string]string, httpClient *http.Client) *Client

NewClient builds an upstream client for url with static headers.

func (*Client) CallTool

func (c *Client) CallTool(ctx context.Context, name string, arguments json.RawMessage) (ToolResult, error)

CallTool invokes an upstream tool.

func (*Client) ListTools

func (c *Client) ListTools(ctx context.Context, cursor string) ([]Tool, string, error)

ListTools fetches the upstream tool catalog (one page).

type ContentBlock

type ContentBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

ContentBlock is one element of a tool result's content array.

func TextContent

func TextContent(text string) []ContentBlock

TextContent builds a single text content block.

type Error

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

Error is a JSON-RPC 2.0 error object.

func NewError

func NewError(code int, message string, data any) *Error

NewError builds a JSON-RPC error object.

func (*Error) Error

func (e *Error) Error() string

type OAuthConfig

type OAuthConfig struct {
	ResourceURI          string
	AuthorizationServers []string
	JWKSCacheTTL         time.Duration
}

OAuthConfig configures the MCP OAuth 2.1 resource server (RFC 9728).

type Request

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

Request is a JSON-RPC 2.0 request or notification. A notification omits id.

func DecodeRequests

func DecodeRequests(data []byte) ([]Request, bool, error)

DecodeRequests parses a single request or a batch array. The bool reports whether the payload was a batch (so the response is encoded as an array).

func (Request) IsNotification

func (r Request) IsNotification() bool

IsNotification reports whether the request carries no id (fire-and-forget).

type ResourceServer

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

ResourceServer validates bearer JWTs against the configured authorization servers' JWKS (fetched, cached, and rotated with a stale-grace fallback) and serves RFC 9728 protected-resource metadata. Downstream tokens are never forwarded upstream.

func NewResourceServer

func NewResourceServer(cfg OAuthConfig, httpClient *http.Client) *ResourceServer

NewResourceServer builds a resource server. A nil client uses a 10s default.

func (*ResourceServer) Challenge

func (rs *ResourceServer) Challenge(metadataURL string) string

Challenge is the WWW-Authenticate value for a 401 pointing at the metadata.

func (*ResourceServer) ProtectedResourceMetadata

func (rs *ResourceServer) ProtectedResourceMetadata() map[string]any

ProtectedResourceMetadata is the RFC 9728 document served at /.well-known/oauth-protected-resource.

func (*ResourceServer) ValidateToken

func (rs *ResourceServer) ValidateToken(ctx context.Context, tokenString string) (Claims, error)

ValidateToken parses and verifies a bearer JWT and returns its claims. It enforces the signing algorithm allow-list, an allowed issuer, aud == resource URI, and a required expiry.

type Response

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

Response is a JSON-RPC 2.0 response. Exactly one of Result/Error is set.

type Server

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

Server dispatches MCP JSON-RPC over streamable HTTP against a ToolSource. It is stateless: no session id, no initialize handshake requirement. A POST is answered as a single JSON body, or — when the client sends `Accept: text/event-stream` — as SSE frames on the POST response.

func NewServer

func NewServer(serverVersion string) *Server

NewServer builds a Server advertising serverVersion in serverInfo.

func (*Server) Handle

func (s *Server) Handle(w http.ResponseWriter, r *http.Request, source ToolSource)

Handle processes a POST JSON-RPC request (single or batch) against source. GET and other verbs return 405 — the gateway handler owns any GET metadata path.

type Tool

type Tool struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	InputSchema json.RawMessage `json:"inputSchema,omitempty"`
}

Tool is one callable tool in a tools/list result.

type ToolResult

type ToolResult struct {
	Content           []ContentBlock `json:"content"`
	StructuredContent any            `json:"structuredContent,omitempty"`
	IsError           bool           `json:"isError"`
}

ToolResult is the result of a tools/call.

type ToolSource

type ToolSource interface {
	ListTools(ctx context.Context, cursor string) (tools []Tool, nextCursor string, err error)
	CallTool(ctx context.Context, name string, arguments json.RawMessage) (ToolResult, error)
}

ToolSource is what the Server dispatches against: a set of listable, callable tools. Local toolsets, upstream MCP servers, and aggregates all implement it.

Jump to

Keyboard shortcuts

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