This is the multi-page printable view of this section. Click here to print.
Project
1 - Contributing
This is a rendered copy of the repository CONTRIBUTING.md for convenient access via the documentation site.
Overview
Go Micro welcomes contributions of all kinds: code, documentation, examples, and plugins.
Quick Start
git clone --depth 1 https://github.com/micro/go-micro.git
cd go-micro
go mod download
go test ./...
Process
- Fork and create a feature branch
- Make focused changes with tests
- Run linting and full test suite
- Open a PR describing motivation and approach
Commit Format
Use conventional commits:
feat(registry): add consul health check
fix(broker): prevent reconnect storm
Testing
Run unit tests:
go test ./...
Run race/coverage:
go test -race -coverprofile=coverage.out ./...
Plugins
Place new plugins under the appropriate interface directory (e.g. registry/consul/). Include tests and usage examples. Document env vars and options.
Documentation
Docs live in internal/website/docs/. Add new examples under internal/website/docs/examples/.
Help & Questions
Use GitHub Discussions or the issue templates. For general usage questions open a “Question” issue.
Full Guide
For complete details see the repository copy of the guide on GitHub.
- View on GitHub: https://github.com/micro/go-micro/blob/master/CONTRIBUTING.md
2 - Roadmap
Go Micro is a framework for building agents and services in Go. An agent is a distributed system — it discovers services, calls them, holds state, and recovers from failure — so building an agent is building a service. The roadmap has two jobs: make agentic development excellent, and make the developer experience around it excellent. Nothing else.
Where we are (v6)
The foundation is in place:
- Services — register, discover, RPC, events; every endpoint is automatically an MCP tool.
- Agents — a model with memory and tools that manages services, with
plan,delegate, and guardrails (MaxSteps,LoopLimit,ApproveTool) built in, plus tool-execution middleware (WrapTool) and run metadata. - Flows — durable, event-driven workflows: ordered steps that checkpoint and resume after a crash.
- Interop — the MCP gateway (services as tools) and the A2A gateway (agents as agents, both directions, including A2A streaming, push notifications, and multi-turn continuation), both generated from the registry; x402 for paid tools.
- Secure by default — TLS verification on, state scoped per component.
Principles
These constrain everything below:
- Build into what people run, never a separate product. No hosted platform, no enterprise edition. Improvements go deeper into the framework, not beside it.
- CLI-first. The CLI is the experience. Any UI must be genuinely good and earn its place; bloat gets trimmed, not maintained.
- The getting-started flow is a contract. 0→1 (scaffold → run → call) and 0→hero (the ~10 steps to a working multi-agent system) must always work, and every change is checked against them.
- Interaction is as important as running. Talking to an agent, inspecting runs and history — end to end, not just “it starts.”
- Battle-tested. Works across every provider, fails safely, and is observable.
Now — hardening (“functional on every level”)
The priority is that what exists works everywhere, under real conditions.
- Cross-provider conformance. Each of the seven providers implements its own tool-call loop; today only the mock and one live provider are exercised. A suite that runs the same agent scenario (tool-calling, multi-step, plan/delegate, guardrails) across every provider, gated on keys, on a schedule.
- Failure & resilience. Provider timeouts, rate limits, and cancellation mid-run; deadline/
contextpropagation through the agent loop; retry and backoff at the model call. - The getting-started contract. Define and CI-verify the 0→1 and 0→hero flows so they can’t silently break.
Next — agentic depth
- Streaming. Broaden provider-backed
ai.Streamcoverage and keep chat plus A2Amessage/streamworking end to end for real chat and long-task UX. - Agent observability. Wire the new
RunInfointo OpenTelemetry spans so a run — steps, tool calls, delegation — is traceable. This is also what anyone running it in production will need.
Later
- Memory management — summarization and retrieval (RAG) beyond a fixed buffer.
- Human-in-the-loop — broaden pause/resume UX around
input-requiredruns and approvals. - A2A — richer live-stream reconnection (
tasks/resubscribe) andinput-requiredhandoffs.
Developer experience (ongoing)
- The CLI inner loop — scaffold → run → chat → inspect (
runs/history) → deploy, made seamless. This is the main lever for “dramatically improve the experience.” - UI discipline — keep only high-value, well-built surfaces; trim or cut the rest. The web UI should never be a worse version of the CLI.
- Examples & a real-world build — a maintained example that builds something real with the framework, doubling as the 0→hero reference and continuous battle-testing.
- Docs in lockstep — the getting-started guide tracks the code on every change.
How it’s sustained
The framework is the product. It’s funded by sponsorship from the people and companies who run it — not a hosted service, not an enterprise tier, not venture funding. The model is deliberate: keep refining the framework, aligned users adopt and depend on it, and that dependence funds the work. (See Bringing an Open Source Project Back from the Dead for why.)
3 - Powered by Go Micro Badge
Markdown Badges
Dark Badge
[](https://go-micro.dev)
Light Badge
[](https://go-micro.dev)
Compact Badge
[](https://go-micro.dev)
HTML Badges
Standard HTML Badge
<a href="https://go-micro.dev" target="_blank">
<img src="https://img.shields.io/badge/Powered%20by-Go%20Micro-0366d6?style=for-the-badge&logo=go&logoColor=white" alt="Powered by Go Micro">
</a>
Custom SVG Badge
<a href="https://go-micro.dev" style="display:inline-block;text-decoration:none;">
<svg width="160" height="32" xmlns="http://www.w3.org/2000/svg">
<rect width="160" height="32" rx="6" fill="#0366d6"/>
<text x="16" y="21" font-family="system-ui,-apple-system,sans-serif" font-size="13" font-weight="600" fill="white">
Powered by Go Micro
</text>
</svg>
</a>
Usage
Add one of these badges to your README.md, documentation, or website footer to show that your project uses Go Micro.
Example README
# My Awesome Project

[](https://go-micro.dev)
My project does amazing things using Go Micro microservices framework.
## Features
- Fast and scalable
- Built with Go Micro
- Production ready
Badge Guidelines
- Link the badge to
https://go-micro.devto help others discover Go Micro - Use the badge prominently in your README
- Consider adding it to your project website footer
- Feel free to customize the colors to match your brand
Showcase Your Project
Built something cool with Go Micro? Open an issue to get featured on our homepage!
4 - Server (optional)
Micro Server (Optional)
The Micro server is an optional web dashboard and authenticated API gateway for production environments. It provides a secure entrypoint for discovering and interacting with services that are already running (e.g., managed by systemd via micro deploy).
micro server does not build, run, or watch services. It only discovers services via the registry and provides a UI/API to interact with them.
micro server vs micro run
micro run | micro server | |
|---|---|---|
| Purpose | Local development | Production dashboard |
| Builds services | Yes | No |
| Runs services | Yes (as child processes) | No (discovers already-running services) |
| Hot reload | Yes | No |
| Authentication | Yes (default admin/micro) | Yes (default admin/micro) |
| Scopes | Yes (/auth/scopes) | Yes (/auth/scopes) |
| Dashboard | Full gateway UI with auth, scopes, agent | Full dashboard with API explorer, logs, user/token management |
| When to use | Day-to-day development | Deployed environments, shared servers |
For local development, use micro run instead.
Install
Install the CLI which includes the server command:
go install go-micro.dev/v6/cmd/micro@latest
Run
Start the server:
micro server
Then open http://localhost:8080 and log in with the default admin account (admin/micro).
Features
- Web Dashboard — Browse registered services, view endpoints, request/response schemas
- API Gateway — Authenticated HTTP-to-RPC proxy at
/api/{service}/{method} - JWT Authentication — All API endpoints require a Bearer token or session cookie
- Token Management — Generate, view, copy, and revoke JWT tokens
- User Management — Create, list, and delete users with bcrypt-hashed passwords
- Endpoint Scopes — Restrict which tokens can call which endpoints via
/auth/scopes - MCP Integration — AI agent playground and MCP tools, with scope enforcement
- Logs & Status — View service logs and status (PID, uptime) from the dashboard
Typical Production Setup
After deploying services with micro deploy:
# On your server, start the dashboard
micro server
Services managed by systemd are discovered via the registry and appear in the dashboard automatically. The server provides the authenticated API and web UI for interacting with them.
When to use it
- You have services running in production (via systemd or otherwise) and want a web UI
- You need authenticated API access with JWT tokens
- You want user management and token revocation
- You’re running a shared environment where multiple people interact with services
For CLI usage details, see the CLI documentation on GitHub.
5 - Architecture Decision Records
What are ADRs?
Architecture Decision Records (ADRs) capture important architectural decisions along with their context and consequences. They help understand why certain design choices were made.
Planned
Core Design
- ADR-002: Interface-First Design
- ADR-003: Default Implementations
Service Discovery
- ADR-005: Registry Plugin Scope
Communication
- ADR-006: HTTP as Default Transport
- ADR-007: Content-Type Based Codecs
Configuration
- ADR-008: Environment Variable Support
Status Values
- Proposed: Under consideration
- Accepted: Decision approved
- Deprecated: No longer recommended
- Superseded: Replaced by another ADR
Contributing
To propose a new ADR:
- Number it sequentially (check existing ADRs)
- Follow the structure of existing ADRs
- Include: Status, Context, Decision, Consequences, Alternatives
- Submit a PR for discussion
- Update status based on review
ADRs are immutable once accepted. To change a decision, create a new ADR that supersedes the old one.
5.1 - Adr 001 Plugin Architecture
Status
Accepted
Context
Microservices frameworks need to support multiple infrastructure backends (registries, brokers, transports, stores). Different teams have different preferences and existing infrastructure.
Hard-coding specific implementations:
- Limits framework adoption
- Forces migration of existing infrastructure
- Prevents innovation and experimentation
Decision
Go Micro uses a pluggable architecture where:
- Core interfaces define contracts (Registry, Broker, Transport, Store, etc.)
- Multiple implementations live in the same repository under interface directories
- Plugins are imported directly and passed via options
- Default implementations work without any infrastructure
Structure
go-micro/
├── registry/ # Interface definition
│ ├── registry.go
│ ├── mdns.go # Default implementation
│ ├── consul/ # Plugin
│ ├── etcd/ # Plugin
│ └── nats/ # Plugin
├── broker/
├── transport/
└── store/
Consequences
Positive
- No version hell: Plugins versioned with core framework
- Discovery: Users browse available plugins in same repo
- Consistency: All plugins follow same patterns
- Testing: Plugins tested together
- Zero config: Default implementations require no setup
Negative
- Repo size: More code in one repository
- Plugin maintenance: Core team responsible for plugin quality
- Breaking changes: Harder to evolve individual plugins independently
Neutral
- Plugins can be extracted to separate repos if they grow complex
- Community can contribute plugins via PR
- Plugin-specific issues easier to triage
Alternatives Considered
Separate Plugin Repositories
Used by go-kit and other frameworks. Rejected because:
- Version compatibility becomes user’s problem
- Discovery requires documentation
- Testing integration harder
- Splitting community
Single Implementation
Like standard net/http. Rejected because:
- Forces infrastructure choices
- Limits adoption
- Can’t leverage existing infrastructure
Dynamic Plugin Loading
Using Go plugins or external processes. Rejected because:
- Complexity for users
- Compatibility issues
- Performance overhead
- Debugging difficulty
Related
- ADR-002: Interface-First Design (planned)
- ADR-005: Registry Plugin Scope (planned)
5.2 - Adr 004 Mdns Default Registry
Status
Accepted
Context
Service discovery is critical for microservices. Common approaches:
- Central registry (Consul, Etcd) - Requires infrastructure
- DNS-based (Kubernetes DNS) - Platform-specific
- Static configuration - Doesn’t scale
- Multicast DNS (mDNS) - Zero-config, local network
For local development and getting started, requiring infrastructure setup is a barrier. Production deployments typically have existing service discovery infrastructure.
Decision
Use mDNS as the default registry for service discovery.
- Works immediately on local networks
- No external dependencies
- Suitable for development and simple deployments
- Easily swapped for production registries (Consul, Etcd, Kubernetes)
Implementation
// Default - uses mDNS automatically
svc := micro.NewService("myservice")
// Production - swap to Consul
reg := consul.NewConsulRegistry()
svc := micro.NewService("myservice",
micro.Registry(reg),
)
Consequences
Positive
- Zero setup:
go run main.gojust works - Fast iteration: No infrastructure for local dev
- Learning curve: Newcomers start immediately
- Progressive complexity: Add infrastructure as needed
Negative
- Local network only: mDNS doesn’t cross subnets/VLANs
- Not for production: Needs proper registry in production
- Port 5353: May conflict with existing mDNS services
- Discovery delay: Can take 1-2 seconds
Mitigations
- Clear documentation on production alternatives
- Environment variables for easy swapping (
MICRO_REGISTRY=consul) - Examples for all major registries
- Health checks and readiness probes for production
Use Cases
Good for mDNS
- Local development
- Testing
- Simple internal services on same network
- Learning and prototyping
Need Production Registry
- Cross-datacenter communication
- Cloud deployments
- Large service mesh (100+ services)
- Require advanced features (health checks, metadata filtering)
Alternatives Considered
No Default (Force Configuration)
Rejected because:
- Poor first-run experience
- Increases barrier to entry
- Users must setup infrastructure before trying framework
Static Configuration
Rejected because:
- Doesn’t support dynamic service discovery
- Manual configuration doesn’t scale
- Doesn’t reflect real microservices usage
Consul as Default
Rejected because:
- Requires running Consul for “Hello World”
- Platform-specific
- Adds complexity for beginners
Migration Path
Start with mDNS, migrate to production registry:
# Development
go run main.go
# Staging
MICRO_REGISTRY=consul MICRO_REGISTRY_ADDRESS=consul:8500 go run main.go
# Production (Kubernetes)
MICRO_REGISTRY=nats MICRO_REGISTRY_ADDRESS=nats://nats:4222 ./service
Related
5.3 - Adr 009 Progressive Configuration
Status
Accepted
Context
Microservices frameworks face a paradox:
- Beginners want “Hello World” to work immediately
- Production needs sophisticated configuration
Too simple: Framework is toy, not production-ready Too complex: High barrier to entry, discourages adoption
Decision
Implement progressive configuration where:
- Zero config works for development
- Environment variables provide simple overrides
- Code-based options enable fine-grained control
- Defaults are production-aware but not production-ready
Levels of Configuration
Level 1: Zero Config (Development)
svc := micro.NewService("hello")
svc.Run()
Uses defaults:
- mDNS registry (local)
- HTTP transport
- Random available port
- Memory broker/store
Level 2: Environment Variables (Staging)
MICRO_REGISTRY=consul \
MICRO_REGISTRY_ADDRESS=consul:8500 \
MICRO_BROKER=nats \
MICRO_BROKER_ADDRESS=nats://nats:4222 \
./service
No code changes, works with CLI flags.
Level 3: Code Options (Production)
reg := consul.NewConsulRegistry(
registry.Addrs("consul1:8500", "consul2:8500"),
registry.TLSConfig(tlsConf),
)
b := nats.NewNatsBroker(
broker.Addrs("nats://nats1:4222", "nats://nats2:4222"),
nats.DrainConnection(),
)
svc := micro.NewService("myservice",
micro.Version("1.2.3"),
micro.Registry(reg),
micro.Broker(b),
micro.Address(":8080"),
)
Full control over initialization and configuration.
Level 4: External Config (Enterprise)
cfg := config.NewConfig(
config.Source(file.NewSource("config.yaml")),
config.Source(env.NewSource()),
config.Source(vault.NewSource()),
)
// Use cfg to initialize plugins with complex configs
Environment Variable Patterns
Standard vars for all plugins:
MICRO_REGISTRY=<type> # consul, etcd, nats, mdns
MICRO_REGISTRY_ADDRESS=<addrs> # Comma-separated
MICRO_BROKER=<type>
MICRO_BROKER_ADDRESS=<addrs>
MICRO_TRANSPORT=<type>
MICRO_TRANSPORT_ADDRESS=<addrs>
MICRO_STORE=<type>
MICRO_STORE_ADDRESS=<addrs>
MICRO_STORE_DATABASE=<name>
MICRO_STORE_TABLE=<name>
Plugin-specific vars:
ETCD_USERNAME=user
ETCD_PASSWORD=pass
CONSUL_TOKEN=secret
Consequences
Positive
- Fast start: Beginners productive immediately
- Easy deployment: Env vars for different environments
- Power when needed: Full programmatic control available
- Learn incrementally: Complexity introduced as required
Negative
- Three config sources: Environment, code, and CLI flags can conflict
- Documentation: Must explain all levels clearly
- Testing: Need to test all configuration methods
Mitigations
- Clear precedence: Code options > Environment > Defaults
- Comprehensive examples for each level
- Validation and helpful error messages
Validation Example
func (s *service) Init() error {
if s.opts.Name == "" {
return errors.New("service name required")
}
// Warn about development defaults in production
if isProduction() && usingDefaults() {
log.Warn("Using development defaults in production")
}
return nil
}
Related
- ADR-004: mDNS as Default Registry
- ADR-008: Environment Variable Support (planned)
- Getting Started Guide - Configuration examples
- Configuration Guide
5.4 - Adr 010 Unified Gateway
Status: Accepted Date: 2026-02-11 Authors: Go Micro Team
Context
Previously, the go-micro CLI had two separate gateway implementations:
micro rungateway (cmd/micro/run/gateway/) - Simple HTTP-to-RPC proxy for developmentmicro servergateway (cmd/micro/server/) - Production gateway with authentication, web UI, and API documentation
This duplication created several problems:
- Code maintenance: Gateway logic (HTTP-to-RPC translation, service discovery, health checks) was implemented twice
- Feature parity: Improvements to one gateway didn’t automatically benefit the other
- Complexity: New features (like MCP integration) would need to be implemented twice
- Testing burden: Each gateway required separate testing
Decision
We unified the gateway implementation by:
Extracting reusable gateway module (
cmd/micro/server/gateway.go):GatewayOptionsstruct for configurationStartGateway()function that returns a*GatewayimmediatelyRunGateway()function that blocks until shutdown- Configurable authentication (enabled/disabled)
Refactoring
micro server:- Gateway logic remains in
cmd/micro/server/ registerHandlers()now uses instance-specific*http.ServeMuxinstead of global mux- Authentication middleware is conditional based on
GatewayOptions.AuthEnabled - Auth routes only register when authentication is enabled
- Gateway logic remains in
Updating
micro run:- Removed duplicate gateway implementation (
cmd/micro/run/gateway/) - Now calls
server.StartGateway()withAuthEnabled: true - Retains process management and hot reload functionality
- Same auth, scopes, and token management as
micro server
- Removed duplicate gateway implementation (
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Unified Gateway │
│ (cmd/micro/server/gateway.go) │
│ │
│ • HTTP → RPC translation │
│ • Service discovery via registry │
│ • Web UI (dashboard, logs, API docs) │
│ • Health checks │
│ • Configurable authentication │
│ • Endpoint scopes for access control │
│ • MCP tool integration with scope enforcement │
└─────────────────────────────────────────────────────────────┘
▲ ▲
│ │
┌──────┴──────┐ ┌────────┴────────┐
│ micro run │ │ micro server │
│ │ │ │
│ + Process │ │ + Auth enabled │
│ mgmt │ │ + JWT tokens │
│ + Hot │ │ + Scopes │
│ reload │ │ + Production │
│ + Auth │ │ │
│ + Scopes │ │ │
└─────────────┘ └─────────────────┘
Usage
Development Mode (micro run)
# Start services with gateway (auth enabled, default admin/micro)
micro run
# Gateway provides:
# - HTTP API at /api/{service}/{endpoint}
# - Web dashboard at /
# - JWT authentication (admin/micro default)
# - Endpoint scopes at /auth/scopes
Production Mode (micro server)
# Start gateway with authentication
micro server --address :8080
# Gateway provides:
# - HTTP API at /api/{service}/{endpoint} (auth required)
# - Web dashboard with login
# - JWT-based authentication
# - User/token management UI
# - Endpoint scopes at /auth/scopes
Benefits
- Single Source of Truth: Gateway logic lives in one place
- Automatic Feature Propagation: New features (like MCP) added to the unified gateway benefit both commands
- Simplified Testing: Test gateway once, works everywhere
- Reduced Code Size: Eliminated ~300 lines of duplicate code
- Clear Separation:
micro server= API gateway (HTTP + future MCP)micro run= Development tool (gateway + process management + hot reload)
Implementation Details
GatewayOptions
type GatewayOptions struct {
Address string // Listen address (e.g., ":8080")
AuthEnabled bool // Enable JWT authentication
Store store.Store // Storage for auth data
Context context.Context // Cancellation context
}
Starting the Gateway
// Non-blocking start
gw, err := server.StartGateway(server.GatewayOptions{
Address: ":8080",
AuthEnabled: false,
})
// Blocking start
err := server.RunGateway(server.GatewayOptions{
Address: ":8080",
AuthEnabled: true,
})
Authentication
When AuthEnabled: true:
- Auth middleware checks JWT tokens on all requests
- Auth routes are registered:
/auth/login,/auth/logout,/auth/tokens,/auth/users - Web UI requires login
- API endpoints require
Authorization: Bearer <token>header
When AuthEnabled: false (dev mode):
- No authentication middleware
- Auth routes are not registered
- All endpoints are publicly accessible
Consequences
Positive
- Easier to add new features (only implement once)
- Better code maintainability
- Consistent behavior between development and production
- Foundation for MCP integration
Negative
cmd/micro/runnow depends oncmd/micro/server(acceptable for CLI tools)- Slightly more complex initialization in
micro run(but cleaner overall)
Future Work
With unified gateway architecture, we can now add:
- MCP Integration: Add
mcp.goto server package, both commands get MCP support - GraphQL API: Single implementation serves both dev and prod
- gRPC Gateway: Expose services via gRPC alongside HTTP
- API Versioning: Consistent versioning strategy across all deployments
References
- Original issue: Gateway duplication between
micro runandmicro server - Implementation: PR #XXX (gateway unification)
- Related: ADR-001 (Plugin Architecture), ADR-009 (Progressive Configuration)