mcp

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package mcp implements the Model Context Protocol server for bc workspaces. It exposes workspace state as MCP resources and provides tools for controlling agents.

Supports two transports:

  • stdio: newline-delimited JSON-RPC on stdin/stdout (for direct Claude Code integration)
  • SSE: HTTP server with /sse for server→client events, /message for client→server

Index

Constants

View Source
const (
	ErrParse          = -32700
	ErrInvalidRequest = -32600
	ErrMethodNotFound = -32601
	ErrInvalidParams  = -32602
	ErrInternal       = -32603
)

JSON-RPC 2.0 error codes.

View Source
const ProtocolVersion = "2024-11-05"

Protocol version this server speaks.

Variables

This section is empty.

Functions

func AgentFromContext

func AgentFromContext(ctx context.Context) string

AgentFromContext returns the agent ID from the context, if set.

func LocalhostAddr

func LocalhostAddr(addr string) string

LocalhostAddr rewrites a bare ":port" address to "127.0.0.1:port". Explicit host addresses (e.g. "0.0.0.0:8811") are returned unchanged so callers that deliberately want to bind all interfaces can still do so.

Types

type ChannelMessagePayload

type ChannelMessagePayload struct {
	Time    time.Time `json:"time"`
	Channel string    `json:"channel"`
	Sender  string    `json:"sender"`
	Message string    `json:"message"`
}

ChannelMessagePayload is the notification payload for new channel messages.

type Config

type Config struct {
	Workspace *workspace.Workspace
	Agents    *agent.Manager   // optional: pre-built agent manager
	Costs     *cost.Store      // optional: pre-built cost store
	Gateway   *gateway.Manager // optional: gateway manager for file uploads
	Notify    *notify.Service  // optional: notify service for messaging
	Version   string           // bc binary version, e.g. "1.2.3"
}

Config holds the dependencies needed to build a Server. When Channels or Costs are provided, the server reuses them (e.g. from bcd) instead of opening its own connections.

type Notification

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

Notification is an outgoing JSON-RPC 2.0 notification (no ID).

func NewChannelNotification

func NewChannelNotification(ch, sender, message string, t time.Time) Notification

NewChannelNotification creates a notifications/message JSON-RPC notification.

type RPCError

type RPCError struct {
	Message string `json:"message"`
	Code    int    `json:"code"`
}

RPCError is a JSON-RPC 2.0 error object.

func (*RPCError) Error

func (e *RPCError) Error() string

type Request

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

Request is an incoming JSON-RPC 2.0 message (may be a request or notification).

type Resource

type Resource struct {
	URI         string `json:"uri"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	MIMEType    string `json:"mimeType,omitempty"`
}

Resource describes a queryable MCP resource.

type ResourceContent

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

ResourceContent holds the data returned for a resource read.

type Response

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

Response is an outgoing JSON-RPC 2.0 response.

type SSEBroker

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

SSEBroker fans out SSE messages to all connected clients.

func MountOn

func MountOn(mux *http.ServeMux, srv *Server, prefix string) *SSEBroker

MountOn registers MCP SSE endpoints on an existing ServeMux under the given prefix. Supports both legacy paths (/mcp/sse) and agent-scoped paths (/mcp/{agent}/sse). Returns the broker so callers can push notifications directly.

func NewSSEBroker

func NewSSEBroker() *SSEBroker

NewSSEBroker creates an SSEBroker ready to use.

func (*SSEBroker) SSEHandler

func (b *SSEBroker) SSEHandler() http.HandlerFunc

SSEHandler returns an http.HandlerFunc for the SSE endpoint. Exported so tests in mcp_test can mount it on their own ServeMux.

func (*SSEBroker) SendToAgents

func (b *SSEBroker) SendToAgents(v any, agents map[string]bool)

SendToAgents sends a notification only to clients whose agent name is in the set. Used for channel-membership-filtered message delivery.

func (*SSEBroker) SetMessageEndpoint added in v0.2.0

func (b *SSEBroker) SetMessageEndpoint(endpoint string)

SetMessageEndpoint overrides the endpoint URL returned to new SSE clients in the initial `event: endpoint` line. Used by scoped mounts (phase M6) so each per-workspace broker advertises its scoped /message path.

type Server

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

Server is a bc MCP server. It owns handles to workspace state and dispatches JSON-RPC 2.0 requests from either stdio or SSE transports.

func New

func New(cfg Config) (*Server, error)

New creates a Server. Call Close when done. When stores are provided via Config, the caller owns their lifecycle and Close will not close them.

func (*Server) Close

func (s *Server) Close() error

Close releases resources held by the server. Only closes stores that the server created itself (not injected ones).

func (*Server) Handle

func (s *Server) Handle(ctx context.Context, req Request) Response

Handle processes a single JSON-RPC request and returns the response. For notifications (no ID), the returned Response has a nil ID and no result/error set.

func (*Server) HandleSSEMessage

func (s *Server) HandleSSEMessage(ctx context.Context, broker *SSEBroker) http.HandlerFunc

HandleSSEMessage processes POST /message — client→server direction. Exported so tests can mount it on their own ServeMux.

func (*Server) ServeSSE

func (s *Server) ServeSSE(ctx context.Context, addr string) error

ServeSSE starts an HTTP server that implements the MCP SSE transport.

Endpoints:

  • GET /sse — client connects; receives server→client events as SSE
  • POST /message — client sends JSON-RPC requests; response sent via SSE

addr must be a host:port pair. If addr is a bare ":port" it is rewritten to "127.0.0.1:port" so the server only listens on localhost — never on all interfaces — which prevents accidental network exposure.

The server shuts down cleanly when ctx is canceled.

func (*Server) ServeStdio

func (s *Server) ServeStdio(ctx context.Context) error

ServeStdio runs the MCP server over stdin/stdout using newline-delimited JSON. It blocks until ctx is canceled or stdin is closed.

func (*Server) ServeStdioRW

func (s *Server) ServeStdioRW(ctx context.Context, r io.Reader, w io.Writer) error

ServeStdioRW runs the MCP server using the provided reader/writer instead of os.Stdin/os.Stdout. Useful for testing.

func (*Server) SetBroker

func (s *Server) SetBroker(broker *SSEBroker)

SetBroker attaches an SSE broker for MCP notifications. Message delivery is now handled directly by the OnMessage callback in server.go — no poller needed.

type Tool

type Tool struct {
	InputSchema map[string]any `json:"inputSchema"`
	Name        string         `json:"name"`
	Description string         `json:"description,omitempty"`
}

Tool describes a callable MCP tool.

type ToolContent

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

ToolContent is a piece of content returned by a tool call.

Jump to

Keyboard shortcuts

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