Go SDK
The Go SDK is published at the module path github.com/backbay-labs/chio/packages/sdk/chio-go. Pure Go, CGO_ENABLED=0, no native dependencies. Context-aware throughout, designed to slot into any net/http server or HTTP client stack.
Module layout
auth, client, invariants, nested, session, transport, and version. Import only what you need.Installation
$ go get github.com/backbay-labs/chio/packages/sdk/chio-go@latestGo 1.23 is the minimum supported toolchain (see go.mod). The SDK builds cleanly on Linux, macOS, and Windows.
Separate chio-go-http SDK
github.com/backbay-labs/chio/sdks/go/chio-go-http for embedding chio as net/http middleware. It targets Go 1.21+ and is published under its own module path. See the net/http middleware section below.client.Client
client.Client is the top-level entry. Configure transport, authentication, and sensible defaults once, then reuse the client across goroutines. It is safe for concurrent use.
package main
import (
"context"
"log"
"net/http"
"github.com/backbay-labs/chio/packages/sdk/chio-go/client"
)
func main() {
c := client.WithStaticBearer(
"https://edge.example.com/mcp",
"dev-token",
http.DefaultClient,
)
ctx := context.Background()
sess, err := c.Initialize(ctx, client.InitializeOptions{})
if err != nil {
log.Fatal(err)
}
defer sess.Close(ctx)
}client.New is the lower-level form that takes an explicit auth.StaticBearer value:
import (
"github.com/backbay-labs/chio/packages/sdk/chio-go/auth"
"github.com/backbay-labs/chio/packages/sdk/chio-go/client"
)
c := client.New(
"https://edge.example.com/mcp",
auth.StaticBearerToken("dev-token"),
http.DefaultClient,
)session.Session
session.Session is the Streamable HTTP MCP surface. Every call accepts a context.Context so deadlines and cancellation propagate through the transport.
tools, err := sess.ListTools(ctx)
if err != nil {
return err
}
log.Printf("tools: %v", tools)
result, err := sess.CallTool(ctx, "read_file", map[string]any{
"path": "./README.md",
})
if err != nil {
return err
}
log.Printf("result: %v", result)Beyond the common MCP surface (ListTools, CallTool, ListResources, ReadResource, ListPrompts, GetPrompt), the session exposes Request, Notification, and SendEnvelope for custom JSON-RPC traffic.
transport.PostRPC
The transport package drives the underlying HTTP exchange. Use it directly when you need fine-grained control over retries, headers, or connection reuse. Every function takes a context.Context and an *http.Client.
import (
"net/http"
"github.com/backbay-labs/chio/packages/sdk/chio-go/transport"
)
exchange, err := transport.PostRPC(
ctx,
http.DefaultClient,
"https://edge.example.com/mcp",
authToken,
sessionID,
protocolVersion,
map[string]any{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": map[string]any{},
},
nil,
)
if err != nil {
return err
}
for _, msg := range exchange.Messages {
log.Printf("received: %v", msg["method"])
}
_, err = transport.DeleteSession(ctx, http.DefaultClient, "https://edge.example.com/mcp", authToken, sessionID)Authentication
The auth subpackage ships a static-bearer value plus helpers for the OAuth 2.1 authorization-code flow with PKCE. Feed the resulting token back into client.New or client.WithStaticBearer.
- Static bearer.
auth.StaticBearerToken(token)returns anauth.StaticBearerstruct carrying the token. - OAuth helpers.
auth.DiscoverOAuthMetadata,auth.PerformAuthorizationCodeFlow,auth.ExchangeAccessToken,auth.ResolveOAuthAccessToken,auth.PKCEChallenge.
import (
"net/http"
"github.com/backbay-labs/chio/packages/sdk/chio-go/auth"
"github.com/backbay-labs/chio/packages/sdk/chio-go/client"
)
// Dev: static bearer.
c := client.WithStaticBearer(
"https://edge.example.com/mcp",
"dev-token",
http.DefaultClient,
)
// Prod: run the OAuth flow then hand the resulting token to the client.
metadata, err := auth.DiscoverOAuthMetadata(ctx, http.DefaultClient, "https://edge.example.com", nil)
if err != nil {
return err
}
tokens, err := auth.PerformAuthorizationCodeFlow(ctx, http.DefaultClient, metadata, auth.AuthorizationCodeFlowOptions{
ClientID: "chio-cli",
RedirectURI: "http://127.0.0.1:53682/callback",
Scopes: []string{"chio.read", "chio.invoke"},
})
if err != nil {
return err
}
c2 := client.WithStaticBearer(
"https://edge.example.com/mcp",
tokens.AccessToken,
http.DefaultClient,
)
_ = c2Invariants Package
github.com/backbay-labs/chio/packages/sdk/chio-go/invariants mirrors the contract fixed by the Rust crate chio-binding-helpers. It implements canonical JSON, SHA-256, Ed25519 signing and verification, receipt and capability parsing and verification, and signed manifest verification.
package main
import (
"fmt"
"github.com/backbay-labs/chio/packages/sdk/chio-go/invariants"
)
func main() {
receipt, err := invariants.ParseReceiptJSON(receiptJSON)
if err != nil {
panic(err)
}
result, err := invariants.VerifyReceipt(receipt)
if err != nil {
panic(err)
}
fmt.Printf("signature valid: %v\n", result.SignatureValid)
fmt.Printf("parameter hash valid: %v\n", result.ParameterHashValid)
}Exported Functions
CanonicalizeJSONString(s string) (string, error)SHA256HexBytes(b []byte) string,SHA256HexUTF8(s string) stringSignUTF8MessageEd25519,VerifyUTF8MessageEd25519SignJSONStringEd25519,VerifyJSONStringSignatureEd25519ParseReceiptJSON,VerifyReceipt,VerifyReceiptJSONParseCapabilityJSON,VerifyCapability,VerifyCapabilityJSONParseSignedManifestJSON,VerifySignedManifest
Nested Callback Router
The nested subpackage ships a small router for mounting MCP nested callbacks (elicitation, sampling, roots/list) alongside an existing HTTP server, so a client can service server-initiated requests without standing up a dedicated listener.
DPoP, net/http middleware, and receipt-query client are planned
net/http middleware, or a Go receipt-query client. For HTTP middleware today, use the separate chio-go-http SDK linked below. The remaining helpers will land once the TS and Python surfaces stabilise.net/http Middleware (chio-go-http)
A separate standalone SDK at github.com/backbay-labs/chio/sdks/go/chio-go-http wraps any http.Handler, evaluates the incoming request against a chio sidecar, attaches the resulting receipt IDs to the response, and short-circuits with a structured JSON error on policy deny. It targets Go 1.21+ and is published under its own module path.
$ go get github.com/backbay-labs/chio/sdks/go/chio-go-http@latestErrors
Errors are sentinel values and typed structs you can match on with errors.Is or errors.As.
_, err := sess.CallTool(ctx, "read_file", args)
if err != nil {
log.Printf("call failed: %v", err)
}The current Go SDK returns wrapped error values from transport, JSON-RPC, and invariants helpers. Typed sentinel values and errors.As-friendly struct errors will ship alongside the HTTP middleware and DPoP subpackages.
Conformance
The Go SDK passes the cross-language conformance suite through wave 1 (remote-edge invariants) and wave 2 (transport plus session). The invariants package is byte-identical to the Rust reference for all canonical JSON, hashing, signing, and verification operations.
$ cd packages/sdk/chio-go && go test ./...
$ go test -tags conformance ./...