一个基于 Go 的 Model Context Protocol (MCP) 实现,可实现 LLM 应用程序与外部数据源和工具之间的无缝集成。
一个基于 Go 的 Model Context Protocol (MCP) 实现,可实现 LLM 应用程序与外部数据源和工具之间的无缝集成。
…
That's it!
MCP Go handles all the complex protocol details and server management, so you can focus on building great tools. It aims to be high-level and easy to use.
(*emphasis on aims)
️ MCP Go is under active development, as is the MCP specification itself. Core features are working but some advanced capabilities are still in progress.
go get github.com/mark3labs/mcp-go
Let's create a simple MCP server that exposes a calculator tool and some data:
…
The Model Context Protocol (MCP) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions.
MCP servers can:
mcp-go implements the Model Context Protocol specification version 2025-11-25, with backward compatibility for versions 2025-06-18, 2025-03-26, and 2024-11-05.
The server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:
// Create a basic server
s := server.NewMCPServer(
"My Server", // Server name
"1.0.0", // Version
)
// Start the server using stdio
if err := server.ServeStdio(s); err != nil {
log.Fatalf("Server error: %v", err)
}
Here's a simple example of a static resource:
…
And here's an example of a dynamic resource using a template:
…
The examples are simple but demonstrate the core concepts. Resources can be much more sophisticated - serving multiple contents, integrating with databases or external APIs, etc.
Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects. They're similar to POST endpoints in a REST API.
Task-augmented tools execute asynchronously and return results via polling. This is useful for long-running operations that would otherwise block or time out. Task tools support three modes:
…
Task execution flow:
tasks/result to retrieve the resultFor optional task tools, the same tool can be called synchronously (without task parameter) or asynchronously (with task parameter):
…
Limiting Concurrent Tasks
To prevent resource exhaustion, you can limit the number of concurrent running tasks:
s := server.NewMCPServer(
"Task Server",
"1.0.0",
server.WithTaskCapabilities(true, true, true),
server.WithMaxConcurrentTasks(10), // Allow up to 10 concurrent running tasks
)
When the limit is reached, new task creation requests will fail with an error. Completed, failed, or cancelled tasks don't count toward the limit - only tasks in "working" status. If WithMaxConcurrentTasks is not specified or set to 0, there is no limit on concurrent tasks.
For traditional synchronous tools that execute and return results immediately:
Simple calculation example:
…
HTTP request example:
…
Tools can be used for any kind of computation or side effect:
Each tool should:
Prompts are reusable templates that help LLMs interact with your server effectively. They're like "best practices" encoded into your server. Here are some examples:
…
Prompts can include:
For examples, see the examples/ directory.
Key examples include:
examples/task_tool/ - Demonstrates task-augmented tools with TaskSupportRequired and TaskSupportOptional modesexamples/structured_input_and_output/ - Shows how to use struct-based input/output schemas with type-safe tool handlersexamples/typed_tools/ - Demonstrates type-safe tool handlers with strongly-typed argumentsexamples/custom_context/ - Shows how to use custom contexts in tool handlersMCP-Go supports stdio, SSE and streamable-HTTP transport layers. For SSE transport, you can use SetConnectionLostHandler() to detect and handle disconnections for implementing reconnection logic.
StreamableHTTPServer is an http.Handler, so it can be mounted in any
router that speaks net/http. To embed it in a framework that does not
go through net/http (e.g. fasthttp
or fiber) without buffering the response through an
adaptor, use the transport-agnostic Handle entry point:
func (s *StreamableHTTPServer) Handle(w HTTPResponseWriter, r *HTTPRequest)
HTTPRequest is a plain struct (Method, URL, Header, Body,
Context) and HTTPResponseWriter is a small interface (Header,
WriteHeader, Write, Flush, CanStream). Implementations whose
underlying transport cannot stream MUST return false from CanStream;
the server will then reject GET (SSE listening) with 405 Method Not Allowed and keep POST responses as buffered application/json instead of
upgrading to text/event-stream.
See the HTTP transport docs
for a full fasthttp/fiber adapter example. ServeHTTP is unchanged and
remains the conventional net/http entry point.
Servers that require OAuth can advertise their authorization requirements
via the RFC 9728
/.well-known/oauth-protected-resource endpoint referenced by the
MCP authorization spec.
Use server.WithProtectedResourceMetadata (or
server.WithSSEProtectedResourceMetadata) to auto-mount the endpoint, or
server.NewProtectedResourceMetadataHandler to wire it into a custom router.
See the HTTP transport docs for examples.
httpServer := server.NewStreamableHTTPServer(mcpServer,
server.WithProtectedResourceMetadata(server.ProtectedResourceMetadataConfig{
Resource: "https://my-mcp-server.com",
AuthorizationServers: []string{"https://auth.example.com"},
ScopesSupported: []string{"mcp:read", "mcp:write"},
}),
)
Servers exposed to browser-based MCP clients can opt into Cross-Origin
Resource Sharing handling on either HTTP transport. CORS is disabled by
default; configure it explicitly via server.WithStreamableHTTPCORS or
server.WithSSECORS:
httpServer := server.NewStreamableHTTPServer(mcpServer,
server.WithEndpointPath("/mcp"),
server.WithStreamableHTTPCORS(
server.WithCORSAllowedOrigins("https://my-ai-app.com", "http://localhost:3000"),
server.WithCORSAllowCredentials(),
server.WithCORSMaxAge(300),
),
)
The transport answers preflight (OPTIONS) requests directly and decorates
simple responses with the appropriate Access-Control-Allow-Origin,
Access-Control-Allow-Credentials, Access-Control-Expose-Headers and
Vary headers. Sensible defaults are used when the corresponding option is
omitted (GET, POST, DELETE, OPTIONS for methods; Content-Type, Mcp-Session-Id, Last-Event-ID, Authorization for request headers;
Mcp-Session-Id for exposed headers). Combining WithCORSAllowedOrigins("*")
with WithCORSAllowCredentials() echoes the request Origin to remain
spec-compliant.
Both HTTP transports automatically protect local servers against
DNS rebinding attacks:
requests arriving over a loopback connection (127.0.0.1, [::1]) whose
Host header is not a localhost value are rejected with 403 Forbidden.
The check is derived from the connection's local address at runtime, so it
applies whether the server listens on localhost or 0.0.0.0, and never
affects requests arriving via non-loopback addresses.
If a reverse proxy on the same host forwards requests via localhost while
preserving the original Host header, configure the proxy to rewrite the
Host header to localhost, or opt out explicitly:
httpServer := server.NewStreamableHTTPServer(mcpServer,
// Or server.WithSSEDisableLocalhostProtection(true) on NewSSEServer.
server.WithDisableLocalhostProtection(true),
)
See the HTTP transport docs
for details, including the caveat for the framework-agnostic Handle entry
point.
MCP-Go provides a robust session management system that allows you to:
…
For more advanced use cases, you can implem
暂无开放 Issues,或尚未同步最近议题。