* Initial plan
* feat(health): add RegistryCheck for registry connectivity health checks
Add a RegistryCheck function to the health package that creates a health
check verifying connectivity to the service registry. This enables
Kubernetes readiness probes to detect when a service loses its connection
to the registry (e.g. etcd).
Usage:
health.Register("registry", health.RegistryCheck(reg))
* fix(health): simplify error assertion in registry check test
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* Initial plan
* Add MCP Playground page to web UI with tool discovery and calling
- Add playground.html template with chat-style agent prompt interface
- Add /playground route handler in server
- Add /api/mcp/tools endpoint to list available MCP tools
- Add /api/mcp/call endpoint to invoke MCP tools via RPC
- Add Playground link to sidebar navigation
- Playground auto-discovers services from registry and renders them as
callable tools with input forms and activity logging
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add playground.html template and fix .gitignore micro pattern
Fix .gitignore pattern 'micro' -> '/micro' to only ignore root-level
binary, not paths containing 'micro' as a component.
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Address code review: use crypto/rand for trace IDs, fix var redecl, remove dup comment
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Rename Playground to Agent, fix styling, add LLM-powered prompt
- Rename /playground to /agent, move Agent link to top of sidebar menu
- Fix template styling: use existing form/input/button CSS from styles.css
instead of inline styles and form-plain class
- Add /api/agent/settings GET/POST endpoints for model API key, model
name, and base URL configuration (stored in server store)
- Add /api/agent/prompt POST endpoint that sends user prompt to
OpenAI-compatible LLM API with tool definitions from registry,
executes any tool calls via RPC, and returns results with a
follow-up LLM summary
- Show available tools in a table using existing table styles
- Prompt section is placed above settings for primary workflow
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Address code review: handle unmarshal errors, extract system prompt, improve param descriptions
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add Anthropic model support to the agent
Support both OpenAI and Anthropic APIs in the agent prompt handler:
- Add provider selector (OpenAI/Anthropic) to settings UI and backend
- Auto-detect provider from base URL when not explicitly set
- Anthropic: use /v1/messages endpoint, x-api-key header, input_schema
format for tools, content blocks for responses, tool_use/tool_result
message format for follow-ups
- OpenAI: unchanged /v1/chat/completions with Bearer auth
- Default models: gpt-4o (OpenAI), claude-sonnet-4-20250514 (Anthropic)
- Provider-specific defaults for base URLs
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Remove duplicate Anthropic follow-up message construction
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Add MCP per-tool scopes, tracing, rate limiting, and audit logging
- Add Scopes field to Tool struct for per-tool scope requirements
- Add Auth (auth.Auth) integration to Options for token inspection
- Add trace ID generation (UUID) propagated via metadata to downstream RPCs
- Add per-tool rate limiting with configurable requests/sec and burst
- Add AuditFunc callback for immutable tool-call audit records
- Extract tool scopes from registry endpoint metadata ("scopes" key)
- Update both HTTP and stdio transports with auth/trace/rate/audit
- Add comprehensive tests for all new functionality
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Revert unrelated example go.mod changes
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Remove auto-generated example go.sum files
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add WithEndpointScopes helper, gateway-level ToolScopes, and documentation
- Add server.WithEndpointScopes() for declaring per-endpoint auth scopes at
handler registration time
- Add mcp.Options.ToolScopes for gateway-level scope overrides without
changing individual services
- Update documented example to show WithEndpointScopes usage
- Update examples/mcp/README.md with scopes, tracing, and rate-limiting docs
- Update gateway/mcp/DOCUMENTATION.md with scopes section and FAQ
- Add tests for both new features
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix ToolScopes doc comment: clarify override (not merge) semantics
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Revert unrelated example go.mod/go.sum changes
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Rename ToolScopes to Scopes in MCP Options
The field name "Scopes" is more universal and consistent with how
auth scopes are used throughout go-micro. Updated all code references,
tests, and documentation.
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* MCP gateway: add per-tool scopes, tracing, rate limiting, and audit logging
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Fix insecure TLS configuration - make secure by default
- Changed util/tls/Config() to be secure by default (InsecureSkipVerify=false)
- Added MICRO_TLS_INSECURE=true environment variable for development/testing
- Updated documentation to emphasize security-first approach
- Added comprehensive tests for TLS configuration
- All existing broker tests pass
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Revert to backward-compatible TLS defaults to avoid breaking changes
- Reverted default to InsecureSkipVerify=true for backward compatibility
- Changed environment variable to MICRO_TLS_SECURE=true (opt-in security)
- Added deprecation warning that logs once per process
- Updated tests to reflect backward-compatible behavior
- Added comprehensive migration guide
- No breaking changes - production systems safe to upgrade
- Security improvement is opt-in via environment variable
- Planned breaking change for v6 with proper major version bump
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add TLS security update documentation
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Apply rate limiting before singleflight to prevent blocking
- Check rate limiting BEFORE entering singleflight
- If rate-limited AND stale cache exists, return stale cache immediately
- This prevents all goroutines from blocking when etcd is down/slow
- Maintains stampede prevention via singleflight for non-rate-limited requests
- All existing tests pass
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix variable shadowing in rate limiting check
- Rename shadowed variables to currentLastRefresh and currentMinimumRetryInterval
- Improves code clarity and prevents potential bugs
- All tests still pass
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Enhance cache rate limiting to protect against rolling deployment scenarios
Per @asim's feedback, rate limiting now applies to ALL cache refresh attempts
(not just error cases) to prevent registry overload during rolling deployments.
Changes:
- Rate limit ALL refresh attempts using lastRefreshAttempt tracking
- Always return stale cache if available (even if expired) when rate limiting
- Only return ErrNotFound when no cache exists during rate limit period
- Rate limiting happens inside singleflight to avoid race conditions
- Update test to reflect new behavior (no retry when stale cache + rate limit)
- Enhanced documentation with rolling deployment scenario examples
This addresses the scenario where all upstream services expire their cache
simultaneously during a downstream rolling deployment, which would previously
cause a stampede to the registry under high QPS.
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Remove unused failedAttempts and consecutiveFailures fields
Per @asim's feedback, these fields are no longer needed since the new
rate limiting strategy uses lastRefreshAttempt to track ALL refresh
attempts, not just failed ones.
Removed:
- failedAttempts map[string]time.Time
- consecutiveFailures int
- All code that sets these fields
The rate limiting logic now only uses lastRefreshAttempt, making these
fields redundant. All tests continue to pass.
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Add adaptive throttling to prevent cache penetration without stale cache
Implement rate limiting mechanism to protect etcd when:
- Cache is empty (no stale data available)
- Registry is failing/overloaded
- Multiple sequential requests arrive
Changes:
- Add MinimumRetryInterval option (default 5s)
- Track last failed attempt time per service
- Throttle requests within retry interval when no cache exists
- Clear throttling on successful lookup
- Add comprehensive tests validating throttling behavior
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix WaitGroup race condition in events stream tests
The WaitGroup.Add() calls were happening after goroutines started,
causing a race where Done() could be called before Add(), resulting
in "negative WaitGroup counter" panics.
Fixes:
- Move wg.Add(1) before goroutine in TestConsumeTopic
- Move wg.Add(2) before first goroutine in TestConsumeGroup
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Update registry cache documentation with adaptive throttling feature
Document the new adaptive throttling feature that prevents cache
penetration when registry is failing and no stale cache exists.
Includes:
- Feature overview
- Usage examples with configuration options
- Explanation of throttling behavior
- Example scenario demonstrating protection
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* Replace KeepAliveOnce with KeepAlive to reduce etcd auth requests
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add tests to verify cache penetration protection via singleflight
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add etcd integration tests to CI workflow
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix race conditions and improve code quality based on review feedback
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add workflow permissions to fix security scan finding
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Add comprehensive documentation for performance improvements
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix memory store limit/offset bug causing events test failure
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Fix memory store to filter before limiting in prefix/suffix reads
The previous fix had a logic error where limit/offset were applied before
prefix/suffix filtering. This could cause incorrect results when the first
N items in the unfiltered list don't match the search criteria.
Now filters first to get all matching keys, then applies limit/offset to
the filtered results. This ensures ReadLimit(1) always returns 1 matching
record if available, regardless of map iteration order.
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* Initial plan
* docs: clarify gRPC server option ordering and service name usage
- Fix all examples to show Server option before Name option
- Add note explaining why option ordering matters
- Add new section on "Option Ordering Issue" in Common Errors
- Add new section on "Service Name vs Package Name" in Common Errors
- Update transport.md to show proper ordering with comment
Co-authored-by: asim <17530+asim@users.noreply.github.com>
* docs: refine comments based on code review feedback
- Clarify that Server ordering before Name is mandatory
- Remove confusing comment about Client ordering being for consistency
Co-authored-by: asim <17530+asim@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>