Skip to main content
Glama
kioie

tiny-go-mcp-server

by kioie

Tiny Go MCP Server

CI Go Reference Go Report Card tiny-go-mcp-server MCP server

A lightweight Model Context Protocol (MCP) toolkit for Go. Build spec-compliant MCP servers (stdio, streamable HTTP, legacy SSE) with tools, resources, and prompts — minimal boilerplate and automatic JSON Schema from Go structs.

Built on the official modelcontextprotocol/go-sdk.

Requirements: Go 1.26+ (download).


Why Tiny?

Tiny Go MCP Server

Full frameworks

Goal

Thin helper on official go-sdk + tiny static binary

Full MCP feature surface

Deps

Official go-sdk only

Varies

Binary

~5MB stripped, no runtime on host

Often larger stacks

Schemas

Inferred from struct tags

Manual or builder APIs

Use this project as a library (tinymcp package) or as a starting template (cmd/tiny-go-mcp).

When to use what

tinymcp (this repo)

mcp-go

go-sdk alone

Best for

Thin helper on go-sdk, tiny binary

Rich helpers, large ecosystem

Full control, no extra layer

Schema

Struct tags → auto JSON Schema

Builder APIs / helpers

AddTool + generics yourself

Transport

stdio (Start()), streamable HTTP (StartHTTP), legacy SSE (StartSSE)

stdio, SSE, HTTP, …

All transports

Deps

go-sdk only

Standalone module

go-sdk only

Choose tinymcp when you want the official protocol implementation with minimal boilerplate and a small static server binary.

Philosophy

tinymcp is a thin helper on the official go-sdk — not a replacement for it.

We reduce setup and transport boilerplate (server creation, registration error handling, stdio/HTTP/SSE, TextResult, deploy examples). The protocol implementation, generics, and schema inference still come from modelcontextprotocol/go-sdk.

That means handler code uses both imports — and that is intentional:

import (
    "github.com/kioie/tiny-go-mcp-server/tinymcp"
    "github.com/modelcontextprotocol/go-sdk/mcp" // handler types, prompts, resources, advanced APIs
)

Use tinymcp for

Use go-sdk (mcp) for

NewServer, RegisterTool, transports

Handler signatures (CallToolRequest, GetPromptRequest, …)

Safe registration (errors, not panics)

Tool annotations, elicitation, custom protocol features

TextResult, HTTP middleware helpers

Anything via server.RawServer()

We are not aiming for a non-leaky facade that hides the SDK. If you need full control, call RawServer() or use go-sdk directly — same underlying server, no lock-in.

tinymcp vs raw go-sdk

Same protocol implementation — tinymcp removes repetitive setup. Handler code still imports mcp for request types in both cases.

go-sdk alone (minimal stdio server):

server := mcp.NewServer(&mcp.Implementation{Name: "my-mcp", Version: "1.0.0"}, nil)
mcp.AddTool(server, &mcp.Tool{
    Name:        "greet",
    Description: "Greet someone by name",
}, greet)
if err := server.Run(context.Background(), &mcp.StdioTransport{}); err != nil {
    log.Fatal(err)
}

tinymcp (same tool, less boilerplate):

s := tinymcp.NewServer("my-mcp", "1.0.0")
if err := tinymcp.RegisterTool(s, "greet", "Greet someone by name", greet); err != nil {
    log.Fatal(err)
}
log.Fatal(s.Start())

tinymcp adds

Still on go-sdk (mcp)

NewServer(name, ver)

Handler signatures (CallToolRequest, prompts, resources)

RegisterTool + struct-tag JSON Schema

Tool annotations via RegisterToolDef + mcp.Tool

Safe registration errors (no panics)

Advanced session / event-store APIs

Start() / StartHTTP() / HTTP middleware

Full control via RawServer()

Use go-sdk alone when you want zero wrapper. Use tinymcp when you want less setup while staying on the official implementation.

Transport

Method

API

Typical clients

stdio (default)

Start()

Cursor, Claude Desktop, Windsurf (local subprocess)

Streamable HTTP

StartHTTP(addr, opts) or StreamableHTTPHandler

Remote MCP clients, gateways, browser tools

Legacy SSE

StartSSE(addr, opts) or SSEHandler

Older clients on MCP 2024-11-05 SSE transport

Start() runs stdio (stdin/stdout) — what most local AI clients expect.

For HTTP/SSE, tinymcp wraps the official go-sdk handlers with minimal options:

// Streamable HTTP on loopback (stateless demo — no GET/SSE or server→client RPC)
log.Fatal(server.StartHTTP("127.0.0.1:8080", &tinymcp.HTTPOptions{Stateless: true}))

// Or mount on your own mux (auth, TLS, path prefix)
handler, _ := tinymcp.StreamableHTTPHandler(server, nil)
http.Handle("/mcp", handler)

Stateless mode (Stateless: true) is the default in examples: one POST JSON-RPC per request, no long-lived SSE GET stream, and no server-initiated messages. Omit it or use session options when you need full streamable HTTP sessions — see docs/HTTP.md.

See docs/HTTP.md and examples/http. To host for Smithery URL listing (no Docker for end users), use examples/http-deploy. For advanced session routing or event stores, use server.RawServer() with the go-sdk directly.


Related MCP server: MCP Playground Server

Quick start (library)

Step-by-step guide: docs/QUICKSTART.md. AI codegen: SYSTEM_PROMPT.md.

go get github.com/kioie/tiny-go-mcp-server/tinymcp@latest
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/kioie/tiny-go-mcp-server/tinymcp"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

type greetArgs struct {
	Name string `json:"name" jsonschema:"Person to greet"`
}

func main() {
	s := tinymcp.NewServer("my-mcp", "1.0.0")
	if err := tinymcp.RegisterTool(s, "greet", "Greet someone by name", greet); err != nil {
		log.Fatal(err)
	}
	log.Fatal(s.Start())
}

func greet(_ context.Context, _ *mcp.CallToolRequest, args greetArgs) (*mcp.CallToolResult, any, error) {
	return tinymcp.TextResult(fmt.Sprintf("Hello, %s!", args.Name)), nil, nil
}

See examples/minimal for a runnable copy-paste example.

Scaffold a new server

Requires tagged module template/ (v1.1.1+) for stdio, or template-http/ for streamable HTTP:

go install golang.org/x/tools/cmd/gonew@latest
gonew github.com/kioie/tiny-go-mcp-server/template@latest example.com/my-mcp my-mcp
cd my-mcp && go run .

# HTTP deploy (Smithery / Fly / Render):
gonew github.com/kioie/tiny-go-mcp-server/template-http@latest example.com/my-mcp-http my-mcp-http
cd my-mcp-http && go run .

Or copy examples/minimal, template/, or template-http/ directly.


Install the example server

Both install paths produce a binary named tiny-go-mcp:

# Installs to $(go env GOPATH)/bin/tiny-go-mcp
go install github.com/kioie/tiny-go-mcp-server/cmd/tiny-go-mcp@latest

Or build from source (binary in the repo root):

git clone https://github.com/kioie/tiny-go-mcp-server.git
cd tiny-go-mcp-server
make release   # → ./tiny-go-mcp

Method

Binary name

Typical path

go install …/cmd/tiny-go-mcp

tiny-go-mcp

$(go env GOPATH)/bin/tiny-go-mcp

make build / make release

tiny-go-mcp

./tiny-go-mcp in the repo

make install

tiny-go-mcp

$(go env GOPATH)/bin/tiny-go-mcp

Example tools (reference server)

These tools exist for MCP integration demos, not production logic. Agents should compute math and write greetings in-chat unless they are explicitly testing tool calls.

Tool

When to use

When not to / alternative

Arguments

add

Test that the client can call an addition tool

Real arithmetic → compute locally or use a calculator MCP

a, b

subtract

Test subtraction wiring (use instead of add for subtraction tests)

Real arithmetic → compute locally

a, b

greet

Test a text-returning tool (use instead of add/subtract for messaging demos)

User-facing hello → reply in the conversation

name (required), greeting (optional)


Connect AI clients

MCP servers communicate over stdio. Point your client at the compiled binary path.

Template config: examples/mcp-client-config.json (copy and set the absolute path to tiny-go-mcp).

Logging: The protocol uses stdin/stdout. Server logs (if any) go to stderr only. Set TINY_GO_MCP_VERBOSE=1 on the server process to enable startup log lines.

Cursor

Settings → Features → MCP → Add server:

  • Name: tiny-go-mcp

  • Type: stdio

  • Command: /absolute/path/to/tiny-go-mcp

Or add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "tiny-go-mcp": {
      "command": "/absolute/path/to/tiny-go-mcp"
    }
  }
}

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "tiny-go-mcp": {
      "command": "/absolute/path/to/tiny-go-mcp"
    }
  }
}

Windsurf / Zed / other stdio clients

Use the same shape: command = absolute path to tiny-go-mcp, transport = stdio. Refer to your client’s MCP docs for the config file location.

Tips for LLM-friendly tools

  • Use clear tool names (snake_case) and descriptions that say when to use, when not to, and which sibling tool applies — models pick tools from these and often have overlapping options.

  • Add jsonschema tags on struct fields so argument docs appear in the schema.

  • Return human-readable text via tinymcp.TextResult for predictable client display.

  • See AGENTS.md for conventions when extending this repo with AI assistants.


Resources and prompts

Register read-only context and reusable prompt templates alongside tools:

if err := tinymcp.RegisterTextResource(server, "file:///info", "info", "Server metadata", "text/plain", "…"); err != nil {
	log.Fatal(err)
}
if err := tinymcp.RegisterPrompt(server, "code_review", "Review code", []*mcp.PromptArgument{
	{Name: "code", Required: true},
}, func(_ context.Context, req *mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
	code := req.Params.Arguments["code"]
	if code == "" {
		return nil, tinymcp.RequiredPromptArgument("code")
	}
	return tinymcp.PromptResult("Review", tinymcp.UserPromptMessage("Review:\n"+code)), nil
}); err != nil {
	log.Fatal(err)
}

Runnable example: examples/resources. For dynamic URI templates use RegisterResourceTemplate.


Package API

server := tinymcp.NewServer("name", "version")
tinymcp.NewServer("name", "version", tinymcp.WithInstructions("…")) // optional SDK config
tinymcp.NewServerWithOptions("name", "version", &mcp.ServerOptions{…})
tinymcp.RegisterTool(server, name, description, handler)     // typed handler, auto schema
tinymcp.RegisterTextResource(server, uri, name, desc, mime, text)
tinymcp.RegisterPrompt(server, name, desc, args, handler)
server.Start()                                              // stdio transport
server.StartHTTP(":8080", &tinymcp.HTTPOptions{})         // streamable HTTP
server.StartSSE(":8080", nil)                             // legacy SSE
tinymcp.StreamableHTTPHandler(server, nil)                // mount on custom http.Server
tinymcp.TextResult("message")                               // tool text helper
tinymcp.TextResource(uri, mime, text)                       // resource read helper
tinymcp.PromptResult(desc, tinymcp.UserPromptMessage("…")) // prompt helper
server.RawServer()                                          // escape hatch to go-sdk

// v1.2+: panic-at-startup registration or errors.Is sentinels
tinymcp.MustRegisterTool(server, name, description, handler)
errors.Is(err, tinymcp.ErrNilServer)                        // ErrNilTool, ErrNilHandler, ErrRegistrationFailed
opts := (&tinymcp.HTTPOptions{Stateless: true}).WithMiddleware(requestLogger)
tinymcp.ListenAndServeHTTPContext(ctx, addr, handler)       // graceful shutdown; also StartHTTPContext / StartSSEContext

Documentation: pkg.go.dev/github.com/kioie/tiny-go-mcp-server/tinymcp. Upgrading from v1.1.x: docs/MIGRATION-v1.2.md.


Development

Command

Description

make test

Run tests with race detector

make lint

golangci-lint

make lint-tools

Validate MCP tool descriptions in reference servers

make coverage

Coverage report

make build

Dev binary ./tiny-go-mcp

make release

Stripped static binary

make install

go install$(go env GOPATH)/bin/tiny-go-mcp

Smaller binaries (~1.8MB)

After make release, optionally pack with UPX:

upx --best --lzma tiny-go-mcp

Project structure

tinymcp/              # Library package
cmd/tiny-go-mcp/      # Reference MCP server
template/             # gonew stdio scaffold
template-http/        # gonew streamable HTTP deploy scaffold
examples/minimal/     # Minimal stdio example
examples/http/        # Streamable HTTP example
examples/http-deploy/ # Deployable HTTP + Smithery URL listing (server card, Render/Fly)
examples/resources/   # Resources + prompts example
examples/mcp-client-config.json  # Cursor/Claude-style template
scripts/lint-tools/   # MCP tool description linter (make lint-tools)
docs/                 # Guides — see below
server.json           # MCP Registry metadata (publish with mcp-publisher)
CHANGELOG.md          # Release history
SYSTEM_PROMPT.md      # Agent-facing API summary for codegen
.github/workflows/    # CI, lint, CodeQL, releases

Key docs in docs/:

Doc

Purpose

QUICKSTART.md

Step-by-step library setup

HTTP.md

stdio vs streamable HTTP vs legacy SSE

STABILITY.md

Public API stability policy

MIGRATION-v1.2.md

Upgrade guide from v1.1.x

TLS.md

HTTPS via reverse proxy or Go

LOCALHOST-PROTECTION.md

DNS rebinding security advisory

DISCOVERY.md

Registries and visibility

GLAMA.md

Glama hosting

SMITHERY.md

Smithery URL and MCPB listings


Releases

Tag a semver version (e.g. v1.2.0) to publish stable go get versions and trigger GitHub Releases with cross-platform binaries and multi-arch GHCR images. Release history: CHANGELOG.md. Public API stability: docs/STABILITY.md. Agent-facing API summary: SYSTEM_PROMPT.md. Upgrading from v1.1.x: docs/MIGRATION-v1.2.md.

git tag v1.2.0
git push origin v1.2.0

Discovery and registries

See docs/DISCOVERY.md for MCP Registry (server.json), awesome lists, and community directories. Listing copy and launch posts: docs/SUBMISSIONS.md. For Glama hosting with Docker, see docs/GLAMA.md.

Contributing

See CONTRIBUTING.md. For AI codegen outside this repo, see SYSTEM_PROMPT.md. CI runs tests, lint, and CodeQL; Dependabot keeps Go and Actions dependencies updated.

License

MIT — see LICENSE.

Available Tools

3 tools
addA

Demo: adds two integers. Use only to test MCP addition calls; do not use for real math—compute in the agent instead. Use add (not subtract or greet) when verifying addition wiring.

ParametersJSON Schema
NameRequiredDescriptionDefault
aYesThe first number to add
bYesThe second number to add

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It states the tool adds integers, which is accurate for a demo tool. While it doesn't mention edge cases like overflow, the simplicity of the operation makes it largely transparent. The description adds value beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core action, and every word serves a purpose. No unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple demo tool with two integer parameters and a clear output (sum), the description is fully sufficient. No output schema is needed as the return type is straightforward.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with both parameters 'a' and 'b' already described as 'The first number to add' and 'The second number to add' respectively. The description does not add additional meaning beyond what the schema provides, so baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'adds two integers' with a specific verb and resource. It also explicitly differentiates from sibling tools 'subtract' and 'greet', making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use only to test MCP addition calls; do not use for real math—compute in the agent instead. Use add (not subtract or greet) when verifying addition wiring.' This provides clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

greetA

Demo: returns a greeting string. Use only to test MCP text tools; do not use for user-facing messages—reply in chat instead. Use greet (not add or subtract) for hello/welcome integration tests.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesThe name of the person to greet
greetingNoAn optional custom greeting phrase like 'Welcome'

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It states it returns a greeting string, which is sufficient for a simple demo tool. No mention of side effects or additional behavior, but not needed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose and usage, no extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple demo tool with two parameters and no output schema, the description covers purpose, usage, and sibling differentiation completely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline 3. Description adds context about the purpose but no deeper parameter semantics beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description explicitly states it returns a greeting string ('returns a greeting string') and differentiates from siblings by specifying 'use greet (not add or subtract) for hello/welcome integration tests'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly states when to use ('only to test MCP text tools') and when not to ('do not use for user-facing messages—reply in chat instead'), plus gives sibling alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subtractA

Demo: subtracts B from A. Use only to test MCP subtraction calls; do not use for real math—compute in the agent instead. Use subtract (not add or greet) when verifying subtraction wiring.

ParametersJSON Schema
NameRequiredDescriptionDefault
aYesThe number to subtract from
bYesThe amount to subtract

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so full burden falls on description. Description labels it as a 'Demo' and restricts use to testing, implying safety, but does not explicitly state side effects, authentication, or limits. For a simple arithmetic operation, the disclosure is adequate but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with front-loaded purpose and critical usage constraints. Every sentence adds value; no extraneous text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given low complexity (two integers, no output schema), the description covers purpose, usage constraints, and alternatives. It does not explicitly state the return value, but this is inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with clear descriptions for both parameters. The description 'subtracts B from A' restates the order, adding no new semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'subtracts' and the resource 'B from A', and explicitly distinguishes from siblings by naming 'add' and 'greet'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('only to test MCP subtraction calls') and when not to use ('do not use for real math'), and names alternatives ('Use subtract (not add or greet)').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 3 tool updatesv1.1.3
    • Addedadd
    • Addedgreet
    • Addedsubtract
  2. 3 tool updatesv1.1.0
    • Removedadd
    • Removedgreet
    • Removedsubtract
  3. 3 tool updatesv0.1.0
    • First observedadd
    • First observedgreet
    • First observedsubtract

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct function (addition, subtraction, greeting) and descriptions explicitly guide differentiation and testing scenarios.

Naming Consistency5/5

All tool names are single lowercase verbs, following a consistent pattern.

Tool Count5/5

3 tools is appropriate for a simple demo/testing server, covering core operations without excess.

Completeness4/5

The set covers basic arithmetic and greeting for demo purposes; minor gaps like multiplication exist but are unnecessary for the stated goal.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Provides intelligent command completion, validation, and contextual help for the Kafka Docker Playground CLI. Integrates with GitHub Copilot to offer auto-complete suggestions, detailed command assistance, and debugging support for playground operations.
    3
    -
  • A
    license
    A
    quality
    B
    maintenance
    Go MCP server for multi-format document access — PDF, TXT, MD, DOCX, CSV, images. 12 tools including OCR, search, table extraction, and URL fetch. Single binary, no runtime.
    26
    13
    10
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A simple toolkit for creating MCP servers with stdio and SSE transport, auto-validating tools via Pydantic.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kioie/tiny-go-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server