mcp

package
v0.222.0 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

README

mcp

What - the Model Context Protocol anti-corruption layer: connecting to MCP servers, discovering their tools, and exposing them to the agent. Why - MCP servers speak their own protocol and their tools only exist at runtime, so a translating layer keeps discovery and lifecycle out of the agent. How - infrastructure/ is a small HTTP client for MCP 2026-07-28, and Supervisor manages the server connections, their containers and their liveness.

How it plugs in

  • The Supervisor discovers each server's tools and names them MCP_<server>_<tool>. Chat registers them as server status updates arrive; headless registers them once at start-up.
  • Servers are configured in .infer/mcp.yaml or ~/.infer/mcp.yaml. infer mcp and the /mcp shortcut manage them.
  • Only tools are consumed. Embedded resource blocks in a tool result are flattened into text.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type MCPTool

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

MCPTool is the agent's view of one tool on an MCP server: it presents the server's tool to the LLM under its namespaced name and calls it through the server's Client.

func NewMCPTool

func NewMCPTool(
	serverName, toolName, description string,
	inputSchema map[string]any,
	client mcpdomain.Client,
	mcpConfig *config.MCPConfig,
) *MCPTool

NewMCPTool creates a new MCP tool wrapper

func (*MCPTool) Definition

func (t *MCPTool) Definition() sdk.ChatCompletionTool

Definition returns the tool definition for the LLM

func (*MCPTool) Execute

func (t *MCPTool) Execute(ctx context.Context, args map[string]any) (*agentdomain.ToolExecutionResult, error)

Execute runs the MCP tool with given arguments

func (*MCPTool) FormatForLLM

func (t *MCPTool) FormatForLLM(result *agentdomain.ToolExecutionResult) string

FormatForLLM formats the result for LLM consumption with detailed information

func (*MCPTool) FormatForUI

func (t *MCPTool) FormatForUI(result *agentdomain.ToolExecutionResult) string

FormatForUI formats the result for UI display

func (*MCPTool) FormatPreview

func (t *MCPTool) FormatPreview(result *agentdomain.ToolExecutionResult) string

FormatPreview returns a short preview of the result for UI display

func (*MCPTool) FormatResult

func (t *MCPTool) FormatResult(result *agentdomain.ToolExecutionResult, formatType agentdomain.FormatterType) string

FormatResult formats tool execution results for different contexts

func (*MCPTool) IsEnabled

func (t *MCPTool) IsEnabled() bool

IsEnabled returns whether this MCP tool is enabled

func (*MCPTool) ShouldAlwaysExpand

func (t *MCPTool) ShouldAlwaysExpand() bool

ShouldAlwaysExpand determines if tool results should always be expanded in UI

func (*MCPTool) ShouldCollapseArg

func (t *MCPTool) ShouldCollapseArg(key string) bool

ShouldCollapseArg determines if an argument should be collapsed in display

func (*MCPTool) Validate

func (t *MCPTool) Validate(args map[string]any) error

Validate checks the arguments against the server's input schema.

type ServerStatus

type ServerStatus struct {
	Name      string `json:"name"`
	Connected bool   `json:"connected"`
	Tools     int    `json:"tools"`
	Error     string `json:"error,omitempty"`
}

ServerStatus is the probe result for one configured MCP server.

type StatusReport

type StatusReport struct {
	Enabled          bool           `json:"enabled"`
	TotalServers     int            `json:"total_servers"`
	ConnectedServers int            `json:"connected_servers"`
	TotalTools       int            `json:"total_tools"`
	Servers          []ServerStatus `json:"servers"`
}

StatusReport mirrors the TUI's "MCP connected/total (tools)" indicator plus a per-server breakdown. TotalServers counts every configured server, like the TUI; only enabled servers are dialed.

func ProbeStatus

func ProbeStatus(ctx context.Context, cfg *config.MCPConfig, only string) (StatusReport, error)

ProbeStatus dials every enabled server once (or just `only` when non-empty) and reports what a fresh session would see. Connection state is per process, so a probe is the only honest answer from outside a running session.

func (StatusReport) Indicator

func (r StatusReport) Indicator() string

Indicator renders the report the way the TUI status bar does.

type Supervisor

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

Supervisor manages multiple MCP server connections and their container lifecycle

func NewSupervisor

func NewSupervisor(sessionID convdomain.SessionID, cfg *config.MCPConfig, runtime containerruntime.ContainerRuntime, notifier agentdomain.UINotifier) *Supervisor

NewSupervisor creates a new MCP supervisor. notifier is the single UI ingress the liveness probes push ServerStatusUpdateEvent through; a nil notifier degrades to no UI pushes.

func (*Supervisor) Close

func (s *Supervisor) Close() error

Close stops monitoring, stops containers, and cleans up resources

func (*Supervisor) DiscoverTools

func (s *Supervisor) DiscoverTools(ctx context.Context) map[string]agentdomain.Tool

DiscoverTools probes every server once, in parallel, and returns the tools of those that answered. Headless calls it before the first turn, since it has no liveness loop to register tools as servers come up. ponytail: run:true container servers still starting in the background are skipped (their client has no URL yet); wait on StartServers if headless ever needs container-hosted MCP tools on the first turn.

func (*Supervisor) GetTotalServers

func (s *Supervisor) GetTotalServers() int

GetTotalServers returns the total number of configured MCP servers from config

func (*Supervisor) StartMonitoring

func (s *Supervisor) StartMonitoring(ctx context.Context)

StartMonitoring begins background health monitoring, pushing every ServerStatusUpdateEvent through the injected UI notifier. It is idempotent - subsequent calls are no-ops. The initial status is emitted from a goroutine because Notify wraps the unbuffered (*tea.Program).Send, which blocks until the Bubble Tea loop consumes; emitting it synchronously from app.Init (before the loop runs) would deadlock.

func (*Supervisor) StartServer

func (s *Supervisor) StartServer(ctx context.Context, server config.MCPServerEntry) error

StartServer starts a single MCP server container, or points the client at a detached shared container when one is already running.

func (*Supervisor) StartServers

func (s *Supervisor) StartServers(ctx context.Context) error

StartServers starts all MCP servers that have run=true This method is non-fatal and always returns nil

func (*Supervisor) StopServer

func (s *Supervisor) StopServer(ctx context.Context, serverName string) error

StopServer stops this session's container for the named server. With the shared session id it stops the detached container started by `infer mcp start`.

func (*Supervisor) StopServers

func (s *Supervisor) StopServers(ctx context.Context) error

StopServers stops all running MCP server containers

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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