Go SDK for Anthropic Model Context Protocol
Several Software Development Kits (SDK) already exist for developing Model Context Protocol (MCP) servers in Typescript and Python.
However, the Go programming language presents a compelling alternative for creating robust and efficient MCP server implementations.
Go offers several key advantages that make it particularly well-suited for developing Model Context Protocol servers:
- Performance: Go is known for its high performance and efficient concurrency model, which is crucial for server-side applications.
- Simplicity: The language’s clean syntax and straightforward design make it easy to develop and maintain complex server infrastructures.
- Strong Typing: Go’s strong type system helps prevent runtime errors and ensures more reliable code.
- Compilation Speed: Quick compilation times enable faster development and iteration cycles.
In this document, I will provide a quick description of this SDK and illustrate how Go is particularly well-suited for this kind of development.
A Notion document retrieval server example
The code of the SDK is available at: https://github.com/llmcontext/gomcp
. This SDK is still at version 0.1.0
as the public APIs may still change.
You can find an example of a Go Application with the Go SDK at: https://github.com/llmcontext/mcpnotion
This application allows Claude to retrieve a Notion document identified by its pageId
.
A use case is to ask Claude to proofread a Notion page.
Note: you can find the caude for this example in github at: https://github.com/llmcontext/mcpnotion
Claude MCP server configuration
As described in my previous post, you bind your MCP server to Claude through the Application Support/Claude/claude_desktop_config.json
configuration file.
You can easily access this file from the Settings
menu in Claude:
The content of this file is something like this:
IMPORTANT: you need to restart Claude each time you change that file!
You can confirm in Claude that your MCP server is properly configured if you see it there:
If you click on that button you should see:
The first time Clause will call your function, a popup will ask you for permission:
You will also be able to see from Claude, the parameters and result from this call:
How to use the gomcp SDK
Install the SDK in your go project with:
The integration is done in 3 steps in your main function:
Step 1
The gomcp.NewModelContextProtocolServer()
call initialize and configure the SDK. You pass as a parameter the configuration file that is like this:
This file allows you to configure the logging of the server. As a reminder your server can never write on stdout as this is is the communication channel between Claude and your server.
The tools section of the configuration file is where you set the configuration parameter of each tools that your server is implementing.
Step 2
This is the step where you wire the tools you want to expose into the MCP server. See the next section for more information about that step.
Step 3
This is where you actually start the server. The server needs a transport mechanism used to communicate with Claude and right now only the stdin/stdout transport is supported.
Tools configuration
Let’s consider our Notion example again.
You have a function to read a notion document:
( code available here )
This function takes 3 parameters:
- the usual Go context. This context gives access to a logger integrated to the MCP server
- the Notion client, coming from a Notion SDK
- the pageId that, in the context of the MCP server, will be coming from the Claude application
Tool Context
The notion client needs to have access to a notion integration token to be allowed to read the content of the page: this parameter is set in the configuration file (see above).
To get that value you define a type:
This is where we see how Go is well suited for this kind of tool.
The type definition contains json
tags and jsonschema_description
tags.
Those tags allow us to generate a Json schema and validate at run time that the configuration data are matching what we expect: if the token is not provided or if there is a typo in the name of the property, or if there is an extra property in the configuration file, the MCP server won’t start.
The way you expose that configuration to the MCP server is by providing an initialization function:
This function will be called by the MCP server at startup time, with the actual data from the configuration file, and that function should return a tool specific context that will be used each time a tool function is called, indirectly, by the Claude application.
This tool specific context for this Notion example is used to store the Notion client:
Finally, you need to write the actual function that will do the job of retrieving a Notion page for Claude:
This function takes 4 parameters:
- the usual Go context. You see in the code how we can retrieve a logger from the context.
- the tool specific context: coming from the previous step
- the input parameters coming from Claude
- the output parameter is the mechanism that allows you to return data in the format suitable for the MCP protocol (see interface definition here)
One important part is to define how we retrieve parameters from Claude.
You do that by defining a type describing those parameters:
Using those tags, the MCP server is able to generate a schema that will be provided to Claude during the listing tools phase of the MCP protocol:
We now have 2 functions:
- the tool initialization function. Here
NotionToolInit
that instantiates the Notion client and makes it available in the tool context. - the tool function,
NotionGetPage
that does the actual job of retrieving the Notion page and returns it to Claude in the expected format.
The Go SDK allows you to have:
- multiple *tool providers *: your server could expose multiple set of functions, like functions to interact with Notion, and function that interacts with a local SQL database etc…
- each tool provider will have one or multiple functions
You declare those tool providers and their functions in the final step of the SDK integration:
That is the function called in step 2 described above.
That steps is the glue between the MCP server and your application code:
- the
DeclareToolProvider
gives a name to your provider: that name is the property that will be used to retrieve the configuration parameters from your configuration file. You also provide the initialization function to the SDK. - the
AddTool
is the way you add functions to the tool provider: you give the name that will be given to claude and a description of that function. Those are the parameters that will show up in the listing tools phase show above. You also provide the actual processing function.
Is Go a good language to implement a Model Context Protocol SDK?
The RegisterTools
function above show where Go is particularly well suited for the MCP protocol.
First, using interfaces you can expose a very small surface area to use the SDK (see code here):
That’s all there is to know API wise.
Another powerful feature of Golang are its reflection capabilities.
For instance, you add a tool to the SDK with:
The function is types as interface{}
(could be also the alias type any
).
That means you could actually give anything to that call, but the reflection capabilities of Go allow the Go SDK, at run time to check that (code here):
- the parameter is actually a function
- this function takes 4 parameters
- the first parameter is of the type
*context.Context
- the second parameter is a pointer to a struct and that this struct is of the type returned by the tool initialization function (the tool context)
- the third parameter is a pointer to a struct (the arguments of the function as used by Claude)
- the fourth parameter is of type
*types.ToolCallResult
, our interface to produce an output following the MCP protocol
Those checks provide very good developer experience as they ensure that if the code pass the initialization phase, you won’t have any runtime issue due to misconfiguration.
Another interesting feature of Go are the tag annotations.
For instance, during the analysis of the third parameter above, the introspection API allows the SDK to retrieve the schema of the expected parameters for that function. This schema will be used in the MSP protocol to provide the information when the tools are listed, but the SDK will also check at run time that, when called by Claude, the parameters match this schema.