dockyard

module
v1.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2026 License: Apache-2.0

README

Dockyard

Dockyard

Build production MCP Servers and MCP Apps in Go.

Typed tools. Embedded UI. Local inspection. Observable by default. One static binary.

Docs · Quickstart · Templates · The Dockyard loop · Contributing


Dockyard is a Go-native framework for building MCP servers with rich, interactive MCP Apps. It is for the moment when a tool stops being a demo and starts becoming software: it needs typed contracts, UI states, fixtures, validation, observability, packaging, and a way to debug the whole thing locally before a host ever renders it.

You write Go handlers and Svelte views. Dockyard generates the protocol contracts, TypeScript types, fixtures, embedded UI resources, and local inspection surface around them.

Dockyard inspector previewing an analytics-widgets chart against a live MCP server

The local inspector rendering a real create_chart call against a scaffolded MCP server.

A Dockyard tool, in full

type GetWeatherInput struct {
    City string `json:"city" jsonschema:"required"`
}

type GetWeatherOutput struct {
    Temperature float64 `json:"temperature"`
    Conditions  string  `json:"conditions"`
}

func GetWeather(ctx context.Context, in GetWeatherInput) (tool.Result[GetWeatherOutput], error) {
    // ...your code...
}

That struct pair is the source of truth. dockyard generate produces the JSON Schema the host validates against, the TypeScript types the App consumes, and the fixture scaffolds the inspector renders. dockyard validate fails if any of them drift. You never hand-maintain a schema or a TypeScript shadow contract; the toolchain does.

Why Dockyard exists

MCP makes tools available to agents. MCP Apps make those tools visible to users. That second part changes the job.

A useful App is not just a tool result with some HTML attached. It needs a contract between the server and the UI. It needs loading, empty, error, permission, slow, and large-data states. It needs fixtures so the App is testable before the backend is finished. It needs safe iframe boundaries. It needs host-compatibility. It needs a way to see what the server emitted and why the UI rendered what it rendered.

Without a framework, every team rebuilds that plumbing differently — and most teams ship the happy path first and learn the edge cases in production.

So Dockyard handles it for you:

  • Go structs are the source of truth.
  • JSON Schema and TypeScript types are generated.
  • UI resources are embedded into the server binary.
  • Apps render through a sandboxed bridge with deny-by-default CSP.
  • Tasks and human-in-the-loop flows are first-class.
  • The runtime emits Logbook — a native observability stream the inspector reads directly.
  • The inspector debugs tools, fixtures, JSON-RPC, Tasks, and UI in one place.
  • dockyard validate catches drift before users do.

The protocol is the foundation. Dockyard is the product layer above it.

What you can build

MCP server = tools + resources + prompts
MCP App    = server + ui:// views the host renders
MCP Tasks  = task-augmented tools, human-in-the-loop  (experimental spec)

Start with a server. Add a UI when the tool deserves one. Pause for user input when a tool needs approval — Tasks is a first-class extension Dockyard already supports end to end, with the caveat that the spec itself is still experimental upstream. Ship all three shapes as the same single binary. Good fits include analytics widgets, approval and review flows, internal business apps exposed through MCP, dashboards inside chat, and any agent-facing tool that needs a user-facing surface.

Templates

Two ready-to-fork starting points covering both halves of MCP Apps — scaffold one, run it, remix it into your own project:

analytics-widgets

analytics-widgets

The read-side template: charts, tables, and metric cards rendered inline in the host's chat. Exercises the contract-first path end to end — Go output → JSON Schema → TypeScript → fixtures → Svelte App → embedded ui:// resource → inspector preview.

Reach for it when the App is data-first.

approval-flows

approval-flows

The write-side template: human-in-the-loop approve / reject / edit flows over MCP Tasks. Demonstrates the input_required lifecycle, editable proposals, and the task timeline rendered live in the inspector.

Reach for it when a tool needs the user's go-ahead before acting.

dockyard new --template analytics-widgets ~/my-widgets
dockyard new --template approval-flows    ~/my-approvals

The Dockyard loop

Scaffold + generate. dockyard new --template <name> materialises a real project with typed contracts, generated JSON Schema + TypeScript, fixtures, and an embedded App. dockyard generate keeps the generated artifacts in sync as the contracts evolve.

Develop with the inspector. dockyard dev runs the live-reload loop and opens the local inspector. The inspector renders your App against the real running server — not a mock viewer. Switch between fixture states, invoke tools with operator-provided parameters, watch the Logbook stream, step through a Task's input_required round-trip, and verify the App in its sandboxed iframe before any host sees it.

Validate + package. dockyard validate catches contract drift, stale generated files, missing UI states, unsafe App settings, and spec-compliance issues — the failures users would otherwise hit. dockyard build produces a single CGo-free Go binary with the UI embedded. The same artifact runs over stdio, over HTTP, or wherever your transport story lands; the choice is at runtime, not baked into the build.

Quickstart

Replace @main with @v1.0.0 after the first release tag is published.

go install github.com/hurtener/dockyard/cmd/dockyard@main
dockyard --help

Scaffold and run the analytics template:

dockyard new --template analytics-widgets ~/widgets-demo
cd ~/widgets-demo
go mod tidy
dockyard generate
dockyard build

Serve the generated MCP server over HTTP and attach the inspector:

DOCKYARD_TRANSPORT=http \
DOCKYARD_HTTP_ADDR=127.0.0.1:8080 \
./bin/widgets-demo &

dockyard inspect \
  --url http://127.0.0.1:8080/mcp \
  --dir .

Core ideas

Contract-first. A Dockyard tool starts with typed Go structs. Those structs generate the JSON Schema the MCP host sees and the TypeScript types the App uses. The UI does not hand-maintain a shadow contract. If generated output is stale or drifted, validation fails before a build can ship.

Apps are server resources. Dockyard treats an MCP App as an MCP server with one or more ui:// resources. The UI is built, bundled, embedded, served through resources/read, and linked to tools through App metadata. The App runs in a sandboxed iframe behind a deny-by-default CSP and talks to the host through the Dockyard bridge.

Logbook — observability built in. Every Dockyard server emits Logbook, a canonical, versioned event stream covering tool calls, resource reads, App lifecycle, Tasks transitions, prompt invocations, and server diagnostics. The inspector is a Logbook client; the optional OpenTelemetry adapter is another Logbook client. Understanding what your server is doing is not a separate tier of the stack — it ships in the box, on by default, with W3C trace propagation already wired so a calling agent's trace context flows through.

Tasks are first-class. Dockyard supports task-augmented tools and the input_required lifecycle used by human-in-the-loop Apps. A tool can pause for user input, render a form, resume from the iframe, and expose the whole lifecycle to the inspector — without the developer hand-rolling the elicitation choreography.

One artifact. A Dockyard project builds to a single static Go binary with the UI embedded. No separate Node server. No runtime web-asset folder. No CGo requirement. No separate frontend deploy just to render an MCP App.

Where Dockyard fits

Dockyard is the server side of MCP. Not the agent loop, not the production client, not a gateway, not a hosted cloud — those are different jobs, and trying to do all of them would mean doing none of them well. The local inspector is the one place Dockyard talks like a client, and it stays on your laptop: it refuses any non-loopback bind before its listener opens, and it only fires a state-changing call when you click one.

For the agent side, look at Harbor — Dockyard's sibling framework in the same family.

Documentation

The published documentation site covers getting started, the CLI reference (auto-generated from the command tree), template walkthroughs, design conventions, the agent skills, the RFC, the decisions log, and the glossary.

Start here: https://hurtener.github.io/dockyard/

Build from source

To work from a local checkout (and to scaffold projects that reference your working tree before the first published tag):

git clone https://github.com/hurtener/dockyard
cd dockyard
make build
./bin/dockyard --help

Use the local CLI to scaffold a project against your checkout:

./bin/dockyard new --template analytics-widgets ~/widgets-demo \
  --dockyard-path "$(pwd)"
cd ~/widgets-demo
go mod tidy
dockyard generate
dockyard build

Contributing

Dockyard is built doc-first. Research briefs, RFCs, plans, and architectural decisions live in the repository — if you change the framework shape, update the design record with the code.

Before opening a PR:

make preflight

Human and AI contributors should read:

License

Apache-2.0.

Directories

Path Synopsis
cmd
dockyard command
Command dockyard is the entrypoint for the Dockyard CLI (RFC §9).
Command dockyard is the entrypoint for the Dockyard CLI (RFC §9).
examples
backend-tools-only/cmd/server command
Command backend-tools-only is the Phase 28 worked example showing Dockyard as a pure-tools MCP server — no MCP App, no UI, just typed tool handlers exposed to an agent host (RFC §2; Phase 28, D-150).
Command backend-tools-only is the Phase 28 worked example showing Dockyard as a pure-tools MCP server — no MCP App, no UI, just typed tool handlers exposed to an agent host (RFC §2; Phase 28, D-150).
backend-tools-only/internal/contracts
Package contracts holds the tool input/output contracts for the backend-tools-only example (Phase 28).
Package contracts holds the tool input/output contracts for the backend-tools-only example (Phase 28).
backend-tools-only/internal/handlers
Package handlers implements the backend-tools-only example's tool handlers over a small, in-process bookmarks catalog.
Package handlers implements the backend-tools-only example's tool handlers over a small, in-process bookmarks catalog.
combined-patterns/cmd/server command
Command combined-patterns is the Phase 28 worked example showing analytics-widgets + approval-flows COMPOSED on one MCP App (D-150).
Command combined-patterns is the Phase 28 worked example showing analytics-widgets + approval-flows COMPOSED on one MCP App (D-150).
combined-patterns/internal/contracts
Package contracts holds the tool contracts for the combined-patterns example (Phase 28).
Package contracts holds the tool contracts for the combined-patterns example (Phase 28).
combined-patterns/internal/handlers
Package handlers implements the combined-patterns example's two tool handlers.
Package handlers implements the combined-patterns example's two tool handlers.
prompts-demo/cmd/server command
Command prompts-demo is the Phase 28 worked example for the Dockyard prompts API (D-151).
Command prompts-demo is the Phase 28 worked example for the Dockyard prompts API (D-151).
prompts-demo/internal/contracts
Package contracts holds the tool contract for the prompts-demo example's one tool (Phase 28).
Package contracts holds the tool contract for the prompts-demo example's one tool (Phase 28).
prompts-demo/internal/handlers
Package handlers implements the prompts-demo example's one tool (summarize_text) and its three MCP Prompts.
Package handlers implements the prompts-demo example's one tool (summarize_text) and its three MCP Prompts.
internal
buildpkg
Package buildpkg implements the `dockyard build` pipeline — the step that turns a Dockyard project into the shippable artifact (RFC §14).
Package buildpkg implements the `dockyard build` pipeline — the step that turns a Dockyard project into the shippable artifact (RFC §14).
changelogx
Package changelogx parses Dockyard's top-level CHANGELOG.md and extracts one version's section as plain Markdown (Phase 30 — V1 release engineering).
Package changelogx parses Dockyard's top-level CHANGELOG.md and extracts one version's section as plain Markdown (Phase 30 — V1 release engineering).
changelogx/cmd/changelogx command
Command changelogx serves the release pipeline's CHANGELOG needs:
Command changelogx serves the release pipeline's CHANGELOG needs:
cli
Package cli is the cobra command tree for the dockyard CLI (RFC §9).
Package cli is the cobra command tree for the dockyard CLI (RFC §9).
clidocs
Package clidocs is the small helper that renders the dockyard CLI command tree as a Markdown page for the published documentation site (Phase 29 — docs/site/cli/index.md).
Package clidocs is the small helper that renders the dockyard CLI command tree as a Markdown page for the published documentation site (Phase 29 — docs/site/cli/index.md).
clidocs/cmd/clidocs command
Command clidocs renders the dockyard CLI reference to a Markdown file.
Command clidocs renders the dockyard CLI reference to a Markdown file.
codegen
Package codegen turns Go contract structs into downstream artifacts — the spine of Dockyard's contract-first property (P1, RFC §6.1).
Package codegen turns Go contract structs into downstream artifacts — the spine of Dockyard's contract-first property (P1, RFC §6.1).
coveragecheck
Package coveragecheck is the mechanical coverage gate (Phase 21.5).
Package coveragecheck is the mechanical coverage gate (Phase 21.5).
coveragecheck/cmd/coveragecheck command
Command coveragecheck is the mechanical coverage gate's entry point: it reads a Go coverage profile and a threshold config, compares each package's statement coverage against its required band, prints a report, and exits non-zero on a shortfall (or on an unconfigured package).
Command coveragecheck is the mechanical coverage gate's entry point: it reads a Go coverage profile and a threshold config, compares each package's statement coverage against its required band, prints a report, and exits non-zero on a shortfall (or on an unconfigured package).
devloop
Package devloop is the embedded fsnotify dev orchestrator behind the `dockyard dev` command (RFC §9.2).
Package devloop is the embedded fsnotify dev orchestrator behind the `dockyard dev` command (RFC §9.2).
generate
Package generate is the engine behind `dockyard generate` — the contract-first code generation verb (RFC §6, §9.1).
Package generate is the engine behind `dockyard generate` — the contract-first code generation verb (RFC §6, §9.1).
inspector
Package inspector implements the host-side core of Dockyard's local inspector — the single test/debug surface for exercising an MCP server and its Apps without a real host (RFC §12).
Package inspector implements the host-side core of Dockyard's local inspector — the single test/debug surface for exercising an MCP server and its Apps without a real host (RFC §12).
installpkg
Package installpkg implements the `dockyard install` verb — registering a built Dockyard server with an MCP host (RFC §14).
Package installpkg implements the `dockyard install` verb — registering a built Dockyard server with an MCP host (RFC §14).
manifest
Package manifest is the typed schema, loader, and structural validator for dockyard.app.yaml — Dockyard's control plane (RFC §4.2).
Package manifest is the typed schema, loader, and structural validator for dockyard.app.yaml — Dockyard's control plane (RFC §4.2).
protocolcodec
Package protocolcodec is Dockyard's single isolation seam for every MCP extension wire format.
Package protocolcodec is Dockyard's single isolation seam for every MCP extension wire format.
releasebuild
Package releasebuild drives the Dockyard release pipeline — the step the `.github/workflows/release.yml` workflow runs on a `v*` tag push to produce the cross-compile artifacts attached to the GitHub Release (Phase 30 — V1 release engineering, RFC §14).
Package releasebuild drives the Dockyard release pipeline — the step the `.github/workflows/release.yml` workflow runs on a `v*` tag push to produce the cross-compile artifacts attached to the GitHub Release (Phase 30 — V1 release engineering, RFC §14).
releasebuild/cmd/releasebuild command
Command releasebuild drives Dockyard's V1 release pipeline — the step the `.github/workflows/release.yml` workflow runs on a `v*` tag push.
Command releasebuild drives Dockyard's V1 release pipeline — the step the `.github/workflows/release.yml` workflow runs on a `v*` tag push.
runpkg
Package runpkg implements the `dockyard run` verb — running a Dockyard project's MCP server on a chosen transport (RFC §14, §9.1).
Package runpkg implements the `dockyard run` verb — running a Dockyard project's MCP server on a chosen transport (RFC §14, §9.1).
scaffold
Package scaffold implements `dockyard new` — the no-template project scaffold (RFC §9.1, §10).
Package scaffold implements `dockyard new` — the no-template project scaffold (RFC §9.1, §10).
skillcheck
Package skillcheck validates SKILL.md files against the agentskills.io Agent Skills specification (https://agentskills.io/specification).
Package skillcheck validates SKILL.md files against the agentskills.io Agent Skills specification (https://agentskills.io/specification).
skillcheck/cmd/skillcheck command
Command skillcheck validates a tree of Dockyard agent skills against the SKILL.md format (agentskills.io specification).
Command skillcheck validates a tree of Dockyard agent skills against the SKILL.md format (agentskills.io specification).
testgate
Package testgate is the engine behind `dockyard test` — the contract + compliance gate (RFC §9.1, §9.4).
Package testgate is the engine behind `dockyard test` — the contract + compliance gate (RFC §9.1, §9.4).
validate
Package validate is the engine behind `dockyard validate` — the quality-gate verb (RFC §9.4).
Package validate is the engine behind `dockyard validate` — the quality-gate verb (RFC §9.4).
runtime
apps
Package apps is the Dockyard server-side MCP Apps extension layer (io.modelcontextprotocol/ui, SEP-1865, spec revision 2026-01-26 — RFC §7).
Package apps is the Dockyard server-side MCP Apps extension layer (io.modelcontextprotocol/ui, SEP-1865, spec revision 2026-01-26 — RFC §7).
obs
Package obs is Dockyard's observability protocol — obs/v1 (RFC §11).
Package obs is Dockyard's observability protocol — obs/v1 (RFC §11).
obs/otel
Package otel is the optional OpenTelemetry export adapter for obs/v1 — the OTelEmitter (RFC §11.3, brief 05 §3.4).
Package otel is the optional OpenTelemetry export adapter for obs/v1 — the OTelEmitter (RFC §11.3, brief 05 §3.4).
server
Package server is the Dockyard app-runtime MCP server core.
Package server is the Dockyard app-runtime MCP server core.
store
Package store is the Dockyard persistence seam (RFC §13).
Package store is the Dockyard persistence seam (RFC §13).
store/inmem
Package inmem is the in-memory Store driver (RFC §13).
Package inmem is the in-memory Store driver (RFC §13).
store/sqlitestore
Package sqlitestore is the modernc.org/sqlite Store driver (RFC §13).
Package sqlitestore is the modernc.org/sqlite Store driver (RFC §13).
store/storetest
Package storetest holds the shared Store-driver conformance suite (RFC §13, AGENTS.md §9).
Package storetest holds the shared Store-driver conformance suite (RFC §13, AGENTS.md §9).
tasks
Package tasks is the Dockyard server-side MCP Tasks extension (io.modelcontextprotocol/tasks, experimental, SEP-1686/2663).
Package tasks is the Dockyard server-side MCP Tasks extension (io.modelcontextprotocol/tasks, experimental, SEP-1686/2663).
tasks/taskstoretest
Package taskstoretest holds the shared TaskStore conformance suite (RFC §8.5, CLAUDE.md §9).
Package taskstoretest holds the shared TaskStore conformance suite (RFC §8.5, CLAUDE.md §9).
tool
Package tool is Dockyard's contract-first typed tool builder — the app-facing API an author uses to declare an MCP tool (RFC §6, brief 04 §3).
Package tool is Dockyard's contract-first typed tool builder — the app-facing API an author uses to declare an MCP tool (RFC §6, brief 04 §3).
templates
analytics-widgets
Package analyticswidgets ships the analytics-widgets builtin template (Phase 24, RFC §10, decision D-124).
Package analyticswidgets ships the analytics-widgets builtin template (Phase 24, RFC §10, decision D-124).
analytics-widgets/pkg/contracts
Package contracts holds this server's tool input and output contracts — the typed Go structs that are the source of truth for the tool schemas (Dockyard P1 — contract-first, RFC §6).
Package contracts holds this server's tool input and output contracts — the typed Go structs that are the source of truth for the tool schemas (Dockyard P1 — contract-first, RFC §6).
analytics-widgets/pkg/handlers
Package handlers implements the three analytics-widgets tool handlers.
Package handlers implements the three analytics-widgets tool handlers.
approval-flows
Package approvalflows ships the approval-flows builtin template (Phase 25, RFC §10).
Package approvalflows ships the approval-flows builtin template (Phase 25, RFC §10).
approval-flows/pkg/contracts
Package contracts holds this server's tool input and output contracts — the typed Go structs that are the source of truth for the tool schemas (Dockyard P1 — contract-first, RFC §6).
Package contracts holds this server's tool input and output contracts — the typed Go structs that are the source of truth for the tool schemas (Dockyard P1 — contract-first, RFC §6).
approval-flows/pkg/handlers
Package handlers implements the two approval-flows tool handlers.
Package handlers implements the two approval-flows tool handlers.
test
conformance
Package conformance is Dockyard's MCP spec-compliance conformance suite (Phase 27, RFC §16).
Package conformance is Dockyard's MCP spec-compliance conformance suite (Phase 27, RFC §16).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL