inventory

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package inventory is a transport-agnostic, domain-agnostic registry for MCP tools, resources, and prompts. It groups them into toolsets and supports filtering (read-only, toolset selection, allow/deny lists, feature flags, arbitrary predicates) so that callers can assemble different surfaces — for example, per-persona presets — from a single flat manifest.

It is deliberately independent of any particular domain: tool dependencies are typed as `any` and resolved by the domain package (e.g. pkg/windows) which retrieves them from the request context. This mirrors the design of github-mcp-server's pkg/inventory.

Index

Constants

View Source
const (
	MCPMethodInitialize             = "initialize"
	MCPMethodToolsList              = "tools/list"
	MCPMethodToolsCall              = "tools/call"
	MCPMethodResourcesList          = "resources/list"
	MCPMethodResourcesRead          = "resources/read"
	MCPMethodResourcesTemplatesList = "resources/templates/list"
	MCPMethodPromptsList            = "prompts/list"
	MCPMethodPromptsGet             = "prompts/get"
)

MCP method constants for use with ForMCPRequest.

Variables

View Source
var ErrUnknownTools = errors.New("unknown tools specified in WithTools")

ErrUnknownTools is returned by Build when tools named via WithTools are not recognized.

Functions

This section is empty.

Types

type Builder

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

Builder assembles an Inventory. Configure it with the fluent With* methods, then call Build.

inv, err := NewBuilder().
    SetTools(AllTools()).
    WithReadOnly(true).
    WithToolsets([]string{"interaction", "system"}).
    Build()

func NewBuilder

func NewBuilder() *Builder

NewBuilder creates a Builder that defaults to the "default" toolset selection.

func (*Builder) Build

func (b *Builder) Build() (*Inventory, error)

Build produces the Inventory. It returns ErrUnknownTools if WithTools names a tool that does not exist (and is not a deprecated alias).

func (*Builder) SetFixedResources

func (b *Builder) SetFixedResources(resources []ServerResource) *Builder

SetFixedResources sets the fixed-URI resource manifest.

Separate from SetResources (which takes templates) because the MCP server keeps the two in disjoint collections: resources/list paginates only fixed resources. Registering templates alone yields an empty resources/list.

func (*Builder) SetPrompts

func (b *Builder) SetPrompts(prompts []ServerPrompt) *Builder

SetPrompts sets the prompt manifest.

func (*Builder) SetResources

func (b *Builder) SetResources(resources []ServerResourceTemplate) *Builder

SetResources sets the resource template manifest.

func (*Builder) SetTools

func (b *Builder) SetTools(tools []ServerTool) *Builder

SetTools sets the full tool manifest.

func (*Builder) WithDeprecatedAliases

func (b *Builder) WithDeprecatedAliases(aliases map[string]string) *Builder

WithDeprecatedAliases registers old→canonical tool name aliases.

func (*Builder) WithExcludeTools

func (b *Builder) WithExcludeTools(toolNames []string) *Builder

WithExcludeTools names tools to exclude regardless of other settings. This takes precedence over toolset and additional-tool selection.

func (*Builder) WithFeatureChecker

func (b *Builder) WithFeatureChecker(checker FeatureFlagChecker) *Builder

WithFeatureChecker sets the feature-flag checker. When non-nil, Build installs a feature-flag filter at the head of the pipeline so tools annotated with FeatureFlagEnable/Disable are gated. Resources and prompts use the same checker at their iteration sites.

func (*Builder) WithFilter

func (b *Builder) WithFilter(filter ToolFilter) *Builder

WithFilter appends an arbitrary predicate applied to every tool.

func (*Builder) WithReadOnly

func (b *Builder) WithReadOnly(readOnly bool) *Builder

WithReadOnly, when true, filters out any tool not annotated read-only.

func (*Builder) WithServerInstructions

func (b *Builder) WithServerInstructions() *Builder

WithServerInstructions enables aggregation of per-toolset instructions into the Inventory's Instructions string.

func (*Builder) WithTools

func (b *Builder) WithTools(toolNames []string) *Builder

WithTools names individual tools that bypass toolset filtering (they are included even if their toolset is disabled). Read-only and other filters still apply.

func (*Builder) WithToolsets

func (b *Builder) WithToolsets(toolsetIDs []string) *Builder

WithToolsets selects which toolsets to enable. Special keywords:

  • "all": enable every toolset
  • "default": expand to toolsets marked Default

Pass nil to use the default toolsets; pass an empty (non-nil) slice to enable none.

type FeatureFlagChecker

type FeatureFlagChecker func(ctx context.Context, flagName string) (bool, error)

FeatureFlagChecker reports whether a feature flag is enabled. The context may carry actor/request information used to evaluate the flag. On error the caller logs and treats the flag as disabled.

type HandlerFunc

type HandlerFunc func(deps any) mcp.ToolHandler

HandlerFunc generates an MCP tool handler from dependencies. Handlers are generated on demand at registration time so that ServerTool values can be passed around and filtered without materializing handlers. The deps parameter is typed as `any` to avoid a dependency from this generic package onto any concrete domain type. Context-based constructors ignore deps and retrieve dependencies from the request context instead.

type Inventory

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

Inventory holds a filtered view of tools, resources, and prompts. Build one with Builder.

func (*Inventory) AllTools

func (r *Inventory) AllTools() []ServerTool

AllTools returns all tools without filtering, sorted.

func (*Inventory) AvailablePrompts

func (r *Inventory) AvailablePrompts(ctx context.Context) []ServerPrompt

AvailablePrompts returns prompts passing the toolset and feature-flag filters, sorted.

func (*Inventory) AvailableResourceTemplates

func (r *Inventory) AvailableResourceTemplates(ctx context.Context) []ServerResourceTemplate

AvailableResourceTemplates returns resource templates passing the toolset and feature-flag filters, sorted.

func (*Inventory) AvailableResources

func (r *Inventory) AvailableResources(ctx context.Context) []ServerResource

AvailableResources returns fixed-URI resources passing the toolset and feature-flag filters, sorted.

Note the filter set is narrower than for tools: WithReadOnly, WithFilter, WithExcludeTools and the WithTools bypass all operate on *ServerTool and do not apply here. Resources are read-only by construction, so the absence of a read-only filter is intentional rather than an oversight.

func (*Inventory) AvailableTools

func (r *Inventory) AvailableTools(ctx context.Context) []ServerTool

AvailableTools returns the tools passing all filters, sorted by toolset ID then tool name for deterministic output.

func (*Inventory) AvailableToolsets

func (r *Inventory) AvailableToolsets(exclude ...ToolsetID) []ToolsetMetadata

AvailableToolsets returns the toolsets that contain at least one tool, sorted by ID. Pass toolset IDs to exclude from the result.

func (*Inventory) DefaultToolsetIDs

func (r *Inventory) DefaultToolsetIDs() []ToolsetID

DefaultToolsetIDs returns the IDs of toolsets marked Default, sorted.

func (*Inventory) EnabledToolsets

func (r *Inventory) EnabledToolsets() []ToolsetMetadata

EnabledToolsets returns the toolsets enabled under the current filters.

func (*Inventory) FindToolByName

func (r *Inventory) FindToolByName(toolName string) (*ServerTool, ToolsetID, error)

FindToolByName searches all tools (ignoring filters) for one with the given name.

func (*Inventory) ForMCPRequest

func (r *Inventory) ForMCPRequest(method string, itemName string) *Inventory

ForMCPRequest returns an Inventory trimmed to only the items relevant to a specific MCP request. This lets a server that builds a fresh instance per request register just the one tool a tools/call needs rather than the whole manifest. All existing filters still apply to the returned items.

func (*Inventory) HasToolset

func (r *Inventory) HasToolset(id ToolsetID) bool

HasToolset reports whether any tool/resource/prompt belongs to the toolset.

func (*Inventory) Instructions

func (r *Inventory) Instructions() string

Instructions returns the aggregated server instructions (empty unless WithServerInstructions was used).

func (*Inventory) RegisterAll

func (r *Inventory) RegisterAll(ctx context.Context, s *mcp.Server, deps any, middleware ...ToolHandlerMiddleware)

RegisterAll registers all available tools, resources, and prompts.

func (*Inventory) RegisterPrompts

func (r *Inventory) RegisterPrompts(ctx context.Context, s *mcp.Server)

RegisterPrompts registers all available prompts.

func (*Inventory) RegisterResourceTemplates

func (r *Inventory) RegisterResourceTemplates(ctx context.Context, s *mcp.Server, deps any)

RegisterResourceTemplates registers all available resource templates.

func (*Inventory) RegisterResources

func (r *Inventory) RegisterResources(ctx context.Context, s *mcp.Server, deps any)

RegisterResources registers all available fixed-URI resources. These are what resources/list returns; templates are listed separately by resources/templates/list.

func (*Inventory) RegisterTools

func (r *Inventory) RegisterTools(ctx context.Context, s *mcp.Server, deps any, middleware ...ToolHandlerMiddleware)

RegisterTools registers all available tools with the server.

func (*Inventory) ResolveToolAliases

func (r *Inventory) ResolveToolAliases(toolNames []string) (resolved []string, aliasesUsed map[string]string)

ResolveToolAliases resolves deprecated tool aliases to canonical names, logging a warning for each. Returns the resolved names and the map of aliases that were used.

func (*Inventory) ToolsetDescriptions

func (r *Inventory) ToolsetDescriptions() map[ToolsetID]string

ToolsetDescriptions maps toolset ID to description.

func (*Inventory) ToolsetIDs

func (r *Inventory) ToolsetIDs() []ToolsetID

ToolsetIDs returns all toolset IDs present in the manifest, sorted.

func (*Inventory) UnrecognizedToolsets

func (r *Inventory) UnrecognizedToolsets() []string

UnrecognizedToolsets returns toolset IDs requested via WithToolsets that do not match any registered toolset — useful for warning about typos.

type ResourceHandlerFunc

type ResourceHandlerFunc func(deps any) mcp.ResourceHandler

ResourceHandlerFunc generates an MCP resource handler from dependencies.

type ServerPrompt

type ServerPrompt struct {
	Prompt             mcp.Prompt
	Handler            mcp.PromptHandler
	Toolset            ToolsetMetadata
	FeatureFlagEnable  string
	FeatureFlagDisable []string
}

ServerPrompt pairs a prompt with its toolset metadata.

func NewServerPrompt

func NewServerPrompt(toolset ToolsetMetadata, prompt mcp.Prompt, handler mcp.PromptHandler) ServerPrompt

NewServerPrompt creates a ServerPrompt.

type ServerResource

type ServerResource struct {
	Resource           mcp.Resource
	HandlerFunc        ResourceHandlerFunc
	Toolset            ToolsetMetadata
	FeatureFlagEnable  string
	FeatureFlagDisable []string
}

ServerResource pairs a fixed-URI resource with its toolset metadata and a lazy handler generator.

This is distinct from ServerResourceTemplate on purpose. The MCP server keeps resources and resource templates in two disjoint collections: resources/list paginates only the former and resources/templates/list only the latter. A server that registers templates alone answers resources/read correctly but returns an *empty* resources/list, so a client that only lists sees nothing. Fixed-URI resources therefore need their own registration path.

func NewServerResource

func NewServerResource(toolset ToolsetMetadata, resource mcp.Resource, handlerFn ResourceHandlerFunc) ServerResource

NewServerResource creates a ServerResource.

func (*ServerResource) Handler

func (sr *ServerResource) Handler(deps any) mcp.ResourceHandler

Handler materializes the resource handler with the given dependencies.

func (*ServerResource) HasHandler

func (sr *ServerResource) HasHandler() bool

HasHandler reports whether the resource has a handler generator.

type ServerResourceTemplate

type ServerResourceTemplate struct {
	Template           mcp.ResourceTemplate
	HandlerFunc        ResourceHandlerFunc
	Toolset            ToolsetMetadata
	FeatureFlagEnable  string
	FeatureFlagDisable []string
}

ServerResourceTemplate pairs a resource template with its toolset metadata and a lazy handler generator.

func NewServerResourceTemplate

func NewServerResourceTemplate(toolset ToolsetMetadata, resourceTemplate mcp.ResourceTemplate, handlerFn ResourceHandlerFunc) ServerResourceTemplate

NewServerResourceTemplate creates a ServerResourceTemplate.

func (*ServerResourceTemplate) Handler

func (sr *ServerResourceTemplate) Handler(deps any) mcp.ResourceHandler

Handler materializes the resource handler with the given dependencies.

func (*ServerResourceTemplate) HasHandler

func (sr *ServerResourceTemplate) HasHandler() bool

HasHandler reports whether the resource has a handler generator.

type ServerTool

type ServerTool struct {
	// Tool is the MCP tool definition (name, description, schema, annotations).
	Tool mcp.Tool
	// Toolset records which toolset this tool belongs to.
	Toolset ToolsetMetadata
	// HandlerFunc generates the handler when given dependencies.
	HandlerFunc HandlerFunc

	// FeatureFlagEnable, if set, requires the named feature flag to be enabled
	// for the tool to be available.
	FeatureFlagEnable string
	// FeatureFlagDisable lists feature flags that, if any is enabled, omit this
	// tool.
	FeatureFlagDisable []string
	// Enabled, if set, is consulted at filter time to decide availability. A nil
	// Enabled means "enabled" (subject to the other filters). On error the tool
	// is treated as disabled.
	Enabled func(ctx context.Context) (bool, error)

	// RequiredScopes and AcceptedScopes are optional permission metadata for
	// tools. They are unused by the core filter pipeline but provide an
	// extension point for scope/permission-based filtering via WithFilter.
	RequiredScopes []string
	AcceptedScopes []string
}

ServerTool is an MCP tool paired with its toolset membership and a lazy handler generator, plus optional gating metadata.

func NewServerTool

func NewServerTool(tool mcp.Tool, toolset ToolsetMetadata, handler mcp.ToolHandler) ServerTool

NewServerTool creates a ServerTool from a raw mcp.ToolHandler that retrieves dependencies from the request context. Use this when the handler needs the raw request rather than typed, pre-unmarshaled arguments.

func NewServerToolWithContextHandler

func NewServerToolWithContextHandler[In any, Out any](tool mcp.Tool, toolset ToolsetMetadata, handler func(ctx context.Context, req *mcp.CallToolRequest, args In) (*mcp.CallToolResult, Out, error)) ServerTool

NewServerToolWithContextHandler creates a ServerTool whose typed handler retrieves dependencies from the request context (injected via middleware) rather than from a registration-time closure. The In value is unmarshaled from the raw call arguments; the Out value is currently ignored by this low-level constructor (domain helpers may use it for structured output).

This is the preferred constructor: it avoids allocating a closure per tool at registration time, which matters for servers that build a fresh instance per request.

func (*ServerTool) Handler

func (st *ServerTool) Handler(deps any) mcp.ToolHandler

Handler materializes the tool's handler with the given dependencies. It panics if HandlerFunc is nil — every registered tool must have a handler.

func (*ServerTool) HasHandler

func (st *ServerTool) HasHandler() bool

HasHandler reports whether the tool has a handler generator.

func (*ServerTool) IsReadOnly

func (st *ServerTool) IsReadOnly() bool

IsReadOnly reports whether the tool is annotated read-only.

func (*ServerTool) RegisterFunc

func (st *ServerTool) RegisterFunc(s *mcp.Server, deps any, middleware ...ToolHandlerMiddleware)

RegisterFunc registers the tool with the MCP server, wrapping the handler in the supplied middleware (first middleware = outermost). A shallow copy of the tool is registered so the original ServerTool is never mutated.

type ToolDoesNotExistError

type ToolDoesNotExistError struct {
	Name string
}

ToolDoesNotExistError is returned when a tool is not found.

func NewToolDoesNotExistError

func NewToolDoesNotExistError(name string) *ToolDoesNotExistError

NewToolDoesNotExistError creates a ToolDoesNotExistError.

func (*ToolDoesNotExistError) Error

func (e *ToolDoesNotExistError) Error() string

type ToolFilter

type ToolFilter func(ctx context.Context, tool *ServerTool) (bool, error)

ToolFilter decides whether a tool should be included. Returning false (or an error) excludes the tool.

type ToolHandlerMiddleware

type ToolHandlerMiddleware func(next mcp.ToolHandler) mcp.ToolHandler

ToolHandlerMiddleware wraps an MCP tool handler. Middleware is applied from last to first, so the first middleware passed to RegisterFunc executes closest to the transport (outermost).

type ToolsetDoesNotExistError

type ToolsetDoesNotExistError struct {
	Name string
}

ToolsetDoesNotExistError is returned when a toolset is not found.

func NewToolsetDoesNotExistError

func NewToolsetDoesNotExistError(name string) *ToolsetDoesNotExistError

NewToolsetDoesNotExistError creates a ToolsetDoesNotExistError.

func (*ToolsetDoesNotExistError) Error

func (e *ToolsetDoesNotExistError) Error() string

func (*ToolsetDoesNotExistError) Is

func (e *ToolsetDoesNotExistError) Is(target error) bool

type ToolsetID

type ToolsetID string

ToolsetID is a unique identifier for a toolset. A distinct type provides compile-time safety when passing toolset identifiers around.

type ToolsetMetadata

type ToolsetMetadata struct {
	// ID is the unique identifier for the toolset (e.g. "interaction", "system").
	ID ToolsetID
	// Description is a human-readable summary of the toolset.
	Description string
	// Default indicates the toolset is enabled when the caller asks for the
	// "default" configuration (or passes no explicit toolset selection).
	Default bool
	// Icon is an optional icon hint for UIs. It is metadata only.
	Icon string
	// InstructionsFunc, if set, returns server instructions contributed by this
	// toolset. It receives the built Inventory so it can consider what else is
	// enabled.
	InstructionsFunc func(inv *Inventory) string
}

ToolsetMetadata describes a toolset — a named group of related tools.

Jump to

Keyboard shortcuts

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