Skip to main content
Glama
sarmakska

mcp-server-toolkit

by sarmakska

mcp-server-toolkit

The batteries-included starter for production Model Context Protocol servers.

CI License: MIT Language Last commit Python MCP

MCP became the default integration layer for agents, and most reference servers are still toys: a single tool, no auth, no observability. This toolkit is the opinionated alternative that ships an MCP 1.0 compliant server with the plumbing already wired in. Write a tool once and reach it over stdio for a local agent and over streamable HTTP for a remote one, with the same handler, schema validation, auth, rate limiting, and tracing on every call.

Built by Sarma Linux.


Architecture

graph TD
  Client[MCP client<br/>desktop / IDE / remote agent]
  Client -->|stdio JSON-RPC| Stdio[stdio transport]
  Client -->|streamable HTTP| HTTP[FastAPI HTTP transport]
  HTTP --> Auth[auth: API key / OAuth 2.1<br/>+ per-client rate limit]
  Stdio --> Proto[MCP protocol dispatch<br/>initialize / tools.list / tools.call]
  Auth --> Proto
  Proto --> Reg[tool registry<br/>schema validation + spans]
  Reg --> P1[plugin: filesystem]
  Reg --> P2[plugin: sarmalink]
  Reg --> P3[your plugins]
  Reg -->|OTLP| OTEL[OpenTelemetry collector]
  P2 -->|api.sarmalink.ai| SLAI[SarmaLink-AI]

  classDef ext fill:#a78bfa,stroke:#a78bfa,color:#fff
  class SLAI,OTEL ext

Related MCP server: FastMCP Server Template

Quick start

git clone https://github.com/sarmakska/mcp-server-toolkit.git
cd mcp-server-toolkit
uv sync
cp .env.example .env
uv run mcp-toolkit run --transport stdio

That boots an MCP server over stdio with the bundled plugins registered. Point a desktop client or IDE at it (see the Quick-Start wiki page), or drive it by hand:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | uv run mcp-toolkit run --transport stdio

For remote use, switch to HTTP and call the MCP endpoint:

uv run mcp-toolkit run --transport http --port 8000
curl -s localhost:8000/mcp -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Send several calls in one round trip with a JSON-RPC 2.0 batch (an array). The response is an array in the same order, with notifications omitted:

curl -s localhost:8000/mcp -d '[
  {"jsonrpc":"2.0","id":1,"method":"ping"},
  {"jsonrpc":"2.0","id":2,"method":"tools/list"}
]'

What is in the box

  • MCP 1.0 compliant. Full initialize handshake with protocol version negotiation (2025-06-18, 2025-03-26, 2024-11-05), notifications/initialized, ping, tools/list, and tools/call with content blocks and structured results. The protocol layer is shared, so both transports behave identically.

  • Two transports, one code path. stdio (JSON-RPC 2.0) for local agents, streamable HTTP (FastAPI) at POST /mcp for remote deployment. A tool written once is reachable over both. Both accept JSON-RPC 2.0 batches: send an array of messages and get an array of responses back, dispatched concurrently, with notifications omitted per the spec.

  • Auth built in. API key (constant-time comparison) or OAuth 2.1 bearer tokens validated against the issuer's JWKS with issuer and audience checks, selected by MCP_AUTH. A mcp-toolkit login command runs the OAuth 2.1 PKCE flow to obtain a token against a hosted server.

  • Schema validation. The registry derives a JSON Schema from each handler's type hints and validates every call's arguments against it. Declare an output_schema and the return value is validated too, then surfaced as MCP structuredContent.

  • Per-client rate limiting. Token bucket keyed by client identity, configurable with MCP_RATE_LIMIT_RPS.

  • Span export. Every tool call runs inside an OpenTelemetry span with name, argument count, duration, and error type. Set an OTLP endpoint and spans export; otherwise structured JSON logs still flow to stderr.

  • Two example plugins. A sandboxed filesystem plugin and a sarmalink plugin that wraps an external API end to end.

  • Container image. Reproducible uv-based multi-stage build that runs as a non-root user with a health check.

Plugin authoring

A plugin is a Python module that registers handlers with @registry.tool. The input schema comes from the type hints.

from mcp_toolkit.registry import registry

@registry.tool("search_docs", description="Search internal docs")
async def search_docs(query: str, limit: int = 10) -> dict:
    return {"results": [...]}

query is required (no default) and typed as a string; limit is optional and typed as an integer. The generated schema reflects both. See Plugin-Authoring.

Configuration

Env var

Purpose

Default

MCP_TRANSPORT

stdio or http

stdio

MCP_HTTP_HOST / MCP_HTTP_PORT

HTTP bind address

0.0.0.0:8000

MCP_AUTH

none, api_key, oauth

none

MCP_API_KEY

key for api_key mode

unset

MCP_OAUTH_ISSUER / MCP_OAUTH_AUDIENCE

OAuth resource server checks

unset

MCP_OAUTH_JWKS_URI

explicit JWKS endpoint (else discovered)

unset

MCP_RATE_LIMIT_RPS / MCP_RATE_LIMIT_BURST

per-client rate limit

0 (off)

MCP_FS_ROOT

filesystem plugin sandbox root

~/mcp-data

MCP_OTEL_ENDPOINT

OTLP collector URL for span export

unset

MCP_SARMALINK_API_KEY

key for the sarmalink plugin

unset

All settings use the MCP_ prefix and can be supplied via a .env file. See .env.example.

Deployment

docker build -t mcp-toolkit .
docker run -p 8000:8000 --env-file .env mcp-toolkit

The image runs the HTTP transport as a non-root user with a built-in health check. Front it with TLS termination (your platform's load balancer, or Caddy on a VPS). See Deployment.

When to use this, when not to

Use this when you are building an MCP server that needs to ship: you want auth, schema validation, tracing, rate limiting, and both transports without writing the plumbing, and you want the same plugin code to run locally over stdio and in production over HTTP. It suits internal tool gateways, remote MCP servers for a team, and bridges that wrap an existing API as MCP tools.

Do not reach for this if you only need a throwaway single-tool stdio server for one local agent, where the reference SDK example is lighter. It is also not a managed product: you host and operate it yourself.

Documentation

Full docs live in the wiki: architecture, quick start, plugin authoring, auth modes, observability, and deployment. The bundled sarmalink plugin is a working end-to-end example of a tool that calls an external API. See also ARCHITECTURE.md, ROADMAP.md, and CHANGELOG.md.

License

MIT. Built by Sarma Linux.


More open source by Sarma

Part of a portfolio of twelve production-shaped open-source repositories built and maintained by Sarma.

Repository

What it is

Sarmalink-ai

Multi-provider OpenAI-compatible AI gateway with 14-engine failover and intent-based plugin auto-routing

agent-orchestrator

Durable multi-agent workflows in TypeScript with deterministic replay and Inspector UI

voice-agent-starter

Sub-second full-duplex voice agent loop. WebRTC, mediasoup, pluggable STT / LLM / TTS

ai-eval-runner

Evals as code. Python, DuckDB, FastAPI viewer, regression mode for CI

mcp-server-toolkit

Production Model Context Protocol server starter (Python / FastAPI)

local-llm-router

OpenAI-compatible proxy that routes to Ollama or cloud providers based on policy

rag-over-pdf

Minimal end-to-end RAG starter for PDF corpora

receipt-scanner

Vision OCR for receipts with Zod-validated JSON output

webhook-to-email

Webhook receiver that forwards events to email via Resend

k8s-ops-toolkit

Helm chart for shipping Next.js to Kubernetes with full observability stack

terraform-stack

Vercel + Supabase + Cloudflare + DigitalOcean modules in one Terraform repo

staff-portal

Open-source HR / ops portal: leave, attendance, expenses, kiosk mode

Engineering essays at sarmalinux.com/blog · All projects at sarmalinux.com/open-source

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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/sarmakska/mcp-server-toolkit'

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