Skip to content
Subako Docs
English
Esc
↑↓navigate↵open⌘Jpreview
On this page

Go

The Go SDK.

subako-function-sdk-go runs an MCP server written with the official MCP Go SDK as a Subako function package. Each tool you add becomes a function an agent can call. It needs Go 1.25 or newer.

Start a package

go run golang.org/x/tools/cmd/gonew@latest \
  github.com/subako-ai/subako-function-template-go example.com/orders

Or add the SDK to a module of your own:

go get github.com/modelcontextprotocol/go-sdk github.com/subako-ai/subako-function-sdk-go

Tools

package main

import (
	"context"
	"fmt"

	"github.com/modelcontextprotocol/go-sdk/mcp"
	subakofn "github.com/subako-ai/subako-function-sdk-go"
)

type LookupInput struct {
	Order int `json:"order" jsonschema:"the order's number, such as 1042"`
}

type Order struct {
	Status     string `json:"status"`
	TotalCents int    `json:"total_cents"`
}

func lookup(ctx context.Context, req *mcp.CallToolRequest, in LookupInput) (*mcp.CallToolResult, Order, error) {
	if in.Order <= 0 {
		return nil, Order{}, fmt.Errorf("order numbers start at 1")
	}
	return nil, Order{Status: "shipped", TotalCents: 12900}, nil
}

func main() {
	server := mcp.NewServer(&mcp.Implementation{Name: "orders", Version: "0.1.0"}, nil)
	mcp.AddTool(server, &mcp.Tool{Name: "lookup", Description: "Look an order up by its number."}, lookup)
	subakofn.Serve(server)
}
  • One mcp.AddTool per tool. The schemas are inferred from the input and output structs, and a field’s jsonschema tag is its description.
  • A returned error is a failed call the model reads.
  • subakofn.Serve(server) takes the place of server.Run(ctx, &mcp.StdioTransport{}), which stalls under WASI.

The package’s name and description live in subako-package.json beside main.go:

{ "abi": 1, "name": "orders", "description": "Looks orders up." }

Files

Use os on the volume and assets: os.ReadFile("/volume/tmp/export.csv"), os.WriteFile("/volume/data/q3.md", data, 0o644).

HTTP

Under wasip1 the SDK replaces http.DefaultTransport, so net/http sends requests through Subako, under the grant’s network and credentials:

resp, err := http.Get("https://api.example.com/orders/1042")

net/http carries text bodies. For a volume file as the body, or a response saved to the volume, use subakofn.Do:

res, err := subakofn.Do(subakofn.Request{
	URL:    "https://api.example.com/exports/q3",
	Output: subakofn.ToFile("/volume/tmp/q3.csv"),
})

subakofn.TextBody, subakofn.JSONBody, and subakofn.FileBody build request bodies, and subakofn.Get(url) is the short form of a GET. A failure is an *subakofn.HTTPError with a Kind and a Message.

Images

subakofn.ImageResult shows the model images from the volume beside the value:

res, err := subakofn.ImageResult(plot, plot.Path)
return res, plot, err

Build and test

go test ./...                                         # tools run as plain Go
GOOS=wasip1 GOARCH=wasm go build -trimpath -o dist/module.wasm .
cp subako-package.json dist/
subako function create dist

The template’s package.sh builds and packs dist/<name>.tar.gz, adding assets/ when there is one. Run it with bash package.sh.

Was this page helpful?