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.AddToolper tool. The schemas are inferred from the input and output structs, and a field’sjsonschematag is its description. - A returned
erroris a failed call the model reads. subakofn.Serve(server)takes the place ofserver.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.