Skip to content
goadesignPublic

About

Design-first agentic systems in Go: declare agents, tools, MCP servers, policies, and structured model output in Goa, then generate the durable runtime.

Topics

Resources

Stars

13 stars

Watchers

0 watching

Forks

Repository files navigation

Goa-AI: one Go design generates typed agent tools, MCP clients and servers, and HTTP and gRPC APIs. Goa-AI: one Go design generates typed agent tools, MCP clients and servers, and HTTP and gRPC APIs.

Release CI Go reference MIT license

Goa-AI: agents, MCP, and tool registries in Go

Design your capabilities once. Generate the contracts that connect your services, AI agents, and MCP clients.

Goa-AI extends Goa with AI agents, the Model Context Protocol (MCP), and distributed tool registries. Write a design in Go; generate typed clients, servers, model schemas, validation, and runtime wiring. Implement your application's behavior in ordinary Go.

Design tools can read the generated per-agent schema catalog, including consumer-bound, lookup, and text-only input contracts, without running application bindings.

For engineers, this means fewer contracts to maintain and compiler feedback when they change. For coding agents, it means explicit types, generated validation, and an application-specific guide to the code they need to implement.

Run the quickstart · Explore the guides · Upgrade to v0.89.0

Choose what you want to build

Your goal Start here
An AI agent that calls typed tools, returns structured answers, and can pause for human input Agent quickstart
Composable prompts and scoped overrides with compile-time AST validation, sub-prompt composition, and OpenTelemetry tracing Composable prompt management
An MCP server exposing Go service methods, resources, and prompts, or an MCP client consuming them MCP integration guide
A tool registry that publishes capabilities across services and lets agents discover independently implemented Agent operations without loading provider code, or binds generated native tools to selected registrations while retaining typed codecs and child routes Registries and tool search

Catalog owners can inspect active registration facts without loading tool declarations, using the saved identity, exact token and service-or-native kind.

Low-level runtime and custom Store integrations use a required generated run subject to identify the actual executor. Read its upgrade requirements before changing a deployment with saved runs.

These capabilities compose. You can also use MCP servers and clients independently of the agent runtime.

Paged agent tools declared with ContinueWith publish one operation for both the initial query and subsequent pages. Direct callers supply the declared page arguments; agents receive temporary no-argument actions tied to the exact query. See pagination ownership for the generated input and execution contracts.

One design, several ways to use it

A product lookup can be an HTTP endpoint, a gRPC method, an MCP tool, and a local agent tool. The input, output, descriptions, and validation come from the same design:

package design

import (
    . "goa.design/goa/v3/dsl"
    . "goa.design/goa-ai/dsl"
)

var Lookup = Type("Lookup", func() {
    Field(1, "sku", String, "Product SKU", func() { MinLength(1) })
    Required("sku")
    Example(map[string]any{"sku": "SKU-123"})
})

var Product = Type("Product", func() {
    Field(1, "name", String, "Product name")
    Required("name")
})

var _ = Service("catalog", func() {
    Description("Look up products for applications and shopping assistants.")
    MCP("catalog", "1.0.0")
    JSONRPC(func() { POST("/mcp") })

    Method("lookup", func() {
        Description("Retrieve a product by its SKU.")
        Payload(Lookup)
        Result(Product)
        HTTP(func() { GET("/products/{sku}") })
        GRPC(func() {})
        Tool("lookup", "Look up a product by SKU")
    })

    Agent("shopper", "Help customers find products", func() {
        Use("products", func() {
            Tool("lookup", "Look up a product by SKU", func() {
                BindTo("lookup")
            })
        })
    })
})

Run generation using the Goa version selected by your application:

go run goa.design/goa/v3/cmd/goa gen <design-package-import-path>
From this design You get
Service contract Typed Go interfaces, payloads, results, and validation
Agent tool Model-facing JSON Schema, examples, codecs, and a service executor
Composable prompt Validated AST, typed args struct, spec builder, and typed render helper
MCP tool A typed client and HTTP server with discovery and input/output schemas
HTTP and gRPC methods Clients, servers, OpenAPI, and protobuf definitions

Change a field and regenerate these contracts together. Your implementation, planner, authorization, and business rules remain application code. Ordinary methods can coexist with MCP tools in the same service.

Tools can expose a focused subset of a method's inputs and results, inject server-owned values, or return a selected Goa result view. The generator handles the declared transforms. See service bindings and MCP composition.

Quick start

With Go 1.27.0 or newer, run the checked-in example:

git clone https://github.com/goadesign/goa-ai.git
cd goa-ai/quickstart
go run ./cmd/orchestrator

It runs the real agent loop and typed completions with a deterministic planner and an in-memory engine and store. No model API key, Temporal, Redis, or MongoDB is required. You'll see:

Assistant: Tool helpers.answer returned {"text":"Tokyo is the capital of Japan."}
Completion draft_task: Prepare launch checklist (Confirm the service is ready to launch.), 3 steps

Run its evaluation suite:

go run ./cmd/chat_quality-evals

The quickstart guide walks through the design, generation, service wiring, and connecting a model. For MCP, follow the MCP integration guide.

What you can build

Agents and typed outputs

  • Typed tools and structured answers. Bind tools to Goa methods or custom executors; declare Completion(...) for typed direct responses. Generated codecs and schemas enforce the authored contract.
  • Composable prompts and scoped overrides. Declare agent system instructions and shared prompt templates in Goa design. Templates compile with missingkey=error and validate field references against typed Args at generation time. Compose sub-prompts via {{ render "<prompt_id>" . }} and manage scoped overrides dynamically with exact-scope reset and OpenTelemetry model span tracing.
  • Correction of invalid tool calls. Missing fields, wrong types, and invalid values receive specific feedback and authored examples. The runtime can ask the model for a replacement within your recovery budget, before execution.
  • Specialist agents. Expose agents as tools and compose real child runs with linked progress and cancellation. Cancellation preserves completed results and waits for required cleanup before closing the run; cleanup failures remain errors. Child workflow IDs stay bounded for long names and repeated nesting; see the identifier and worker upgrade contract.
  • Human input and approvals. Save a pending question or confirmation and continue from the host's answer. Direct and registered operations share durable continuation submission and completion. Hosts supply each successor workflow's Memo explicitly; recovery preserves it and rejects changed answers or metadata. Canceling a root question with no saved child or remote work closes its continuation while preserving the original suspended result. Text-only runs exclude interactive tools. Hosts can apply the same restriction to exact direct and registered operations with WithTextOnly(true).
  • Large results and images. Bound model-visible results, continue paginated queries, retain native image evidence, and keep rich host data outside model requests. Saved history remains readable after tool changes; only compatible current tools can supply another page. Outbound run-log record encoding applies the workflow payload allowance before publication; complete records assembled inside storage and historical reads preserve separately accepted data.

Agent DSL · Composable prompts · Runtime and composition · Native images

MCP clients and servers

  • MCP 2026-07-28 over HTTP. Generate stateless servers and typed clients with discovery, tools, structured results, and ordered text, image, audio, resource links, and embedded resources. Consumers also support stdio; generated stdio servers are deferred. Generated HTTP servers also accept basic 2025-11-25 clients on the same URL, using the same configured Goa endpoints. See the older-client contract.
  • Runtime-defined tools. Declare DynamicTools() to implement tool listing and invocation through generated protocol types without authored static tools. Older clients receive dynamic structured results in a matching value object; modern clients receive the original JSON value. See runtime-defined tools.
  • Resources and prompts. Serve fixed or parameterized text/binary resources, typed prompts, argument completion, and authenticated paginated catalogs.
  • Progress and subscriptions. Report progress from ordinary service methods; observe catalog changes, resource updates, and full Task state. Silent HTTP responses use transport keepalive comments without requiring service progress. Regenerate MCP servers when upgrading: a dependency-only update leaves streaming before middleware. Follow the required upgrade.
  • Additional input and durable Tasks. Collect form input or URL consent; preserve additional protocol members without changing declared fields; expose existing durable jobs with creation, observation, answers, and cancellation. The same native methods work as local and registry tools.
  • Authorization. Compose browser OAuth, machine credentials, signed client authentication, and enterprise identity exchange. Servers verify configured signed tokens or use token introspection. Hosts own trusted registration, consent, and private credential storage.
  • Apps and Skills. Associate tools with HTML app resources and caller visibility; publish Skill catalogs and files with manifest verification. Reference hosts demonstrate browser isolation and content-bound approval.

MCP declarations · Clients and authorization · Apps example · Skills guide

Context-limit responses are recovered by the workflow rather than accepted as completed answers or executable tool batches. The runtime uses its existing history policy to summarize older turns before a replacement request, preserves live text and usage, and stops if compaction cannot shorten the input. This uses the existing recovery-turn budget. See context-window recovery.

Initial-history writes reference the already bound preparation operation; seed reads return its original invocation without duplicating it in bounded commands. Custom stores must follow the preparation ownership upgrade.

Registries, search, and production execution

  • Distributed tool registries. Publish typed toolsets, discover changing catalogs, and route calls to providers with exact contracts and renewable leases. Providers can bound individual Registry operations independently of accepted-call shutdown; omitted options retain existing behavior. See provider lifecycle. Regenerate application gRPC code to adopt nullable collection conversion fixes; converter and wire rules remain separate. Catalogs retain resource ownership; applications authorize discovery and use. Newly committed native declarations retain an independently owned saved representation and its exact-byte digest for local reuse; cold reads strictly validate saved bytes. Reads still check current bytes, state and retirement. Service.ReadSavedCatalogToolset reads an exact saved declaration after retirement without reporting health or granting new execution; active catalog reads and provider admission keep rejecting retired registrations. Local maintenance tools can use registry.NewCatalogReader to inspect saved registrations without starting workers or writing Redis data; see read-only catalog inspection. Registered imports derive distinct names for equal operations from different owners and retain original declarations for execution and replay. Portable bounded-result codecs accept provider result data; the runtime adds counts and truncation before publishing results against the advertised schema. Generated Agent declarations also retain each operation's authored timeout recovery policy through registry transport; see the regeneration requirements.
  • Bind generated tools to selected services. Keep generated tool names, input preparation, codecs, and executors while attaching an exact owner-selected registration. Calls and retries retain the original route and token. New pages select today's provider after the resource owner verifies prior registrations; saved queries and completed results remain unchanged. See static service bindings. Binding validates complete generated declarations without expanding the consuming Agent's executable tools; separately discovered tools remain available. When the selected declarations remain fixed, compile their complete match once with CompileStaticService, then use BindCompiledStaticService for each activity. The immutable value retains compact call selections, not full catalogs or authority; current selection and admission remain caller-owned.
  • Standalone service operations. Execute a registered service tool without creating a session; sessionful calls retain their existing session. Direct calls validate complete execution arguments, including retained query fields and continuation cursors, while excluding provider-injected fields. Protocol 15 requires coordinated registry, provider, and consumer upgrades; see session metadata and upgrade. Registry startup preserves historical declaration identities without decoding old consumer metadata as today's executable contract, allowing saved-result recovery before provider replacement. This does not change typed historical resolution when removed metadata fields cannot fit the current response. GetToolsetSchemas returns original descriptive fields and input/output schemas for inspection without executable metadata or registration authority.
  • Direct Agent operations. Start typed operations before tool publication, using the same provider preparation and result contract as delegation. Revision-owned providers load and verify complete exports from the selected immutable configuration. Providers can select literal messages or exact completed-run history with retained privacy exclusions; see the resolver upgrade.
  • Load tools when needed. Use deferred tool search for whole toolsets or selected compiled tools, through supported OpenAI and Claude integrations.
  • Durable execution. Retain failures and cancellation even before the first Run is stored. Use Temporal and an application-owned durable store to retain accepted work, host continuations, remote Task identity, and cancellation across worker restarts. New turns preserve saved results completed by a later run, including conversations stored as literal history. Failed calls stay in the transcript and do not block later turns by restoring old paging state. Saved results without bounds remain evidence and supply no next page; completed page chains remain readable after their tool inputs change. Obsolete unfinished queries offer no page action but do not block new turns; current bounded results still require bounds and valid arguments. Paged operations retain each query and page branch's declared progress labels and result previews under the same public tool name. Regenerate callers after upgrading to install the matching templates. Steps that combine provider-selected calls with extra planner-created calls retain every call and result for the next planner activity, including after suspension. Completed tool results, accepted arguments, media, and rendered previews remain readable through clarification resumes after their generated result type changes or their tool is removed. Pending execution, result materialization, confirmations, child runs, and unfinished paging still use current generated contracts. Original provider messages and reasoning signatures stay unchanged. The in-memory engine supports local development.
  • Exact root worker builds. WithRootExecutionTarget selects one worker deployment and build for an accepted root request. Prepared starts, retries, and completion repair preserve that target; child routing remains generated. Each new answer or cancellation continuation leaves worker selection to the engine. Temporal chooses current workers and uses their configured versioning behavior; default pinned versioning keeps that execution on its assigned build. Retrying an already published request preserves its original launch settings.
  • Native Temporal handlers. Register SDK workflows and activities alongside agent handlers, and read the exact workflow and activity queues from successful registrations before starting workers.
  • Policies and context. Control permitted tools, call and recovery budgets, timing, history compression, prompt caching, and prompt overrides. Runtime model clients preserve provider token counting without creating an inference record or span; see model middleware.
  • Evaluation and observability. Generate typed evaluation suites; observe assistant text, tool progress, child runs, usage, and OpenTelemetry traces.
  • Standalone JSON codecs. Generate typed validators and strict JSON encoders and decoders beside ordinary Goa types, independently of agent and MCP declarations.

Registries and search · Production configuration · Evaluations · JSON codecs

Build with a coding agent

Install the Goa service designer skill in your application project (requires Node.js and npm):

npx skills add goadesign/goa --skill goa-service-designer

Give your coding agent the generated AGENTS_QUICKSTART.md. It names your agents, tools, packages, and registration functions. A useful first task:

Add a product lookup tool backed by the catalog service. Update the Goa design, regenerate, implement the service method, and verify valid and invalid calls. Use AGENTS_QUICKSTART.md for wiring. Do not edit gen/.

goa gen replaces generated contracts. goa example creates missing application scaffolding without overwriting existing files. Your application behavior stays yours. See the coding-agent workflow.

Take it to production

Choose model adapters for OpenAI, Anthropic, Amazon Bedrock, Google Vertex AI, or a model gateway. Provider support varies by model and API. Optional integrations include MongoDB for memory and prompt overrides, and Redis/Pulse for streams and registries.

Your application owns planners, service behavior, authorization, side-effect idempotency, durable storage, and deployment. Configure the Temporal engine and a durable runtime store for restart-safe execution. A trusted host receives runtime events and decides what to expose to users.

v0.89.0 is a breaking upgrade. Regenerate and coordinate servers, clients, providers, runtime workers, and storage implementations. Older MCP revisions, registry wire versions, and suspension checkpoints are not interchangeable. Read the release and upgrade instructions before replacing existing deployments; a source rollback alone cannot undo new stored work.

When binding generated service or Agent tools, the previous-registration reader returns the owner's exact ResolvedToolset, or nil without an error when the saved registration has no matching current resource. That query offers no new page, while its saved messages and results remain readable. A failed read or malformed binding still stops planning. Every member of a page chain is checked before an unavailable chain is omitted. The returned declarations let new pages verify their saved declarations while using current input and paging rules, including after a tool description changes. See static tool binding.

Learn more

Contributing

Issues and PRs are welcome. Include a Goa design, failing test, or clear reproduction when reporting behavior. See AGENTS.md for repository guidelines.

Run make setup once after cloning or when .tool-versions or .go-install changes. It installs the exact protobuf compiler and Go generators used by CI. Normal make targets verify those versions before building or generating code.

License

MIT License (C) Raphael Simon and the Goa community.

About

Design-first agentic systems in Go: declare agents, tools, MCP servers, policies, and structured model output in Goa, then generate the durable runtime.

Topics

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages