registry

package
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package registry provides a thread-safe, ordered collection of LLM tools for use in agent dispatch loops.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Registry

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

Registry holds a named collection of model.Tool objects for an agent loop.

Storing model.Tool (the minimal interface) keeps the registry decoupled from the execution layer. Callers that need to execute a tool type-assert to handler.ExecutableTool at dispatch time:

tool, ok := reg.ByName(call.Name)
exec, ok := tool.(handler.ExecutableTool)
result, err := exec.Execute(ctx, call.Arguments)

Registry is safe for concurrent use: reads (All, ByName, Names) hold a read lock; writes (Add) hold a write lock.

Typical usage:

reg := registry.New(myTool)
req.Tools = reg.All()
tool, ok := reg.ByName(call.Name)

func New

func New(t ...model.Tool) *Registry

New creates a Registry pre-populated with the given tools.

Example
package main

import (
	"context"
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/handler"
	"github.com/v8tix/mcp-toolkit/v2/registry"
)

type greetArgs struct {
	Name string `json:"name" description:"Name to greet."`
}

func greetTool(name, desc string) handler.ExecutableTool {
	return handler.NewTool(name, desc,
		func(_ context.Context, in greetArgs) (string, error) {
			return "hello, " + in.Name, nil
		},
	)
}

func main() {
	reg := registry.New(
		greetTool("greet", "Greet someone."),
		greetTool("farewell", "Say goodbye."),
	)

	fmt.Println(reg.Names())
}
Output:
[greet farewell]

func (*Registry) Add

func (r *Registry) Add(t ...model.Tool) *Registry

Add registers one or more tools and returns the Registry for method chaining. Panics if any tool's Definition().Name is empty — an empty name is always a programmer error: the LLM API rejects tools without a name, and a nameless tool cannot be dispatched by ByName.

Example
package main

import (
	"context"
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/handler"
	"github.com/v8tix/mcp-toolkit/v2/registry"
)

type greetArgs struct {
	Name string `json:"name" description:"Name to greet."`
}

func greetTool(name, desc string) handler.ExecutableTool {
	return handler.NewTool(name, desc,
		func(_ context.Context, in greetArgs) (string, error) {
			return "hello, " + in.Name, nil
		},
	)
}

func main() {
	reg := registry.New(greetTool("greet", "Greet someone."))
	reg.Add(greetTool("farewell", "Say goodbye."))

	fmt.Println(reg.Names())
}
Output:
[greet farewell]

func (*Registry) All

func (r *Registry) All() []*sdkmcp.Tool

All returns the tool definitions of every registered tool in insertion order. Pass this slice directly to the tools field of an LLM chat-completion request. Returns a freshly allocated slice; mutations do not affect the registry.

func (*Registry) ByName

func (r *Registry) ByName(name string) (model.Tool, bool)

ByName looks up a tool by its name and returns the model.Tool. Returns the tool and true if found, nil and false otherwise. Callers that need execution should type-assert to handler.ExecutableTool.

Example
package main

import (
	"context"
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/handler"
	"github.com/v8tix/mcp-toolkit/v2/registry"
)

type greetArgs struct {
	Name string `json:"name" description:"Name to greet."`
}

func greetTool(name, desc string) handler.ExecutableTool {
	return handler.NewTool(name, desc,
		func(_ context.Context, in greetArgs) (string, error) {
			return "hello, " + in.Name, nil
		},
	)
}

func main() {
	reg := registry.New(greetTool("greet", "Greet someone."))

	t, ok := reg.ByName("greet")
	fmt.Println(ok)
	fmt.Println(t.Definition().Name)
}
Output:
true
greet

func (*Registry) Filter

func (r *Registry) Filter(fn func(model.Tool) bool) *Registry

Filter returns a new Registry containing only the tools for which fn returns true. The original registry is not modified.

exec := reg.Filter(func(t model.Tool) bool {
    _, ok := t.(handler.ExecutableTool)
    return ok
})
Example
package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/v8tix/mcp-toolkit/v2/handler"
	"github.com/v8tix/mcp-toolkit/v2/model"
	"github.com/v8tix/mcp-toolkit/v2/registry"
)

type greetArgs struct {
	Name string `json:"name" description:"Name to greet."`
}

func greetTool(name, desc string) handler.ExecutableTool {
	return handler.NewTool(name, desc,
		func(_ context.Context, in greetArgs) (string, error) {
			return "hello, " + in.Name, nil
		},
	)
}

func main() {
	reg := registry.New(
		greetTool("public_greet", "Public."),
		greetTool("internal_sync", "Internal."),
		greetTool("public_farewell", "Public."),
	)

	public := reg.Filter(func(t model.Tool) bool {
		return !strings.HasPrefix(t.Definition().Name, "internal_")
	})

	fmt.Println(public.Names())
	fmt.Println(reg.Names()) // original unchanged
}
Output:
[public_greet public_farewell]
[public_greet internal_sync public_farewell]

func (*Registry) Names

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

Names returns all registered tool names in insertion order.

func (*Registry) Remove

func (r *Registry) Remove(name string) bool

Remove removes the tool with the given name from the registry. Returns true if a tool was removed, false if no tool had that name.

Example
package main

import (
	"context"
	"fmt"

	"github.com/v8tix/mcp-toolkit/v2/handler"
	"github.com/v8tix/mcp-toolkit/v2/registry"
)

type greetArgs struct {
	Name string `json:"name" description:"Name to greet."`
}

func greetTool(name, desc string) handler.ExecutableTool {
	return handler.NewTool(name, desc,
		func(_ context.Context, in greetArgs) (string, error) {
			return "hello, " + in.Name, nil
		},
	)
}

func main() {
	reg := registry.New(
		greetTool("greet", "Greet someone."),
		greetTool("farewell", "Say goodbye."),
	)

	removed := reg.Remove("greet")
	fmt.Println(removed)
	fmt.Println(reg.Names())
}
Output:
true
[farewell]

Jump to

Keyboard shortcuts

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