server

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package server implements a Model Context Protocol (MCP) server. It provides a JSON-RPC dispatcher, method handlers, and provider interfaces that allow exposing tools and resources to MCP clients.

Index

Constants

View Source
const DefaultRequestTimeout = 30 * time.Second

DefaultRequestTimeout is the per-RPC timeout applied to every gRPC call made through the bridge. Callers can override this with BridgeOption.

View Source
const WeaveRequestTimeout = 5 * time.Minute

WeaveRequestTimeout is a longer timeout for Weave/StreamWeave RPCs, which involve multi-step agent execution (LLM calls + tool use).

Variables

This section is empty.

Functions

func ContextWithOutgoingAuth added in v1.4.0

func ContextWithOutgoingAuth(ctx context.Context, bearer, userID string) context.Context

ContextWithOutgoingAuth attaches the caller's bearer token and user id so the bridge forwards them to looms on subsequent gRPC calls made with this context.

Types

type BridgeOption

type BridgeOption func(*LoomBridge)

BridgeOption configures a LoomBridge.

func WithAllowedTools added in v1.4.0

func WithAllowedTools(names []string) BridgeOption

WithAllowedTools restricts the bridge to a fixed set of tool names. When set (non-empty), only these tools are advertised by ListTools and permitted by CallTool/CallToolStream; every other loom RPC is hidden and rejected. This is the edge allow-list for an internet-facing MCP endpoint — it keeps destructive admin tools (delete_agent, register_tool, schedules, ...) off a public surface regardless of what a client requests. Empty/unset = expose everything (backwards compatible).

func WithBuilderAgent added in v1.4.0

func WithBuilderAgent(name string) BridgeOption

WithBuilderAgent overrides the agent that loom_build delegates to. Defaults to the weaver. Set via LOOM_MCP_BUILDER_AGENT to point builds at a dedicated agent.

func WithMCPServer

func WithMCPServer(s *MCPServer) BridgeOption

WithMCPServer sets the MCPServer reference so the bridge can send resource list change notifications after app mutations (create/update/delete).

func WithRequestTimeout

func WithRequestTimeout(d time.Duration) BridgeOption

WithRequestTimeout sets the per-RPC timeout for gRPC calls.

func WithSkillOrchestrator

func WithSkillOrchestrator(o *skills.Orchestrator) BridgeOption

WithSkillOrchestrator sets the skill orchestrator for local skill management tools. When set, the bridge exposes loom_list_skills, loom_get_skill, loom_create_skill, loom_activate_skill, and loom_deactivate_skill tools.

func WithTLS

func WithTLS(certFile string, skipVerify bool) BridgeOption

WithTLS configures TLS for the gRPC connection to the looms server. certFile is the path to a PEM-encoded CA certificate. If empty, the system certificate pool is used. Set skipVerify to true to skip server certificate verification -- this is NOT recommended for production deployments.

type LoomBridge

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

LoomBridge maps Loom's gRPC API to MCP tool and resource providers. It connects to a running looms server and exposes its capabilities as MCP tools for clients like Claude Desktop.

func NewLoomBridge

func NewLoomBridge(grpcAddr string, uiRegistry *apps.UIResourceRegistry, logger *zap.Logger, opts ...BridgeOption) (*LoomBridge, error)

NewLoomBridge creates a bridge to a running looms server.

func NewLoomBridgeFromClient

func NewLoomBridgeFromClient(client loomv1.LoomServiceClient, uiRegistry *apps.UIResourceRegistry, logger *zap.Logger, opts ...BridgeOption) *LoomBridge

NewLoomBridgeFromClient creates a bridge from an existing gRPC client. Useful for testing with mock clients.

func (*LoomBridge) CallTool

func (b *LoomBridge) CallTool(ctx context.Context, name string, args map[string]interface{}) (*protocol.CallToolResult, error)

CallTool implements ToolProvider.

func (*LoomBridge) CallToolStream added in v1.4.0

func (b *LoomBridge) CallToolStream(ctx context.Context, name string, args map[string]interface{}, _ string, emit ProgressEmitter) (*protocol.CallToolResult, error)

CallToolStream implements StreamingToolProvider. loom_weave and loom_execute_workflow run their streaming RPCs and forward progress via emit; any other tool falls back to the synchronous CallTool (no progress emitted).

func (*LoomBridge) Close

func (b *LoomBridge) Close() error

Close closes the gRPC connection.

func (*LoomBridge) ListResources

func (b *LoomBridge) ListResources(ctx context.Context) ([]protocol.Resource, error)

ListResources implements ResourceProvider. Returns embedded apps from the local registry merged with dynamic apps from the gRPC server. The server is authoritative for dynamic apps; the local registry is authoritative for embedded apps.

func (*LoomBridge) ListTools

func (b *LoomBridge) ListTools(_ context.Context) ([]protocol.Tool, error)

ListTools implements ToolProvider.

func (*LoomBridge) ReadResource

func (b *LoomBridge) ReadResource(ctx context.Context, uri string) (*protocol.ReadResourceResult, error)

ReadResource implements ResourceProvider. Reads from the local registry first (embedded apps). If not found locally, proxies the request to the gRPC server (dynamic apps).

func (*LoomBridge) SetMCPServer

func (b *LoomBridge) SetMCPServer(s *MCPServer)

SetMCPServer sets the MCPServer reference after construction. This is useful when the MCPServer is created after the bridge (common in main.go wiring).

func (*LoomBridge) SupportsStreaming added in v1.4.0

func (b *LoomBridge) SupportsStreaming(name string) bool

SupportsStreaming implements StreamingToolProvider. loom_weave streams agent output via StreamWeave; loom_execute_workflow streams multi-agent progress via StreamWorkflow.

type MCPServer

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

MCPServer is a JSON-RPC based MCP server that dispatches method calls to registered handlers.

func NewMCPServer

func NewMCPServer(name, version string, logger *zap.Logger, opts ...Option) *MCPServer

NewMCPServer creates a new MCP server with the given identity and options.

func (*MCPServer) ClientCapabilities

func (s *MCPServer) ClientCapabilities() *protocol.ClientCapabilities

ClientCapabilities returns the connected client's capabilities, or nil if not yet initialized.

func (*MCPServer) ClientInfo

func (s *MCPServer) ClientInfo() *protocol.Implementation

ClientInfo returns the connected client's information, or nil if not yet initialized.

func (*MCPServer) HandleMessage

func (s *MCPServer) HandleMessage(ctx context.Context, msg []byte) ([]byte, error)

HandleMessage processes a single JSON-RPC message and returns the response bytes. For notifications (no id), returns nil.

func (*MCPServer) HandleMessageStream added in v1.4.0

func (s *MCPServer) HandleMessageStream(ctx context.Context, msg []byte, w transport.SSEWriter) ([]byte, error)

HandleMessageStream processes a single JSON-RPC message and, for a stream-capable tools/call, emits progress notifications via w before returning the final response bytes. Any other message — or any tool when no StreamingToolProvider is registered — falls back to the synchronous HandleMessage path, whose single result the transport emits as one SSE event.

It implements transport.StreamingMCPHandler so cmd/loom-mcp can wire it as the StreamableHTTPServer's StreamHandler.

func (*MCPServer) NotifyResourceListChanged

func (s *MCPServer) NotifyResourceListChanged()

NotifyResourceListChanged enqueues a resources/list_changed notification. The notification is sent asynchronously via the Serve() select loop. If the channel is full the notification is dropped with a warning log.

func (*MCPServer) RegisterHandler

func (s *MCPServer) RegisterHandler(method string, handler MethodHandler)

RegisterHandler registers a handler for a JSON-RPC method.

func (*MCPServer) Serve

func (s *MCPServer) Serve(ctx context.Context, t transport.Transport) error

Serve runs the server's read loop on the given transport until the context is cancelled or the transport is closed. It concurrently handles incoming messages and dispatches outgoing notifications via the notification channel.

type MethodHandler

type MethodHandler func(ctx context.Context, id json.RawMessage, params json.RawMessage) (interface{}, error)

MethodHandler processes a JSON-RPC method call. id is the request ID (nil for notifications). params is the raw JSON params from the request.

type Option

type Option func(*MCPServer)

Option configures an MCPServer.

func WithExtensions

func WithExtensions(ext map[string]interface{}) Option

WithExtensions sets the server's extensions (e.g., MCP Apps).

func WithInstructions added in v1.4.0

func WithInstructions(text string) Option

WithInstructions sets the server-level instructions returned on initialize. This is how the endpoint steers a connecting model — e.g. telling it to author agents/workflows via loom_build rather than constructing YAML by hand.

func WithResourceProvider

func WithResourceProvider(p ResourceProvider) Option

WithResourceProvider registers a ResourceProvider and enables the resources capability. Sets ListChanged: true to indicate the server may send resource list change notifications.

func WithToolProvider

func WithToolProvider(p ToolProvider) Option

WithToolProvider registers a ToolProvider and enables the tools capability.

type ProgressEmitter added in v1.4.0

type ProgressEmitter interface {
	// EmitProgress sends one progress update. progress and total are on the
	// same scale (e.g. 0..100); total may be 0 if unknown.
	EmitProgress(progress, total float64) error
	// EmitMessage sends a human-readable status (the MCP progress `message`
	// field) carrying a monotonically increasing progress counter so the
	// notification is spec-valid. loom uses this to stream the agent's
	// cumulative partial response text as it generates.
	EmitMessage(message string) error
}

ProgressEmitter delivers incremental progress for a streaming tool call as MCP `notifications/progress` events. Calls are a no-op when the client did not supply a progress token (progress is opt-in per the MCP spec).

type ResourceProvider

type ResourceProvider interface {
	// ListResources returns all available resources.
	ListResources(ctx context.Context) ([]protocol.Resource, error)

	// ReadResource reads a resource by its URI.
	ReadResource(ctx context.Context, uri string) (*protocol.ReadResourceResult, error)
}

ResourceProvider supplies resources to the MCP server. Implementations expose domain-specific data and UI resources.

type StreamingToolProvider added in v1.4.0

type StreamingToolProvider interface {
	// SupportsStreaming reports whether the named tool streams progress.
	SupportsStreaming(name string) bool
	// CallToolStream invokes a tool, forwarding progress via emit, and returns
	// the final result. Implementations should fall back to a non-streaming
	// execution for tools that do not stream.
	CallToolStream(ctx context.Context, name string, args map[string]interface{}, progressToken string, emit ProgressEmitter) (*protocol.CallToolResult, error)
}

StreamingToolProvider is an optional extension of ToolProvider for tools that can stream progress while running. The MCP server type-asserts its registered ToolProvider to this interface; if absent, every tool uses the synchronous CallTool path.

type ToolProvider

type ToolProvider interface {
	// ListTools returns all available tools.
	ListTools(ctx context.Context) ([]protocol.Tool, error)

	// CallTool invokes a tool by name with the given arguments.
	CallTool(ctx context.Context, name string, args map[string]interface{}) (*protocol.CallToolResult, error)
}

ToolProvider supplies tools to the MCP server. Implementations map domain-specific capabilities to MCP tool definitions.

Jump to

Keyboard shortcuts

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