tools

package
v1.4.1 Latest Latest
Warning

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

Go to latest
Published: May 3, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package tools holds the registered MCP tools and the registry primitives that wire them into the server.

Package tools provides the tool registry and handler types for the MCP server.

Index

Examples

Constants

View Source
const (
	ContentTypeAudio        = "audio"
	ContentTypeImage        = "image"
	ContentTypeResourceLink = "resource_link"
	ContentTypeText         = "text"
)

Content type constants for tool result content blocks.

View Source
const (
	// MaxInputLength is the maximum allowed length for any tool input string.
	MaxInputLength = 4096
)

Variables

This section is empty.

Functions

func Echo added in v0.3.0

func Echo(_ context.Context, input EchoInput) (EchoOutput, Result)

Echo returns the input message as a typed EchoOutput. The dispatch wrapper auto-marshals the non-zero Out into Result.StructuredContent — no legacy text content block is emitted. New tools should follow this single-surface pattern: clients read structuredContent, the typed schema teaches them how to parse it. If you need the legacy text path for a particular client, add a TextResult(...) explicitly via the returned Result; do not double-emit by default.

func Register

func Register[In, Out any](
	r *Registry,
	name, description string,
	handler func(ctx context.Context, input In) (Out, Result),
	opts ...Option,
) error

Register adds a tool to the registry. The generic type parameters describe the handler's typed input In and structured output Out:

  • Exported fields of In (with json tags) are reflected to build the JSON Schema returned in tools/list. Fields without an "omitempty" option and non-pointer types are marked as required.
  • Out drives the outputSchema advertised on the tool definition. Tools without meaningful structured output should use a small named typed wrapper rather than [any] or struct{} — concrete types document the contract and let the schema engine produce a stable shape.

The handler receives a typed In after the server unmarshals the raw JSON arguments and returns (Out, Result). The dispatch layer marshals a non-zero Out into Result.StructuredContent via encoding/json (v1) before the response leaves the server; zero-value Out (including nil pointer Out and a non-nil pointer to a zero struct) is skipped so omitempty stays honest. When the handler also sets Result.StructuredContent manually, the auto-marshaled Out wins — the Out-side path is the canonical surface; the manual escape hatch survives only as a no-op when Out is zero. When Result.IsError is true, the auto-marshal step is skipped entirely so error responses do not carry success-shaped structuredContent.

Register returns an error if a tool with the same name is already registered or if either the input or output type contains unsupported field types (channels, funcs, etc.). The registry is kept sorted alphabetically after each registration so that tools/list responses are deterministic.

The reflection-derived OutputSchema is set on the Tool BEFORE opts are applied, so WithOutputSchema (or any option that writes the same field) deliberately overrides the derived schema for callers who need a hand-authored shape.

Example

ExampleRegister shows the full tool-author workflow: define an input struct, register a handler, then verify it appears in the registry.

package main

import (
	"context"
	"fmt"

	"github.com/andygeiss/mcp/internal/tools"
)

func main() {
	type GreetInput struct {
		Name string `json:"name" description:"Who to greet"`
	}

	r := tools.NewRegistry()
	if err := tools.Register(r, "greet", "Says hello", func(_ context.Context, input GreetInput) (struct{}, tools.Result) {
		return struct{}{}, tools.TextResult("Hello, " + input.Name + "!")
	}); err != nil {
		fmt.Println("error:", err)
		return
	}

	t, ok := r.Lookup("greet")
	fmt.Println("found:", ok)
	fmt.Println("name:", t.Name)
	fmt.Println("schema type:", t.InputSchema.Type)

	all := r.Tools()
	fmt.Println("total tools:", len(all))
}
Output:
found: true
name: greet
schema type: object
total tools: 1

func ValidateInput added in v0.2.0

func ValidateInput(input string) error

ValidateInput checks a generic input string for security issues: null bytes, dangerous shell metacharacters, and length limits. Returns nil if safe.

func ValidatePath added in v0.2.0

func ValidatePath(path string) error

ValidatePath checks a path string for security issues: path traversal, null bytes, and length limits. Returns nil if the path is safe.

Types

type Annotations added in v0.3.0

type Annotations struct {
	DestructiveHint bool   `json:"destructiveHint,omitempty"`
	IdempotentHint  bool   `json:"idempotentHint,omitempty"`
	OpenWorldHint   bool   `json:"openWorldHint,omitempty"`
	ReadOnlyHint    bool   `json:"readOnlyHint,omitempty"`
	Title           string `json:"title,omitempty"`
}

Annotations describes optional behavioral hints for a tool, enabling MCP clients to make informed decisions before invocation.

type ContentBlock

type ContentBlock struct {
	Data     string `json:"data,omitempty"`
	MimeType string `json:"mimeType,omitempty"`
	Text     string `json:"text,omitempty"`
	Type     string `json:"type"`
	URI      string `json:"uri,omitempty"`
}

ContentBlock represents a single content item in a tool result. Text content uses [Text] and [Type]. Image and audio content use [Data], [MimeType], and [Type]. Resource links use [URI] and [Type].

type EchoInput added in v0.3.0

type EchoInput struct {
	// The description tag drives the JSON Schema the agent sees. A wrong
	// description produces a misused tool — the agent will call it for the
	// wrong reasons.
	Message string `json:"message" description:"The message to echo back"`
}

EchoInput defines the parameters for the echo tool. This file is the starter tool — the first point of contact for new scaffold-forkers. Use it as a copy-target for your own tools.

type EchoOutput added in v1.3.7

type EchoOutput struct {
	Echoed string `json:"echoed" description:"The message that was echoed back"`
}

EchoOutput is the structured output Echo returns. The reflection engine derives the tool's outputSchema from this type so clients can validate the structuredContent on the response without ad-hoc string parsing.

type Option added in v0.3.0

type Option func(*Tool)

Option configures a Tool during registration.

func WithAnnotations added in v0.3.0

func WithAnnotations(a Annotations) Option

WithAnnotations returns an Option that attaches behavioral hint annotations to a tool.

func WithOutputSchema added in v0.5.11

func WithOutputSchema(out schema.OutputSchema) Option

WithOutputSchema returns an Option that overrides the tool's outputSchema. Register derives the schema from the Out type parameter via reflection and sets it BEFORE applying options, so this option is the deliberate escape hatch for callers who need a hand-authored shape (e.g., a richer schema than reflection can express, or a stable wire shape decoupled from internal Out struct changes). When this option is not used, the reflection-derived schema is canonical.

func WithTitle added in v0.5.11

func WithTitle(title string) Option

WithTitle returns an Option that sets the tool's human-readable display name.

type Registry

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

Registry holds registered tools sorted alphabetically by name. Not safe for concurrent use — register all tools before starting the server.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty tool registry.

func (*Registry) Lookup

func (r *Registry) Lookup(name string) (Tool, bool)

Lookup finds a tool by name in O(1) via the index map.

func (*Registry) Names added in v0.2.0

func (r *Registry) Names() []string

Names returns the names of all registered tools in alphabetical order.

func (*Registry) Tools

func (r *Registry) Tools() []Tool

Tools returns a copy of all registered tools in alphabetical order.

type Result

type Result struct {
	Content           []ContentBlock  `json:"content"`
	IsError           bool            `json:"isError,omitempty"`
	StructuredContent json.RawMessage `json:"structuredContent,omitempty"`
}

Result represents the outcome of a tool handler invocation.

func ErrorResult

func ErrorResult(text string) Result

ErrorResult creates a Result indicating a tool execution failure.

func StructuredResult added in v0.5.11

func StructuredResult(text string, structured json.RawMessage) Result

StructuredResult creates a successful Result with both a human-readable text content block and machine-readable structured content. The structured JSON should conform to the tool's OutputSchema.

func TextResult

func TextResult(text string) Result

TextResult creates a successful Result with a text content block.

type Tool

type Tool struct {
	Annotations  *Annotations         `json:"annotations,omitempty"`
	Description  string               `json:"description"`
	Handler      toolHandler          `json:"-"`
	InputSchema  schema.InputSchema   `json:"inputSchema"`
	Name         string               `json:"name"`
	OutputSchema *schema.OutputSchema `json:"outputSchema,omitempty"`
	Title        string               `json:"title,omitempty"`
}

Tool represents a registered MCP tool with its handler.

Jump to

Keyboard shortcuts

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