Documentation
¶
Overview ¶
Package tools registers the MCP tools. A handler validates its input, calls the service and returns the model; register decides everything every tool shares — annotations, gating, decoding, errors, the two halves of the reply and the log line — once.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AskFailures ¶
func AskFailures() mcp.Middleware
AskFailures is receiving middleware for a tools/call that asked the person and then failed as a JSON-RPC error rather than a tool result. On protocols before 2026-07-28 the SDK asks with elicitation/create itself, and a client that answers with an error, or an answer that does not fit the form, fails the whole call that way; that call wrote nothing, since its write waits for the answer, and it becomes [blocked]. A failure after the answer confirmed the write — the reply could not be built or sent, the request was canceled — may follow a write, so it becomes [ambiguous_outcome] and is never "nothing was written" (§4.5). The client's error text is not repeated.
func FullSurface ¶
FullSurface is the configuration under which every tool registers: the schema dump and the schema diff compare the whole registrable surface, so a gated tool is neither reported as new on every run nor lost without notice. It names every gate gate() consults, which TestFullSurfaceRegistersEverything holds.
func Register ¶
func Register(s *mcp.Server, d Deps) []service.Registered
Register adds every tool the configuration allows and returns what it registered, which it also tells the service, so get_me and resolve_url report the surface that exists. It adds interactionHint as well, which lists a tool that asks on every call without the mark to a client that can ask.
func RegisterResources ¶
RegisterResources adds the resource templates. Every one is a read, so every configuration has them.
Types ¶
type Deps ¶
type Deps struct {
Service *service.Service
Config config.Config
// Granted are the token's scopes, empty when unknown. A tool whose kind
// needs a scope the token lacks is not registered: a read_api token
// never gets a write tool, whatever the flags say (§9.4).
Granted []string
Logger *slog.Logger
// contains filtered or unexported fields
}
Deps are what the tools need.
type Kind ¶
type Kind int
Kind is what a tool does (docs/architecture.md §4.3). It is one field per tool rather than four, because it decides the annotations, whether the tool is registered at all, the scope it needs and whether a client is asked to put a person in the loop, and four rules kept by hand at sixty call sites is four ways to be quietly wrong at one of them (CLAUDE.md rule 14).
const ( // Read is every GET. Always registered. Read Kind = iota // Write changes something a person can edit back. Registered unless // read-only. Write // Ship is where a persuaded call becomes an effect: a merge, an // approval, a pipeline run. Registered only with // GITLAB_MCP_ENABLE_SHIP=true. Ship // Destructive deletes. Registered only with // GITLAB_MCP_ENABLE_DESTRUCTIVE=true, and refused per call without // confirm: true. Destructive )
The kinds.