The README buried its best asset — the micro run --prompt transcript,
including mid-conversation service generation — under an 11-step on-ramp
and four paragraphs of internal CI make-targets, and put monetization
sections above the first code sample. Restructure for a first-time
visitor while keeping every CI-guarded wayfinding contract intact:
- New "See it" hero right after the Overview: the condensed --prompt
transcript with the mid-chat shipping-service generation moment.
- Quick Start decluttered: install → no-key start → on-ramp → prompt
generation, with the harness make-targets consolidated into one line
in Docs (install-smoke, inner-loop, zero-to-hero-transcript, harness).
- First agent on-ramp compressed from 11 steps to 4, preserving every
canonical wayfinding marker and their required order.
- Community and Commercial Support moved below the value demonstration;
sponsor logos stay near the top.
- Autonomous improvement loop tightened and moved out of Quick Start,
now leading with "Go Micro maintains itself".
- internal/demo/: VHS tapes for a reproducible quick-start GIF
(first-run.tape, no key; make demo-gif) and the keyed hero demo
(prompt-demo.tape, manual), with recording/embedding instructions.
Verified: the zero-to-hero-ci docs harness and cmd/micro wayfinding
tests pass unchanged.
Co-authored-by: Claude <noreply@anthropic.com>
* arch: decouple HTTP API gateway and MCP gateway via shared schema resolver
- Add gateway/schema: shared registry watcher and endpoint schema parser
used by both gateways, replacing duplicated discovery logic in gateway/mcp
- gateway/mcp: consume schema.Resolver; add NewServer for independent
lifecycle (discovery/watching in NewServer, transport in Serve, shutdown
via Stop)
- gateway/api: remove MCPEnabled/MCPAddress fields and background MCP
spawning; the HTTP gateway no longer starts MCP
- cmd/micro/run and cmd/micro/gateway: instantiate and orchestrate both
gateways explicitly, shutting down together on signal or first exit
- Mark gateway decoupling tickets 01-03 done
* feat(mcp): add streamable-HTTP transport for browser MCP clients
Implement the MCP streamable-HTTP spec at /mcp: POST JSON-RPC (batches,
notifications -> 202), GET SSE stream with heartbeat and session
lifecycle, DELETE session teardown, Mcp-Session-Id minted on initialize,
30-min idle session sweep. Tool dispatch shares invokeTool with the
legacy /mcp/call route; x402 challenge and tool-execution errors surface
as isError results.
Fixes browser-based clients (llama.cpp web UI): CORS preflight allows
mcp-protocol-version, and serveHTTP now shuts down the HTTP server when
the context is canceled so Ctrl-C/SIGTERM terminate cleanly.
* docs(website): document streamable-HTTP MCP transport and gateway decoupling
* feat(grpc): reflection option and native gRPC example
Add grpcserver.Reflection() to register go-micro handlers with gRPC's
reflection service, and examples/grpc showing a go-micro v6 service
callable by grpcurl and any standard gRPC client.
Resolvesmicro/go-micro#4880
* docs(grpc): native gRPC compatibility guide with reflection
Update grpc-compatibility guide for the reflection option and
server.Name placement on the gRPC server; remove duplicated intro
text on ai-integration and add client-server description.
* fix(website): more uglyURLs on main page
* docs(website): fix contributing doc paths and jekyll references
* docs(website): dedupe duplicate pages, standardize on _index.md sections
Remove duplicate page titles in internal/website/content/en so every
title resolves to a single canonical page. Precedence: directory index
pages with bundled images, then the most complete content; draft copies
were dropped.
Removed duplicates (kept page in parentheses):
- docs/overview/*/index.md (dir index + image) vs docs/*.md for
ai-integration, architecture, config, getting-started, observability
- docs/interfaces/{broker,registry,transport}/index.md (dir index +
image) vs docs/{broker,registry,transport}.md
- docs/interfaces/{plugins,store}.md vs docs/{plugins,store}.md
- docs/contributing.md and docs/guides/contributing.md vs
docs/project/contributing.md
- docs/guides/quickstart.md vs docs/quickstart.md
- docs/overview/performance.md vs docs/performance.md
- docs/project/{roadmap,roadmap-2026}.md vs docs/roadmap.md
- docs/architecture/{index,adr-*}.md (already mirrored and kept in
docs/project/architecture/, whose index now links the available ADRs)
- docs/model.md vs docs/model/index.md
- blog/news/agent-guardrails.md vs docs/guides/agent-guardrails.md
- docs/examples/learn-by-examples/* (near-identical copies) vs
docs/examples/*
- docs/overview/{REFLECTION-EVALUATION-SUMMARY,TLS_SECURITY_UPDATE}.md
(draft copies)
- docs/index.md and docs/examples/index.md symlinks vs their _index.md
Frontmatter tidy: add missing descriptions (store, atlas-cloud, model),
drop weight/draft overrides, consolidate the Architecture Decision
Records index, and remove dead CSS overrides from _styles_project.scss.
Hugo conventions: _index.md is the branch/section bundle for a
directory - it is the landing page for a doc section that lists its
children. index.md is a leaf bundle - a standalone page at the exact
directory URL whose directory bundles its own resources (images, etc.).
The docs site standardizes on _index.md for section landing pages, so
the redundant index.md symlinks were removed and the duplicate
Architecture directory was merged into the project/architecture section.
* refactor(website): merge duplicates
* docs(website): fix relative links and wayfinding tests after Hugo migration
Replace Jekyll-era .html links with .md/index.md targets, fix relative
paths for pages moved into Hugo bundles, restore the ADR files dropped by
the duplicate-merge refactor, and update zero-to-hero-ci docs tests to the
content/en/docs layout.
* test(cmd/micro): expect .md guide links in docs, translate for CLI alignment
* docs(website): drop duplicate h1s, promote titles, backfill descriptions
Auth is a policy of exposure, not of which command you typed. The bind
address decides the default and there is never a default credential.
- Address-based default: loopback (127.0.0.1/localhost/::1) => auth off;
non-loopback (0.0.0.0/routable) => auth on. micro run now binds
127.0.0.1:8080 by default, so the dev loop and localhost MCP clients
work with no login; micro gateway keeps :8080 (exposed => on).
- No default credential: stop creating admin/micro. When auth is on, use
--auth-token / MICRO_AUTH_TOKEN or generate a machine token and print it
once. It is accepted as an admin (constant-time compare) alongside JWTs.
- Token for machines, login for the browser: /api and /mcp accept
Authorization: Bearer and a ?token= query param (for SSE / links).
- Explicit override both ways: --auth/--no-auth and MICRO_AUTH=on|off,
shared by run and gateway via AuthFlags.
- Capability-aware even locally: checkEndpointScopes no longer short-
circuits when auth is off, so a tool with a required scope (actions,
paid) still needs a token+scope on a loopback gateway; read-only tools
stay open.
Adds gateway/auth.go (isExposed, ResolveAuth, static token, AuthFlags)
with tests, updates the run banner and the micro-run guide. Smoke-tested:
loopback /api open (404 no-service, not 401); exposed /api 401 without a
token and authenticated with Bearer or ?token=; no admin/micro created.
Co-authored-by: Claude <noreply@anthropic.com>
Rename `micro server` to `micro gateway` and fold the standalone
micro-mcp-gateway binary into it, so there is one gateway with one name.
- Rename command server -> gateway (package cmd/micro/server ->
cmd/micro/gateway; update the run and main importers).
- `micro gateway` gains the MCP production controls the standalone binary
had: --rate-limit/--rate-burst, --auth, --audit, --scope,
--circuit-breaker[-timeout], and --x402-*. When --mcp-address is set it
runs the full gateway/mcp with those options; registry selection uses
the CLI global --registry/--registry_address flags.
- `micro server` stays as a hidden, deprecated alias that warns and
delegates, so existing invocations keep working.
- Delete cmd/micro-mcp-gateway (binary + Dockerfile). goreleaser only
builds ./cmd/micro, so releases are unaffected.
- Repoint deploy/refs at the micro CLI image: Dockerfile CMD -> gateway;
Helm chart runs `micro gateway --mcp-address` with registry via
MICRO_REGISTRY env, image ghcr.io/micro/go-micro; drop the v6
micro-mcp-gateway vanity entry and rename server -> gateway; update the
docs guides and CLAUDE.md.
Build, vet, gofmt, and the run/gateway/cmd tests pass; `micro gateway`
and the hidden `micro server` alias both resolve.
Co-authored-by: Claude <noreply@anthropic.com>
micro run is the local development inner loop, not a production runtime.
Make that explicit and fix real dev-UX bugs:
- Clean shutdown: the new-service scanner shared the signal channel with
the main wait; a signal goes to one receiver, so it could steal Ctrl-C
and hang teardown. Give background goroutines a dedicated shutdown
channel and guard the services slice with a mutex (also fixes a data
race on that slice during shutdown).
- Hot reload no longer takes a service offline on a compile error: build
into a temp binary first and only swap+restart if the build succeeds;
on failure the previous version keeps serving and the error is printed.
- Raise the log scanner buffer so long lines (JSON logs, stack traces)
no longer overflow it and silently drop a services logs.
- Help text and the micro run guide now state plainly it is a dev tool
with no daemon, and point to systemd/Docker/Kubernetes for production.
Remove the guides fictional micro logs/status/stop commands (no such
commands exist) and describe the real lifecycle (Ctrl-C, log files).
Co-authored-by: Claude <noreply@anthropic.com>
The "your microservices are already an AI platform" post and the
micro-run guide pointed at github.com/micro/blog as a real example repo,
but it does not exist — the links 404 and `micro run github.com/micro/blog`
would fail. Reword to describe the illustrative blogging platform without
claiming a backing repo, point the runnable example at the in-repo
examples/mcp/platform, and use placeholder names in the compose/run
snippets.
Co-authored-by: Claude <noreply@anthropic.com>
* fix(website): convert /docs/overview/mcp/ link to .html for uglyURLs consistency
* fix(website): add .html suffix to single-page doc links missing it
* fix(website): replace blog short IDs with full permalink + .html
* fix: replace /blog/4 with absolute https://go-micro.dev URL in examples README
* fix(website): convert trailing-slash blog cross-references to .html
/blog/YYYY/MM/DD/slug/ → /blog/YYYY/MM/DD/slug.html across 17 files
for uglyURLs consistency. Includes roadmap blog references.
* fix(docs): add index.md symlinks for wayfinding tests
Hugo uses _index.md convention but wayfinding tests expect index.md.
Create symlinks index.md -> _index.md in docs and examples dirs.
Per-page RSS output rendered each post to <slug>/index.xml while the
post HTML rendered to <slug>.html (uglyURLs). That left the <slug>/
directory with index.xml as its only index, so requesting a post with
a trailing slash (e.g. /blog/2026/03/04/<post>/) served the XML feed
instead of a 404/the post. Drop RSS from the per-page outputs; a
per-page feed is meaningless anyway. Section and home feeds
(/blog/index.xml, /index.xml) are unaffected.
Co-authored-by: Claude <noreply@anthropic.com>
The header brand hardcoded "Go</span>Micro" with no space, and the
logo linked to .Site.Home.RelPermalink which resolves to /index.html
under uglyURLs. Add the space and point the brand link at /.
Co-authored-by: Claude <noreply@anthropic.com>
The site title, og:site_name, hero heading, PWA manifest, and package
author read "GoMicro" with no space. Add the space everywhere it
appears as a brand name.
Leaves the GoMicroToolkit Python class name in code samples untouched.
Co-authored-by: Claude <noreply@anthropic.com>
The migrated docs (#4858) 404'd for every page (e.g. /docs/getting-started.html)
and rendered untitled. Three Jekyll-to-Hugo migration gaps:
1. Leaf-bundle conflict: content/en/docs (and examples, examples/realworld,
guides/migration) had BOTH index.md and _index.md. index.md makes a
directory a leaf bundle — terminal — so every sibling page became a
non-rendered resource with no URL. Merged each index.md's (richer) body
into its _index.md and removed index.md, so the sections render children.
2. URL scheme: the old Jekyll site (and every inbound link, bookmark, and
in-content link) uses .html paths. Set uglyURLs: true so pages serve at
.html again — /docs/getting-started.html resolves instead of 404ing.
3. Front matter: 61 doc pages were raw Jekyll (`layout: default` or none),
so Docsy rendered them titleless with a broken sidebar. Derived each
title from its H1, wrote proper Hugo front matter, dropped `layout`.
Also removed content/en/docs/search.md — a Jekyll Liquid page ({% assign
… | where_exp %}) that hard-failed the Hugo build; Docsy ships its own
search.
Verified with a full local Hugo Extended 0.164.0 build (PostCSS installed):
builds clean, 26+ doc pages emit at .html, titles/H1 populate, and the
sidebar lists 24 doc pages.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
When caller and callee run in the same process, a unary Call pays the
full network tax — pool.Get, dial, codec-over-socket, and the transport
pump — even though the handler table is right there. This adds an opt-in
fast-path that dispatches directly.
- internal/network: a neutral registry (transport.Message in/out) so
client and server wire up without importing each other. A running server
registers a dispatcher under its name on Start, deregisters on Stop.
- server: localDispatch serves a request in-process through the same
router (identical wrappers/codecs/error mapping) over an in-memory
socket — no dial, no pipe, no gob.
- client: LocalDispatch() opt-in. In call(), a unary request whose body and
response are raw frames (codec/bytes.Frame — the agent/MCP/flow shape)
dispatches locally; everything else falls back to the network path
unchanged.
Correctness test proves the fast-path returns byte-identical replies to
the network path; benchmark shows ~545µs -> ~28µs (~20x) and ~3.6x fewer
allocations. Off by default. Covers #4817 (path b); the zero-copy typed
path remains a follow-up.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
* a2a: conform to external A2A clients — well-known path + spec SSE events
The A2A gateway interoperated go-micro-to-go-micro but a real external
client (ADK, LangGraph, a2a-SDK) would not:
- Discovery: served the Agent Card at /.well-known/agent.json, but A2A
0.3.0 discovers it at /.well-known/agent-card.json. Serve both, with
agent-card.json canonical and agent.json a legacy alias — per-agent,
per-skill, and at the single-agent top level.
- message/stream emitted repeated full Task snapshots. External SSE
clients parse by `kind` and stop on `final:true`; a Task snapshot has
neither, so they never terminate. Emit spec-shaped TaskArtifactUpdate
(append) chunks and close with a TaskStatusUpdate final:true. The
non-streaming and resubscribe paths also close with a terminal marker.
- A streaming error set both `result` and `error` in one JSON-RPC
response (strict clients reject it). Emit a failed status-update
instead — never result and error together.
Tests assert the canonical card path, the status-update/artifact-update
event shapes ending in final:true, and that no response carries both
result and error.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
* harness: update a2a-streaming to the spec-shaped stream events
The A2A gateway now emits artifact-update deltas and a terminal
status-update (final:true) instead of repeated full Task snapshots, so
the conformance harness must reassemble the answer from the append
artifact-update chunks and assert the final:true marker. This makes the
harness a stronger spec check rather than a snapshot-shape check.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
* agent: update a2a stream test to spec-shaped events
TestA2AStreamUsesAgentChatPathWithTools decoded the last SSE event as a
completed Task snapshot with artifacts. The gateway now closes the stream
with a status-update (final:true) and carries the answer as append
artifact-update deltas, so reassemble the answer from those deltas and
assert the terminal completed status-update instead.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
---------
Co-authored-by: Claude <noreply@anthropic.com>
The loop's dispatch is agent-agnostic already — `--agent` just sets the
@mention it posts, so any coding agent that responds to an issue @mention and
opens a PR works. Make that explicit instead of implying Codex-only:
- micro-loop guide: add a "Choosing an agent" section — Codex (default), Claude
Code (via anthropics/claude-code-action responding to @claude), any other
mention-driven agent, and an honest note that assignment-triggered agents
(e.g. Copilot's coding agent) aren't supported by the mention dispatch yet.
- Clarify the `--agent` help text and the CLI README bullet.
No behavior change — the mention model already covers Codex and Claude; this
documents it and scopes the one real gap (an "assign" adapter) honestly.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
Adds a deterministic reachable-CVE gate: `govulncheck ./...` on every push/PR,
failing on any reachable vulnerability EXCEPT an explicit allow-list of
known-unfixable ones. Today the allow-list holds exactly the two pgx/v4 CVEs
(GO-2026-5004, GO-2026-4518) with no upstream fix (tracked in #4556), so the
gate is green now and turns red the moment a NEW vulnerability appears.
This is the deterministic layer under the `security` loop role: the role
audits with judgment, this blocks known CVEs mechanically. Also adds
`govulncheck` to the loop-triage watch list, so a newly-disclosed CVE that
reddens the gate on master auto-files a fix issue for the loop to bump the dep.
Make `govulncheck` a required status check on master to enforce it.
Verified locally: exit 3 with only the two allow-listed IDs -> gate PASS.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>