# kioie/tiny-go-mcp-server [Health: Active]

**Category:** 🛠️ Other Tools and Integrations  
**Repository:** https://github.com/kioie/tiny-go-mcp-server  
**GitHub Stars:** 1  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/kioie-tiny-go-mcp-server

## Description
Minimal Go wrapper on the official modelcontextprotocol/go-sdk for stdio MCP servers: struct-tag JSON Schema inference, tinymcp library, reference binary tiny-go-mcp, 5MB static builds. For teams that want go-sdk compliance with minimal boilerplate (go get github.com/kioie/tiny-go-mcp-server/tinymcp@v1.0.0).

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "tiny-go-mcp-server": {
    "command": "npx",
    "args": ["-y","kioie-tiny-go-mcp-server"]
  }
}
```

## Documentation & README

<p align="center">
  <img src="https://raw.githubusercontent.com/kioie/tiny-go-mcp-server/HEAD/docs/assets/banner.png" alt="Tiny Go MCP Server — minimal Go MCP toolkit" width="720">
</p>

# Tiny Go MCP Server

[![CI](https://github.com/kioie/tiny-go-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/kioie/tiny-go-mcp-server/actions/workflows/ci.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/kioie/tiny-go-mcp-server/tinymcp.svg)](https://pkg.go.dev/github.com/kioie/tiny-go-mcp-server/tinymcp)
[![Go Report Card](https://goreportcard.com/badge/github.com/kioie/tiny-go-mcp-server/tinymcp)](https://goreportcard.com/report/github.com/kioie/tiny-go-mcp-server/tinymcp)
[![tiny-go-mcp-server MCP server](https://glama.ai/mcp/servers/kioie/tiny-go-mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/kioie/tiny-go-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`](https://github.com/modelcontextprotocol/go-sdk).

**Requirements:** Go 1.26+ ([download](https://go.dev/dl/)).

---

## 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](https://github.com/mark3labs/mcp-go)** | **[go-sdk](https://github.com/modelcontextprotocol/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`](https://github.com/modelcontextprotocol/go-sdk).

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

```go
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):

```go
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):

```go
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:

```go
// 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`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/HTTP.md).

See [`docs/HTTP.md`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/HTTP.md) and [`examples/http`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/examples/http). To host for [Smithery URL listing](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/SMITHERY.md) (no Docker for end users), use [`examples/http-deploy`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/examples/http-deploy). For advanced session routing or event stores, use `server.RawServer()` with the [go-sdk](https://github.com/modelcontextprotocol/go-sdk) directly.

---

## Quick start (library)

Step-by-step guide: [docs/QUICKSTART.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/QUICKSTART.md). AI codegen: [SYSTEM_PROMPT.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/SYSTEM_PROMPT.md).

```bash
go get github.com/kioie/tiny-go-mcp-server/tinymcp@latest
```

```go
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`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/examples/minimal) for a runnable copy-paste example.

### Scaffold a new server

Requires tagged module [`template/`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/template/) (v1.1.1+) for stdio, or [`template-http/`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/template-http/) for streamable HTTP:

```bash
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`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/examples/minimal), [`template/`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/template/), or [`template-http/`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/template-http/) directly.

---

## Install the example server

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

```bash
# 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):

```bash
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`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/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:

```json
{
  "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):

```json
{
  "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](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/AGENTS.md) for conventions when extending this repo with AI assistants.

---

## Resources and prompts

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

```go
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`](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/examples/resources). For dynamic URI templates use `RegisterResourceTemplate`.

---

## Package API

```go
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](https://pkg.go.dev/github.com/kioie/tiny-go-mcp-server/tinymcp). Upgrading from v1.1.x: [docs/MIGRATION-v1.2.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/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](https://upx.github.io/):

```bash
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](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/QUICKSTART.md) | Step-by-step library setup |
| [HTTP.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/HTTP.md) | stdio vs streamable HTTP vs legacy SSE |
| [STABILITY.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/STABILITY.md) | Public API stability policy |
| [MIGRATION-v1.2.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/MIGRATION-v1.2.md) | Upgrade guide from v1.1.x |
| [TLS.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/TLS.md) | HTTPS via reverse proxy or Go |
| [LOCALHOST-PROTECTION.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/LOCALHOST-PROTECTION.md) | DNS rebinding security advisory |
| [DISCOVERY.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/DISCOVERY.md) | Registries and visibility |
| [GLAMA.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/GLAMA.md) | Glama hosting |
| [SMITHERY.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/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](https://github.com/kioie/tiny-go-mcp-server/releases) with cross-platform binaries and multi-arch GHCR images. Release history: [CHANGELOG.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/CHANGELOG.md). Public API stability: [docs/STABILITY.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/STABILITY.md). Agent-facing API summary: [SYSTEM_PROMPT.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/SYSTEM_PROMPT.md). Upgrading from v1.1.x: [docs/MIGRATION-v1.2.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/MIGRATION-v1.2.md).

```bash
git tag v1.2.0
git push origin v1.2.0
```

## Discovery and registries

See [docs/DISCOVERY.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/DISCOVERY.md) for MCP Registry (`server.json`), awesome lists, and community directories. Listing copy and launch posts: [docs/SUBMISSIONS.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/SUBMISSIONS.md). For Glama hosting with Docker, see [docs/GLAMA.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/docs/GLAMA.md).

## Contributing

See [CONTRIBUTING.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/CONTRIBUTING.md). For AI codegen outside this repo, see [SYSTEM_PROMPT.md](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/SYSTEM_PROMPT.md). CI runs tests, lint, and CodeQL; Dependabot keeps Go and Actions dependencies updated.

## License

MIT — see [LICENSE](https://github.com/kioie/tiny-go-mcp-server/blob/HEAD/LICENSE).

