Reference / Go SDK
Reference

Go SDK

github.com/wakeshift/wakeshift-go/appkit, for Go 1.27 or later, on the official MCP Go SDK (github.com/modelcontextprotocol/go-sdk). It has the same calls as the TypeScript SDK, in Go's style. During the beta it comes with your invite.

Go
import "github.com/wakeshift/wakeshift-go/appkit"

The app

Go
wake, err := appkit.FromKey(os.Getenv("WAKESHIFT_KEY"), os.Getenv("WAKESHIFT_CORE"), "https://ci-bot.example/mcp")

FromKey takes your app key (wst_test_<app>_<seed>), the address of the console it came from, and your MCP endpoint's URL.

Events

Define each event once, at startup. Its arguments and payload are Go types; their JSON Schemas come from the types (field names from json tags, descriptions from jsonschema tags).

Go
type repoArgs struct {
	Owner  string `json:"owner" jsonschema:"The repo's owner, lowercase: acme"`
	Repo   string `json:"repo" jsonschema:"The repo's name, lowercase: api"`
	Branch string `json:"branch,omitempty" jsonschema:"Only this branch"`
}
type ciRun struct {
	Branch     string `json:"branch"`
	Conclusion string `json:"conclusion"`
	Name       string `json:"name"`
	URL        string `json:"url"`
}

ciFinished, err := appkit.DefineEvent(wake, "ci.finished", appkit.EventDef[repoArgs, ciRun]{
	Description: "CI finished on a GitHub repo",
	Authorize: func(ctx context.Context, s appkit.Subscriber, a repoArgs) bool {
		return canSeeRepo(s.User, a.Owner+"/"+a.Repo)
	},
	Text: func(r ciRun, a repoArgs) string {
		return "CI " + r.Conclusion + " on " + a.Owner + "/" + a.Repo + " " + r.Branch + ": " + r.Name
	},
})

Serve the events on your MCP endpoint, after its authentication:

Go
events := wake.ServeEvents(srv, appkit.EventsOptions{User: func(ti *auth.TokenInfo) string { return ti.UserID }})
mux.Handle("/mcp", requireAuth(events(mcpHandler)))

When CI finishes, emit it:

Go
_, err = ciFinished.Emit(ctx, repoArgs{Owner: "acme", Repo: "api"},
	ciRun{Branch: "main", Conclusion: "failure", Name: "tests", URL: runURL},
	appkit.WithID(deliveryID))
Call What it does
appkit.DefineEvent(wake, name, appkit.EventDef[A, P]{…}) Defines an event. Description and Text are required; Authorize(ctx, subscriber, args) decides who may subscribe; Personal: true makes it a personal event. Define every event before ServeEvents.
wake.ServeEvents(srv, appkit.EventsOptions{User, Agent}) Returns the middleware that serves MCP Events for clients that speak it, and adds subscribe_events, unsubscribe_events and list_subscriptions to srv. User is your ID for the person behind a request. Agent is for apps whose users sign in with Wakeshift.
event.Emit(ctx, args, payload, opts…) Sends an occurrence to everyone subscribed with those routing arguments. appkit.To(user) names the one subscriber of a personal event; appkit.WithID(id) makes retries emit once.
event.PublishURL(ctx, args, opts…) A URL that emits the event with those arguments (appkit.To(user) for a personal event): each POST's body is the payload, checked against the schema. wake.RevokePublishURL(ctx, id) turns it off. See emit from a webhook.
event.Subscribe(ctx, call, args) Subscribes the conversation calling one of your own tools. Build call with in.Args.Call(req, user) from a tool whose input embeds appkit.Args.
event.Unsubscribe(ctx, call, args), event.End(ctx, user, id) End the caller's subscription with those arguments, or one of a user's subscriptions by its ID.

The tools' wording and the events/list output are the same as the TypeScript and Python SDKs', word for word.

Topics

Topics are what events are built on. wake.Subscribe(ctx, call, topic, opts), wake.Publish, wake.Send, wake.PublishURL, wake.Unsubscribe, wake.UnsubscribeUser and wake.ForgetUser work as their TypeScript counterparts do. A tool that subscribes embeds appkit.Args in its input, for the arguments Wakeshift needs from the agent.

Sign-in

  • Your own accounts: pass your ID for the person as User in EventsOptions and as user in Args.Call.
  • Guests, no sign-up: appkit.GuestAuth signs MCP clients in with nothing to click. guests.Routes(mux) serves the sign-in endpoints; guests.Verify(token) checks a bearer token and returns the guest. See guest sign-in.
  • Wakeshift accounts: wake.Verify checks an access token from Sign in with Wakeshift; Exchange acts for that person's agent, within their consent.

Examples

Agent Chat, Secret Agent, Nightfall and Slackline are built on this SDK; their source is in wakeshift/apps.