Help us shape the future of Go! Take the 2026 Go Developer Survey

mcpserver

package
v8.154.0-rc.1 Latest Latest
Warning

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

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

Documentation

Overview

Package mcpserver is devctl serve: the agent-facing commands as MCP tools over streamable HTTP, acting on GitHub as the person who calls them.

A tool answers with the command's JSON document, devctl's envelope included, as structured content: the exit code is a field, and the call is an MCP error only for auth_required. A wait is one call that blocks until its verdict and sends notifications/progress on the caller's progressToken meanwhile, at an interval below the server's registered timeout, so the gateway restarts that timeout on each.

What only a laptop needs is not here: no version gate, no keychain or other credential store, no detached merge state on disk, no SIGHUP handling and no DEVCTL_TIME_SCALE.

Index

Constants

View Source
const (
	ToolPRWait        = "pr_wait"
	ToolPRMergeStatus = "pr_merge_status"
	ToolReleaseWait   = "release_wait"
)

The tools' names.

View Source
const Anonymous = "anonymous"

Anonymous is the login of a call refused before its grant named the caller: one without a grant, or one refused as usage.

View Source
const DefaultInstallationsTTL = 5 * time.Minute

DefaultInstallationsTTL is how long a token's installations are kept.

View Source
const DefaultNoProgressTimeout = 20 * time.Second

DefaultNoProgressTimeout bounds a wait called without a progressToken, which no progress keeps alive: below muster's default registered timeout of 30 s with headroom for pr_merge's merge call.

View Source
const DefaultProgressInterval = 10 * time.Second

DefaultProgressInterval is how often a wait reports progress: below muster's default registered timeout of 30 s with headroom.

View Source
const DefaultUsersTTL = 5 * time.Minute

DefaultUsersTTL is how long a token's user is kept.

View Source
const GrantHeaderPrefix = "X-Muster-Grant-" //nolint:gosec // G101: a header name, not a credential

GrantHeaderPrefix starts the header the gateway in front carries the person's token of one provider App in: muster attaches X-Muster-Grant-<app> for every App of the server's registration (spec.auth.providerApps) the person granted.

View Source
const IdentitySource = "platform"

IdentitySource is a promotion's identity source on the server: the token the platform handed over for the person.

View Source
const MaxTimeout = 55 * time.Minute

MaxTimeout bounds a wait's own timeout: below the hour muster keeps a progress-kept call alive at most, so the wait ends with devctl's own timeout verdict, not the gateway's.

View Source
const Name = "devctl"

Name is the server's name in its MCP implementation info.

View Source
const StatusGrantRequired = "grant_required"

StatusGrantRequired is the structuredContent status of a result that needs the person's grant of the Apps it names in "apps": muster answers it auth_required with each App's sign-in link (authUrl).

View Source
const ToolPRMerge = "pr_merge"

ToolPRMerge is the merge tool's name.

View Source
const ToolReleasePromote = "release_promote"

ToolReleasePromote is the promotion tool's name, served with Config.ReleasePromote only.

Variables

This section is empty.

Functions

This section is empty.

Types

type Caller

type Caller struct {
	// Login is the person's GitHub login.
	Login string
	// ID is the person's GitHub user id, stable across a renamed login.
	ID int64
}

Caller is the person a call is made for, as GitHub names the holder of their grant's token.

type Config

type Config struct {
	// Version is the version the server reports: the binary's.
	Version string
	// Credentials answer the person's GitHub token; nil is [NoCredentials].
	Credentials Credentials
	// Sources build the clients a wait reads with; nil is [GitHubSources]
	// over Endpoints.
	Sources Sources
	// Endpoints are GitHub's and the registries'; zero is
	// [agentcli.DefaultEndpoints].
	Endpoints agentcli.Endpoints
	// Clock is the waits' clock; nil is the wall clock at scale 1, never
	// DEVCTL_TIME_SCALE.
	Clock *agentcli.Clock
	// ProgressInterval is how often a wait reports progress; zero is
	// DefaultProgressInterval.
	ProgressInterval time.Duration
	// NoProgressTimeout bounds a wait called without a progressToken, so
	// it answers within the gateway's registered timeout; zero is
	// DefaultNoProgressTimeout.
	NoProgressTimeout time.Duration
	// Merges are the merges of this server pr_merge_status reads; nil is an
	// empty [mergejob.Memory]. pr_merge records its merges in them when they
	// take a Put, as a Memory does. Nothing is kept on disk.
	Merges mergejob.Jobs
	// ReleasePromote serves release_promote, the selector of the one tool
	// that cuts a stable release; off, the tool is not listed.
	ReleasePromote bool
	// Metrics count the calls; nil counts none.
	Metrics *Metrics
	// Logger logs one line per call; nil logs nothing.
	Logger *slog.Logger
}

Config configures a Server.

type Credentials

type Credentials interface {
	// GitHubToken is the person's token for the call in ctx; an
	// [agentcli.ExitCoder] of [agentcli.ExitAuthRequired] when the server
	// holds none for them.
	GitHubToken(ctx context.Context) (string, error)
}

Credentials answer the GitHub token of the person a call is made for.

type GitHubInstallations

type GitHubInstallations struct {
	BaseURL string
	Client  *http.Client
	TTL     time.Duration
	Now     func() time.Time
	// contains filtered or unexported fields
}

GitHubInstallations read GET /user/installations at BaseURL and keep each token's answer for TTL.

func (*GitHubInstallations) Owners

func (g *GitHubInstallations) Owners(ctx context.Context, token string) ([]string, error)

Owners implements Installations.

type GitHubSources

type GitHubSources struct {
	Endpoints agentcli.Endpoints
}

GitHubSources are the clients of GitHub and the registries at Endpoints. They hold no CircleCI client: the server has no CircleCI credential, so a pull request's CircleCI state is the commit statuses CircleCI posts to GitHub. The private registry is read anonymously.

func (GitHubSources) PRMerge

func (g GitHubSources) PRMerge(_ context.Context, token string, transport http.RoundTripper) (PRMergeSources, error)

PRMerge implements Sources.

func (GitHubSources) PRWait

func (g GitHubSources) PRWait(_ context.Context, token string, transport http.RoundTripper) (PRWaitSources, error)

PRWait implements Sources.

func (GitHubSources) ReleasePromote

func (g GitHubSources) ReleasePromote(_ context.Context, token string, transport http.RoundTripper) (*releasepromote.Sources, error)

ReleasePromote implements Sources: the person's token, never renewed.

func (GitHubSources) ReleaseWait

func (g GitHubSources) ReleaseWait(_ context.Context, token string, transport http.RoundTripper) (*releasewait.Sources, error)

ReleaseWait implements Sources: no CircleCI client, the wait reads CircleCI through the commit statuses of the tag's commit.

type GitHubUsers added in v8.154.1

type GitHubUsers struct {
	BaseURL string
	Client  *http.Client
	TTL     time.Duration
	Now     func() time.Time
	// contains filtered or unexported fields
}

GitHubUsers read GET /user at BaseURL and keep each token's answer for TTL: a token GitHub refuses is auth_required.

func (*GitHubUsers) User added in v8.154.1

func (g *GitHubUsers) User(ctx context.Context, token string) (Caller, error)

User implements Users.

type Installations

type Installations interface {
	Owners(ctx context.Context, token string) ([]string, error)
}

Installations answer the accounts a GitHub App is installed on that the holder of a user token of it reaches.

type Metrics

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

Metrics are the server's call metrics, labelled with the tool, the caller's GitHub login and user id (Anonymous and empty for a call whose grant named none), the repository (owner/repo; empty for a tool that names none or an argument refused as usage) and the verdict.

func NewMetrics

func NewMetrics(registerer prometheus.Registerer) (*Metrics, error)

NewMetrics registers the server's metrics with registerer.

type MusterGrant

type MusterGrant struct {
	// App is the provider App's name in muster, the header's suffix.
	App string
	// GitHubApp is the GitHub App's name, as a refusal names it.
	GitHubApp string
	// Users answer the person the token acts as, the call's caller; nil
	// names none and accepts the token unchecked.
	Users Users
	// Installations answer the owners the App is installed on that the
	// person reaches; nil checks none.
	Installations Installations
}

MusterGrant is the person's token of the GitHub App muster keeps as App: muster attaches it to every call the person granted it for. The token names the caller: a call without one GitHub accepts is refused. The server stores no token and runs no sign-in.

func (MusterGrant) GitHubToken

func (g MusterGrant) GitHubToken(ctx context.Context) (string, error)

GitHubToken implements Credentials: the person's token of the App, with the caller it names put on the call; a grant_required auth_required without one or with one GitHub refuses, and not_applicable for a repository whose owner the App is not installed on.

type NoCredentials

type NoCredentials struct{}

NoCredentials is the server with no hand-over of a person's token: every call that reads GitHub is auth_required.

func (NoCredentials) GitHubToken

func (NoCredentials) GitHubToken(context.Context) (string, error)

GitHubToken implements Credentials.

type PRMergeSources

type PRMergeSources struct {
	GitHub  prmerge.GitHub
	Rate    prwait.RateSource
	Entries prwait.EntryFinder
	// Policy is the repository's opt-out; nil reads the team files through
	// GitHub, a *githubclient.Client.
	Policy prmerge.Policy
}

PRMergeSources are what a merge reads and writes, its release wait aside, which reads Sources.ReleaseWait's.

type PRWaitSources

type PRWaitSources struct {
	GitHub  prwait.GitHub
	Rate    prwait.RateSource
	Entries prwait.EntryFinder
}

PRWaitSources are what a pull request wait reads.

type Server

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

Server is devctl serve's MCP server.

func New

func New(config Config) *Server

New returns the server of config with its tools registered.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler is the streamable HTTP handler of the server, at every path. Sessions and listings need no grant, so a person who has not granted the App yet sees the tools; every tool call is refused without one.

func (*Server) MCP

func (s *Server) MCP() *server.MCPServer

MCP is the server's MCP server, for in-process clients.

type Sources

type Sources interface {
	PRWait(ctx context.Context, token string, transport http.RoundTripper) (PRWaitSources, error)
	PRMerge(ctx context.Context, token string, transport http.RoundTripper) (PRMergeSources, error)
	ReleaseWait(ctx context.Context, token string, transport http.RoundTripper) (*releasewait.Sources, error)
	ReleasePromote(ctx context.Context, token string, transport http.RoundTripper) (*releasepromote.Sources, error)
}

Sources build the clients of one call from the person's token; the requests go through transport.

type Users added in v8.154.1

type Users interface {
	User(ctx context.Context, token string) (Caller, error)
}

Users answer the GitHub user a token of the App acts as.

Jump to

Keyboard shortcuts

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