Skip to content

Latest commit

 

History

2,335 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcpkit

Production-grade MCP (Model Context Protocol) server and client library for Go.

Go Reference Go Report Card CI Conformance Coverage Release OpenSSF Scorecard Docs License GitHub stars

Docs site · Examples · Conformance report · Capabilities · Changelog · Quick Start

Quick Start

import (
    "time"

    "github.com/panyam/mcpkit/core"
    "github.com/panyam/mcpkit/server"
)

srv := server.NewServer(
    core.ServerInfo{Name: "my-server", Version: "0.1.0"},
    server.WithToolTimeout(30 * time.Second),
)

srv.RegisterTool(core.ToolDef{
    Name: "greet", Description: "Say hello",
    InputSchema: map[string]any{"type": "object", "properties": map[string]any{"name": map[string]any{"type": "string"}}},
}, func(ctx core.ToolContext, req core.ToolRequest) (core.ToolResponse, error) {
    var args struct{ Name string `json:"name"` }
    req.Bind(&args)
    return core.TextResult("Hello, " + args.Name + "!"), nil
})

srv.Run(":8787") // Streamable HTTP — blocks

Run blocks. When you start it in a goroutine, wait for Ready() instead of sleeping — it closes once the listener is bound and the port is accepting:

go srv.Run(":8787")
<-srv.Ready()
// safe to connect; srv.Addr() has the bound address (useful with ":0")

A client mirrors it. Every method that talks to the server takes a context:

ctx := context.Background()

c := client.NewClient("http://localhost:8787/mcp",
    core.ClientInfo{Name: "my-client", Version: "0.1.0"},
)
if err := c.Connect(ctx); err != nil { // bounds the handshake, not the session
    log.Fatal(err)
}
defer c.Close()

out, err := c.ToolCall(ctx, "greet", map[string]any{"name": "world"})

Packages

Package Import What
core github.com/panyam/mcpkit/core Protocol types (Request, ToolDef, Content, Claims) + tool-handler APIs (Sample, Elicit, EmitLog)
server github.com/panyam/mcpkit/server Server, Dispatcher, transports (SSE + Streamable HTTP), middleware
client github.com/panyam/mcpkit/client Client, HTTP/stdio/command transports, reconnection, logging
ext/auth github.com/panyam/mcpkit/ext/auth Separate module: JWT, PRM, OAuth discovery, DCR, CIMD
ext/ui github.com/panyam/mcpkit/ext/ui Separate module: MCP Apps extension (UIExtension, RegisterAppTool)
ext/tasks github.com/panyam/mcpkit/ext/tasks Separate module: SEP-2663 v2 tasks (long-running / async tool calls)
ext/otel github.com/panyam/mcpkit/ext/otel Separate module: SEP-414 OpenTelemetry tracing adapter
ext/skills github.com/panyam/mcpkit/ext/skills Separate module: SEP-2640 skills (data-only, served over resource primitives)
experimental/ext/events github.com/panyam/mcpkit/experimental/ext/events Separate module: MCP Events protocol (webhooks, polling, streaming)
testutil github.com/panyam/mcpkit/testutil TestClient wrapper for e2e tests

Conformance

mcpkit passes the official MCP conformance suite for the base protocol and the conformance scenarios for a long list of draft/recent SEPs — the "batteries" that set it apart from a minimal SDK:

Suite Spec Result
Server (base protocol) MCP 2025-11-25 30/30 scenarios
Auth MCP authorization 14/14 scenarios
MCP Apps ext-apps 21 tests
Tasks v1 (frozen) 26/27 (1 skipped — SDK-client limitation)
Tasks v2 SEP-2663 47/47 (upstream)
MRTR SEP-2322 3/3 negative (upstream)
Stateless wire SEP-2575 30/30 (upstream)
List-TTL SEP-2549 5/5
File-Inputs SEP-2356 (withdrawn upstream, see below) 7/7
Skills SEP-2640 fixture-driven
Keycloak interop 12/12

Tasks v2, MRTR, and the SEP-2575 stateless wire all run against modelcontextprotocol/conformance main directly (merged upstream). The full per-SEP rollup is published at panyam.github.io/mcpkit/conformance.

On SEP-2356: the working group closed it on 2026-06-26 in favour of SEP-2631 (File Objects and Transfer), which is still in draft. The file-input surface mcpkit ships and the scenarios above continue to work and are still exercised in CI; the row is kept so the behaviour stays covered, not as a claim of conformance to a live proposal. Migration to SEP-2631 is tracked in issue 827.

Three artifacts describe mcpkit's conformance posture at increasing granularity:

Testing

make is the supported task runner and the only one CI uses, so make is preinstalled everywhere and needs no setup step.

make test          # Unit tests (200+ across core/server/client)
make testall       # ALL tests + Keycloak + conformance + HTML report
make testconf      # MCP conformance suite
make testconfauth  # Auth conformance
make test-e2e      # E2E tests (auth + apps)
make test-apps-playwright  # ext-apps Playwright suite (needs Node.js)

Justfiles mirroring the same target names also exist and are kept as an experiment. They are not used by CI, and make is authoritative when the two disagree.

Documentation

Doc What
Examples gallery Runnable, batteries-included examples (auth, tasks, apps, tracing, events, skills) — each a guided two-terminal walkthrough. Source under examples/
CHANGELOG.md Release notes (Keep a Changelog / SemVer); fuller write-ups in docs/releases/
CONTRIBUTING.md How to build, test, and contribute
CLAUDE.md Quick reference: commands, package structure, gotchas
docs/ARCHITECTURE.md Transport design, type definitions, protocol details
docs/PROMPTS.md Prompts: arguments, content types, listing
docs/ELICITATION.md Elicitation: schemas, SEP-1034 defaults, enums, URL mode
docs/COMPLETIONS.md Argument completion for prompt arguments and resource URI templates
ext/auth/docs/DESIGN.md Auth architecture, spec compliance (C1-C23, X1-X5)
docs/APPS_DESIGN.md MCP Apps extension design, protocol flows, conformance strategy

Client Features

Subprocess MCP Servers

Spawn and manage subprocess MCP servers with CommandTransport:

c := client.NewClient("", info,
    client.WithCommandTransport("python", []string{"my_server.py"},
        client.WithEnv("DEBUG=1"),
        client.WithShutdownTimeout(10*time.Second),
    ),
    client.WithMaxRetries(3), // auto-restart on crash
)
c.Connect()
defer c.Close()

Custom Request Headers

Inject headers into all outgoing HTTP requests:

c := client.NewClient(url, info,
    client.WithModifyRequest(func(req *http.Request) {
        req.Header.Set("X-Tenant-ID", "acme")
        req.Header.Set("X-Request-ID", uuid.New().String())
    }),
)

Auth Performance

For best performance, configure your authorization server to use ES256 (ECDSA P-256) instead of RS256. ES256 verification is ~10x faster, with smaller keys and tokens. See auth design doc for details.

Dependencies

  • servicekit v0.1.3 — SSE hub, graceful shutdown, HTTP error types
  • oneauth v0.1.31 — JWT/OIDC (only via ext/auth sub-module)

Star History

Star History Chart

If mcpkit is useful to you, starring the repo is the cheapest way to help — it's the main signal we use to prioritize what to ship next.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages