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

mcpserver

package
v8.151.0 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 27 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 subject of a call no verified caller made.

View Source
const DefaultInstallationsTTL = 5 * time.Minute

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

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 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 {
	// Subject is the token's sub, the person's stable identity at the
	// issuer.
	Subject string
	// Email is the token's email claim, when it carries one.
	Email string
}

Caller is the person a call is made for, as the ID token the gateway in front forwards names them (muster's forwardToken).

func CallerFrom

func CallerFrom(ctx context.Context) (Caller, bool)

CallerFrom is the caller of the call in ctx, if the server verified one.

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
	// 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
	// Verifier checks the ID token the gateway forwards on every request
	// and names the caller; nil verifies none, and every call is
	// anonymous.
	Verifier Verifier
	// 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 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 verified caller's subject (Anonymous without a verifier), the repository (owner/repo; empty for a tool that names none or an argument refused as usage) and the verdict. The caller's email is in the log line only.

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
	// 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 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; a grant_required auth_required without one, 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 OIDCVerifier

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

OIDCVerifier accepts an ID token its issuer signed for one of its audiences.

func NewOIDCVerifier

func NewOIDCVerifier(ctx context.Context, client *http.Client, issuer string, audiences []string) (*OIDCVerifier, error)

NewOIDCVerifier discovers issuer's signing keys through client (nil is http.DefaultClient) and accepts its ID tokens for any of audiences.

func NewStaticOIDCVerifier

func NewStaticOIDCVerifier(issuer string, keys oidc.KeySet, audiences []string) (*OIDCVerifier, error)

NewStaticOIDCVerifier accepts issuer's ID tokens signed by keys for any of audiences, with no discovery.

func (*OIDCVerifier) Verify

func (v *OIDCVerifier) Verify(ctx context.Context, rawIDToken string) (Caller, error)

Verify implements Verifier.

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. With a Verifier it refuses a request without an ID token it accepts.

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 Verifier

type Verifier interface {
	Verify(ctx context.Context, rawIDToken string) (Caller, error)
}

Verifier checks the bearer token of a call and names its caller.

Jump to

Keyboard shortcuts

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