agents-go

Model context protocol (MCP)

MCP is an open protocol for exposing tools (and other capabilities) to LLM applications. The mcp package connects an agent to MCP servers over the official Go SDK: each server tool becomes a function tool the model can call.

Connecting a server

import (
	"os/exec"

	"github.com/zzir/agents-go/mcp"
)

// stdio: launch the server as a subprocess
fsServer, err := mcp.NewStdioServer(ctx, "filesystem",
	exec.Command("npx", "-y", "@modelcontextprotocol/server-filesystem", dir),
	mcp.Options{})
if err != nil {  }
defer fsServer.Close()

agent := &agents.Agent{
	Name:       "file assistant",
	MCPServers: []agents.MCPServer{fsServer},
}

Transports:

Constructor Transport
mcp.NewStdioServer(ctx, name, cmd, opts) Subprocess over stdio
mcp.NewStreamableHTTPServer(ctx, name, endpoint, opts) Streamable HTTP
mcp.NewSSEServer(ctx, name, endpoint, opts) Server-sent events (deprecated — use streamable HTTP)
mcp.NewWithTransport(ctx, name, transport, opts) Anything implementing the go-sdk Transport (e.g. in-memory for tests)

The agent lists each server’s tools at the start of every turn, so servers may add or remove tools between turns.

Options

mcp.Options{
	AllowedTools: []string{"read_file", "list_directory"}, // expose only these
	BlockedTools: []string{"delete_file"},                 // hide these
	Strict:       true,                                    // normalize schemas to OpenAI strict mode
	ClientName:   "my-app", ClientVersion: "1.2.0",        // reported to the server

	CacheToolsList: true,            // cache list_tools across turns
	ToolNamePrefix: "github_",       // avoid name clashes between servers
	ToolFilter: func(ctx context.Context, rc *agents.RunContext, agent *agents.Agent, name string) bool {
		return rc.Context != nil // expose tools only in some run contexts
	},
	RequireApproval: func(name string) bool { return name == "delete_file" }, // HITL
	OAuthHandler: authHandler, // OAuth 2.1 authorization (streamable HTTP only)
}

OAuth

The mcp package supports OAuth 2.1 for streamable HTTP servers via the go-sdk’s auth package. Set Options.OAuthHandler to an auth.OAuthHandler implementation — the built-in auth.NewAuthorizationCodeHandler covers the standard authorization code + PKCE flow with optional dynamic client registration:

import "github.com/modelcontextprotocol/go-sdk/auth"

handler, _ := auth.NewAuthorizationCodeHandler(&auth.AuthorizationCodeHandlerConfig{
	RedirectURL:              "http://localhost:3142",
	AuthorizationCodeFetcher: myFetcher, // opens browser, waits for redirect
})

srv, _ := mcp.NewStreamableHTTPServer(ctx, "my-server", endpoint, mcp.Options{
	OAuthHandler: handler,
})

The agents-server web UI handles this automatically: configure a server with Authentication → OAuth, and the Connect button will open an authorization popup when needed.

Prompts and resources

A Server also exposes the MCP prompt and resource endpoints directly (they are not agent tools — call them yourself, e.g. to seed instructions from a server-managed prompt):

prompts, _ := server.ListPrompts(ctx, nil)
p, _ := server.GetPrompt(ctx, &mcpsdk.GetPromptParams{Name: "code_review", Arguments: map[string]string{"lang": "go"}})
// p.Messages -> turn into agent instructions or input

resources, _ := server.ListResources(ctx, nil)
r, _ := server.ReadResource(ctx, &mcpsdk.ReadResourceParams{URI: "file:///README.md"})
// r.Contents -> inject as context

Behavior

Not modeled: provider-hosted MCP (OpenAI’s server-side MCP tool), per the SDK’s no-hosted-tools stance.