mcp

package
v1.39.0 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: AGPL-3.0 Imports: 27 Imported by: 0

Documentation

Overview

Package mcp: thin-client stdio proxy.

Every Claude Code subagent process spawns its own copy of the project's .mcp.json-configured MCP servers, including "stapler-squad --mcp". Prior to this file, that meant each subprocess called buildMCPDeps() -> BuildCoreDeps() -> NewSessionServiceFromConfig(), which opens its own ent/SQLite client, EventBus, ReviewQueue, and ApprovalStore — a full duplicate of state the already-running stapler-squad HTTP server (localhost:8543) already holds. With N subagents in a session tree, that's N redundant SQLite connections and event buses for read-mostly MCP tool calls.

NewProxyCore/RunProxyServer instead connect to the running server's Streamable HTTP MCP endpoint (mounted at /mcp by NewHTTPHandler) and forward every stdio tool call to it, so the stdio subprocess holds no storage of its own. If the HTTP server isn't reachable (e.g. no daemon running yet), the caller falls back to the original fully-local NewCore() path.

Package mcp implements the MCP (Model Context Protocol) server for Stapler Squad. Activated by the --mcp flag; communicates over stdio transport.

Index

Constants

View Source
const (
	ErrPermissionDenied = "PERMISSION_DENIED"
	ErrItemNotFound     = "ITEM_NOT_FOUND"
	ErrFeatureDisabled  = "FEATURE_DISABLED"
)
View Source
const (
	ErrSessionNotFound       = "SESSION_NOT_FOUND"
	ErrInvalidArgument       = "INVALID_ARGUMENT"
	ErrInternalError         = "INTERNAL_ERROR"
	ErrConfirmationRequired  = "CONFIRMATION_REQUIRED"
	ErrInvalidStatusTrans    = "INVALID_STATUS_TRANSITION"
	ErrSessionNotRunning     = "SESSION_NOT_RUNNING"
	ErrRateLimitExceeded     = "RATE_LIMIT_EXCEEDED"
	ErrSessionStartupTimeout = "SESSION_STARTUP_TIMEOUT"
	ErrInvalidPath           = "INVALID_PATH"
	ErrPTYWriteTimeout       = "PTY_WRITE_TIMEOUT"
)

Error code constants — machine-readable identifiers for all tool failures.

Variables

View Source
var ErrProxyUnavailable = errors.New("mcp proxy: remote server unavailable")

ErrProxyUnavailable wraps any failure to connect to the running HTTP MCP server during the initial handshake (transport start, initialize, or tools/list). Callers should treat this as non-fatal and fall back to a fully local MCP core.

Functions

func InitMCPLogging

func InitMCPLogging()

InitMCPLogging redirects all application loggers to stderr so that log lines do not pollute the MCP stdio channel (stdout). Must be called before RunServer.

func NewCore

func NewCore(store session.InstanceStore, svc *services.SessionService, sbMgr *scrollback.ScrollbackManager, storage *session.Storage, eventBus *events.EventBus, prCache *githubpkg.UserPRCache, backlogEnabled func() bool) *mcpserver.MCPServer

NewCore creates an MCPServer with all tools registered. Shared by the stdio path (RunServer) and the HTTP path (NewHTTPHandler). storage is optional — when nil, backlog tools are not registered. eventBus is optional — when nil, triage-complete notifications are disabled. prCache is optional — when nil, GitHub PR tools are not registered. backlogEnabled is optional — when nil, backlog/goal tools are always enabled (matches pre-flag behavior, used by tests). When set, it gates registration at startup (belt-and-suspenders) and is threaded into each backlog/goal handler so a live flag flip takes effect without restarting the MCP server.

func NewHTTPHandler

func NewHTTPHandler(store session.InstanceStore, svc *services.SessionService, sbMgr *scrollback.ScrollbackManager, storage *session.Storage, eventBus *events.EventBus, prCache *githubpkg.UserPRCache, backlogEnabled func() bool) *mcpserver.StreamableHTTPServer

NewHTTPHandler returns an http.Handler that serves the MCP protocol over Streamable HTTP (the MCP 2025-03-26 transport). Mount it at /mcp on the existing HTTP server so Claude sessions can connect without spawning a subprocess. eventBus is optional — pass nil to disable triage-complete notifications. prCache is optional — pass nil to disable GitHub PR tools. backlogEnabled is optional — see NewCore.

func NewProxyCore added in v1.37.0

func NewProxyCore(ctx context.Context, httpURL string, headers map[string]string) (*mcpserver.MCPServer, *mcpclient.Client, error)

NewProxyCore connects to an already-running stapler-squad HTTP server at httpURL and builds a local *mcpserver.MCPServer whose tools simply forward CallTool requests to it. Returns an error wrapping ErrProxyUnavailable if the remote server cannot be reached or fails the MCP handshake.

The returned *mcpclient.Client must be closed by the caller once the local server is done serving (e.g. via defer).

func ProxyHeaders added in v1.37.0

func ProxyHeaders() map[string]string

ProxyHeaders builds the HTTP headers forwarded on every request to the remote MCP endpoint. Mirrors the X-Stapler-Session-UUID header injected by claudeMCPConfigArgs for the primary (non-proxied) HTTP MCP path, so backlog tools can identify the calling session the same way regardless of transport.

func RunProxyServer added in v1.37.0

func RunProxyServer(ctx context.Context, httpURL string, headers map[string]string) error

RunProxyServer connects to the running stapler-squad HTTP server and serves stdio MCP as a thin forwarding proxy, blocking until stdin closes or ctx is cancelled. Returns an error wrapping ErrProxyUnavailable (safe to fall back to a local core) if the initial handshake fails; any error returned after a successful handshake reflects a mid-session failure and should not trigger a fallback (stdout may already carry a partial MCP session).

func RunServer

func RunServer(ctx context.Context, store session.InstanceStore, svc *services.SessionService, sbMgr *scrollback.ScrollbackManager, storage *session.Storage, eventBus *events.EventBus, prCache *githubpkg.UserPRCache, backlogEnabled func() bool) error

RunServer initializes and starts the MCP stdio server. It blocks until the context is cancelled or stdin is closed. store is used for read-only discovery tools. svc provides lifecycle operations. sbMgr provides read access to terminal scrollback data persisted on disk. storage is used for backlog tools (optional; pass nil to disable). eventBus is optional — pass nil to disable triage-complete notifications on stdio path. prCache is optional — pass nil to disable GitHub PR tools. backlogEnabled is optional — see NewCore.

func WithSessionUUID added in v1.35.0

func WithSessionUUID(ctx context.Context, id string) context.Context

WithSessionUUID injects a session UUID into the context.

Types

type BranchInfo

type BranchInfo struct {
	Name    string `json:"name"`
	Current bool   `json:"current"`
}

BranchInfo holds branch metadata for list_session_branches.

type CreateSessionForPRResult added in v1.35.0

type CreateSessionForPRResult struct {
	MCPResult
	Session *SessionDetail `json:"session,omitempty"`
}

CreateSessionForPRResult is returned by create_session_for_pr.

type CreateSessionResult

type CreateSessionResult struct {
	MCPResult
	Session            *SessionDetail `json:"session,omitempty"`
	MCPInjectionFailed bool           `json:"mcp_injection_failed,omitempty"`
}

CreateSessionResult is returned by create_session.

type DiffStats

type DiffStats struct {
	FilesChanged int `json:"files_changed"`
	Insertions   int `json:"insertions"`
	Deletions    int `json:"deletions"`
}

DiffStats mirrors git.DiffStats for JSON output.

type GetSessionDiffResult

type GetSessionDiffResult struct {
	MCPResult
	Diff      string    `json:"diff"`
	Stats     DiffStats `json:"stats"`
	Truncated bool      `json:"truncated"`
}

GetSessionDiffResult is the response for get_session_diff.

type GetSessionResult

type GetSessionResult struct {
	MCPResult
	Session *SessionDetail `json:"session,omitempty"`
}

GetSessionResult is returned by get_session.

type GitHubPRSummary added in v1.35.0

type GitHubPRSummary struct {
	Owner             string    `json:"owner"`
	Repo              string    `json:"repo"`
	Number            int       `json:"number"`
	Title             string    `json:"title"`
	URL               string    `json:"url"`
	Branch            string    `json:"branch"`
	BaseBranch        string    `json:"base_branch"`
	IsDraft           bool      `json:"is_draft"`
	CIStatus          string    `json:"ci_status"`
	ApprovedCount     int       `json:"approved_count"`
	ChangesReqCount   int       `json:"changes_req_count"`
	UpdatedAt         time.Time `json:"updated_at"`
	ExistingSessionID string    `json:"existing_session_id,omitempty"`
	WorktreePath      string    `json:"worktree_path,omitempty"`
}

GitHubPRSummary is the MCP representation of one open pull request.

type ListGitHubPRsResult added in v1.35.0

type ListGitHubPRsResult struct {
	MCPResult
	PRs        []GitHubPRSummary `json:"prs"`
	TotalCount int               `json:"total_count"`
	Accounts   []string          `json:"accounts"`
}

ListGitHubPRsResult is returned by list_github_prs.

type ListSessionBranchesResult

type ListSessionBranchesResult struct {
	MCPResult
	Branches      []BranchInfo `json:"branches"`
	CurrentBranch string       `json:"current_branch"`
}

ListSessionBranchesResult is the response for list_session_branches.

type ListSessionsResult

type ListSessionsResult struct {
	MCPResult
	Sessions   []SessionSummary `json:"sessions"`
	TotalCount int              `json:"total_count"`
	NextCursor *string          `json:"next_cursor"`
}

ListSessionsResult is returned by list_sessions.

type MCPError

type MCPError struct {
	Code        string `json:"code"`
	Message     string `json:"message"`
	Remediation string `json:"remediation,omitempty"`
}

MCPError is the structured error returned in every tool result on failure.

type MCPResult

type MCPResult struct {
	Success bool      `json:"success"`
	Error   *MCPError `json:"error,omitempty"`
}

MCPResult is the top-level wrapper for all tool responses. On success, Success=true and Error is nil. On failure, Success=false and Error is set.

type ReadSessionOutputResult

type ReadSessionOutputResult struct {
	MCPResult
	Output     string `json:"output,omitempty"`
	TotalLines int    `json:"total_lines"`
	Truncated  bool   `json:"truncated"`
}

ReadSessionOutputResult is the response type for read_session_output.

type ReviewCompletionSignaler added in v1.35.0

type ReviewCompletionSignaler interface {
	StopDriverForSession(sessionTitle string)
}

ReviewCompletionSignaler allows the MCP handler to stop an AutonomousDriver after submit_review_verdict completes. The stop call is belt-and-suspenders; the LLM orchestrator will also detect completion from the terminal tail. Note: Stop() fires fireCompletion(Stuck=true), but the role-aware callback skips all status transitions for SessionRoleReview, so this is safe.

type ReviewTrigger added in v1.37.0

type ReviewTrigger interface {
	TriggerReviewForSession(sessionUUID string)
}

ReviewTrigger allows the MCP handler to spawn a review gate immediately when request_review is called, instead of waiting for the next ReconcileStuck tick (up to 60s later). Implemented by SessionService, which delegates to the BacklogLifecycleListener wired via SetReviewGateTrigger.

type RunCommandResult

type RunCommandResult struct {
	MCPResult
	Output       string `json:"output"`
	Truncated    bool   `json:"truncated"`
	TimedOut     bool   `json:"timed_out"`
	LastSequence uint64 `json:"last_sequence"`
}

RunCommandResult is the response for run_command.

type SearchSessionsResult

type SearchSessionsResult struct {
	MCPResult
	Sessions   []SessionSummary `json:"sessions"`
	TotalCount int              `json:"total_count"`
}

SearchSessionsResult is returned by search_sessions.

type SendControlResult

type SendControlResult struct {
	MCPResult
	Sent string `json:"sent"`
}

SendControlResult is the response for send_control.

type SessionDetail

type SessionDetail struct {
	SessionSummary
	Program     string `json:"program"`
	SessionType string `json:"session_type"`
	WorkingDir  string `json:"working_dir,omitempty"`
}

SessionDetail extends SessionSummary with additional fields returned by get_session.

type SessionSummary

type SessionSummary struct {
	ID             string    `json:"id"`
	Title          string    `json:"title"`
	Status         string    `json:"status"`
	Tags           []string  `json:"tags"`
	Branch         string    `json:"branch,omitempty"`
	Path           string    `json:"path"`
	CreatedAt      time.Time `json:"created_at"`
	LastActivityAt time.Time `json:"last_activity_at"`
}

SessionSummary is returned by list_sessions and search_sessions.

type SetSessionGoalResult added in v1.35.0

type SetSessionGoalResult struct {
	MCPResult
	SessionUUID string `json:"session_uuid"`
	Goal        string `json:"goal"`
	Status      string `json:"status"`
	TasksTotal  int    `json:"tasks_total"`
}

type SteerSessionResult added in v1.35.0

type SteerSessionResult struct {
	MCPResult
	SessionID string `json:"session_id"`
	CharsSent int    `json:"chars_sent"`
	Result    string `json:"result,omitempty"` // set when using --resume subprocess
	Method    string `json:"method"`           // "send_keys" or "resume_subprocess"
}

SteerSessionResult is the response for steer_session.

type UpdateSessionTaskResult added in v1.35.0

type UpdateSessionTaskResult struct {
	MCPResult
	TaskID     string `json:"task_id"`
	NewStatus  string `json:"new_status"`
	TasksDone  int    `json:"tasks_done"`
	TasksTotal int    `json:"tasks_total"`
}

type WaitForOutputResult

type WaitForOutputResult struct {
	MCPResult
	Matched     bool   `json:"matched"`
	MatchedLine string `json:"matched_line,omitempty"`
	Output      string `json:"output"`
	Truncated   bool   `json:"truncated"`
}

WaitForOutputResult is the response for wait_for_output.

type WriteSessionResult

type WriteSessionResult struct {
	MCPResult
	BytesWritten int `json:"bytes_written"`
}

WriteSessionResult is the response for write_to_session.

Jump to

Keyboard shortcuts

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