agentmcp

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package agentmcp bridges tools from Model Context Protocol servers into the agent runtime using the official Go MCP SDK.

Connect owns one initialized MCP client session. Tools returns an immutable snapshot suitable for agent.WithTools, while Session exposes the official SDK session for prompts, resources, completions, and other MCP features. Tool-list change signals tell applications when to obtain a new snapshot and construct the next Agent; an already-running Agent is never mutated.

Registry composes several connected Clients into atomic, versioned catalog entries. It is deliberately pull-based: it neither reconnects transports nor starts goroutines, so applications retain credential and scheduling policy.

Remote tool metadata is untrusted. Use agent.WithBeforeTool to enforce application policy or human approval, and only wrap a returned tool with agent.Parallel after independently establishing that concurrent calls are safe.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client owns an initialized official MCP client session and adapts its tools for the agent runtime. Its methods are safe for concurrent use.

func Connect

func Connect(
	ctx context.Context,
	implementation *mcp.Implementation,
	transport mcp.Transport,
	options ...Option,
) (*Client, error)

Connect initializes an MCP client over transport. Any official SDK transport is supported, including CommandTransport for stdio and StreamableClientTransport for HTTP. The returned Client owns the session and must be closed.

Example (Stdio)
ctx := context.Background()
transport := &mcp.CommandTransport{Command: exec.CommandContext(ctx, "my-mcp-server")}

client, err := agentmcp.Connect(
	ctx,
	&mcp.Implementation{Name: "pips-runtime", Version: "v0.1.0"},
	transport,
	agentmcp.WithToolNamePrefix("workspace"),
)
if err != nil {
	log.Print(err)

	return
}
defer func() {
	if err := client.Close(); err != nil {
		log.Print(err)
	}
}()

tools, err := client.Tools(ctx)
if err != nil {
	log.Print(err)

	return
}

fmt.Println(len(tools)) // Pass tools to agent.WithTools.

func (*Client) Close

func (c *Client) Close() error

Close closes the official SDK session. It is idempotent and concurrency safe.

func (*Client) Session

func (c *Client) Session() *mcp.ClientSession

Session returns the initialized official SDK session. The caller may use it for prompts, resources, completions, logging, and other MCP capabilities. Close the owning Client rather than closing this session separately.

func (*Client) ToolListChanged

func (c *Client) ToolListChanged() <-chan struct{}

ToolListChanged returns a coalescing signal for notifications/tools/list_changed. On receipt, call Tools to obtain a fresh snapshot for the next Agent. The channel is not closed by Close.

func (*Client) Tools

func (c *Client) Tools(ctx context.Context) ([]agent.Tool, error)

Tools lists all remote tools across MCP pagination and returns an immutable agent tool snapshot. The operation rejects the entire snapshot on malformed definitions, mapped-name collisions, or the configured tool limit.

type Option

type Option func(*config) error

Option configures Connect.

func WithClientOptions

func WithClientOptions(options *mcp.ClientOptions) Option

WithClientOptions supplies official SDK client capabilities and handlers. The value is shallow-copied. Do not mutate referenced capability maps after calling Connect. Progress and tool-list handlers are chained after the bridge's internal handlers.

func WithMaxTools

func WithMaxTools(maxTools int) Option

WithMaxTools bounds the number of tools loaded from one server snapshot. The default is 256.

func WithToolNameMapper

func WithToolNameMapper(mapper ToolNameMapper) Option

WithToolNameMapper replaces the default portable-name mapping. The bridge still validates, prefixes, shortens, and collision-checks mapped names.

func WithToolNamePrefix

func WithToolNamePrefix(prefix string) Option

WithToolNamePrefix prefixes every advertised tool name. It is useful when combining tools from multiple MCP servers. Prefix must use the portable tool name character set and leave room for a separator and tool name.

type Registry

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

Registry builds atomic, versioned MCP tool snapshots from connected servers. Failed refreshes leave the previous snapshot untouched. It is safe for concurrent use and creates no goroutines; callers decide when to refresh and how to handle reconnection.

func NewRegistry

func NewRegistry(servers ...RegistryServer) (*Registry, error)

NewRegistry validates server identities and returns an empty registry.

func (*Registry) Changed

func (r *Registry) Changed() <-chan struct{}

Changed receives a coalesced signal after a materially changed successful refresh. It is not closed.

func (*Registry) Refresh

func (r *Registry) Refresh(ctx context.Context) (RegistrySnapshot, error)

Refresh obtains every configured server's tools and atomically installs the resulting catalog entries. On error it preserves the previous snapshot.

func (*Registry) RefreshChanged

func (r *Registry) RefreshChanged(ctx context.Context) (RegistrySnapshot, bool, error)

RefreshChanged consumes any pending source list-change notifications. When none are pending it returns the current snapshot and false. A true result means a refresh was attempted; callers still receive an error if any source failed, with the prior snapshot preserved.

func (*Registry) Snapshot

func (r *Registry) Snapshot() RegistrySnapshot

Snapshot returns the last successfully installed immutable snapshot.

type RegistryServer

type RegistryServer struct {
	ID     string
	Source RegistrySource
	Risk   catalog.Risk
}

RegistryServer identifies one connected MCP server and its policy risk.

type RegistrySnapshot

type RegistrySnapshot struct {
	Version   uint64
	UpdatedAt time.Time
	Entries   []catalog.Entry
}

RegistrySnapshot is an immutable point-in-time set of catalog entries. Version advances only after a complete, materially changed refresh.

type RegistrySource

type RegistrySource interface {
	Tools(context.Context) ([]agent.Tool, error)
	ToolListChanged() <-chan struct{}
}

RegistrySource is the narrow, pull-based MCP contract managed by a Registry. Client satisfies this interface. A Registry never reconnects or owns transports: applications retain credential, transport, and retry authority, then call Refresh when they choose.

type Tool

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

Tool adapts one remote MCP tool to agent.Tool. It is immutable and safe for concurrent use when the remote server supports concurrent calls. The bridge does not mark it parallel automatically because MCP annotations are untrusted hints.

func (*Tool) Decl

func (t *Tool) Decl() ai.Tool

Decl returns the portable declaration advertised to the language model.

func (*Tool) Exec

func (t *Tool) Exec(ctx context.Context, call agent.ToolCall) ([]ai.Part, error)

Exec forwards a tool call to the MCP server using the Agent's context. This propagates cancellation and tool deadlines through the official SDK.

func (*Tool) RemoteName

func (t *Tool) RemoteName() string

RemoteName returns the exact server-side MCP tool name.

type ToolError

type ToolError struct {
	RemoteName string
	Message    string
}

ToolError reports an MCP tool-level failure (`isError: true`). Protocol and transport failures remain wrapped SDK errors instead.

func (*ToolError) Error

func (e *ToolError) Error() string

Error implements error.

type ToolNameMapper

type ToolNameMapper func(remoteName string) (string, error)

ToolNameMapper maps an MCP server's tool name to the name advertised to the language model. The result must contain only ASCII letters, digits, underscores, or dashes. Names longer than 64 bytes are shortened deterministically after mapping and prefixing.

Jump to

Keyboard shortcuts

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