Skip to content

Register and invoke an operation

The registry owns operation descriptions and validates their schemas at construction. Supply application handlers and an explicit host policy. This example registers a status operation for a filtered local catalogue:

registry, err := mcp.New([]mcp.Operation{{
    Definition: mcp.Definition{
        Name: "project.status",
        Summary: "Inspect project status",
        Group: "projects",
        InputSchema: json.RawMessage(`{"type":"object"}`),
        OutputSchema: json.RawMessage(`{"type":"boolean"}`),
    },
    Handle: func(ctx context.Context, invocation *mcp.Invocation) (mcp.Outcome, error) {
        result, err := mcp.JSONResult(true, mcp.Text("Project is ready"))
        return mcp.Finish(result), err
    },
}}, mcp.WithPolicy(mcp.AllowRegistered()))
if err != nil {
    return err
}

Import context, encoding/json and gitlab.com/phpboyscout/go/mcp. A complete runnable example with a typed project identifier lives in registry_example_test.go; run go test -run ExampleNew ./... in the unreleased checkout.

Discover a concise summary, then inspect the operation when its full schema and documentation are needed:

page, err := registry.Search(ctx, mcp.SearchRequest{Query: "status"})
if err != nil {
    return err
}
definition, err := registry.Inspect(ctx, page.Operations[0].Name)

Applications must handle empty search results before indexing a page. The registered example has one visible matching operation. An empty query browses by name; a nonempty NextCursor continues the same query and group.

Invoke a known operation through the same gateway whether or not the caller searched first:

call, err := mcp.NewCall("project.status", json.RawMessage(`{}`))
if err != nil {
    return err
}
reply, callErr := registry.Invoke(ctx, call)
result, hasResult := reply.Result()

callErr is authoritative. A failed call may still have a valid result containing diagnostics. Do not discard that result solely because the call failed. A successful operation declaring an output schema must supply structured output.

AllowRegistered is an explicit local trust choice. For services, provide Policy.Authorize and Policy.ScopeKey using host identity in context. Discovery and execution are distinct decisions. Execution policy receives validated, canonical arguments and runs before application code. Inspection grants no later execution permission.

This example completes through Finish. See confirmation and resume to request form/URL input and the interaction reference for replay and progress. Protocol and Cobra adapters remain upcoming.