Files
wehub-resource-sync e071084ebe
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:40:33 +08:00

236 lines
6.2 KiB
Markdown

---
layout: default
title: MCP Troubleshooting
---
# MCP Troubleshooting
Common issues when using the MCP gateway and AI agents with Go Micro services.
## Agent Can't Find My Tools
**Symptom:** Agent says "no tools available" or doesn't list your service endpoints.
**Check 1: Is the service registered?**
```bash
# List registered services
micro services
```
If your service isn't listed, it hasn't registered with the registry. Make sure your service is running and using the same registry as the MCP gateway.
**Check 2: Is the MCP gateway discovering services?**
```bash
# List tools the gateway sees
curl http://localhost:3001/mcp/tools | jq
```
If empty, the gateway can't reach the registry. Verify both use the same registry address.
**Check 3: Are you using the right port?**
The MCP gateway runs on its own port (default `:3001` with `WithMCP`), separate from the service RPC port. Make sure you're querying the MCP port, not the service port.
## Tool Calls Return Errors
**Symptom:** Agent calls a tool but gets an error response.
**"service not found"**
The MCP gateway found the tool definition but can't reach the service. The service may have stopped since the gateway cached its tools. Restart the service and try again.
**"method not found"**
The handler method name doesn't match what the gateway expects. Ensure your handler is properly registered:
```go
// Correct - registers all methods on the handler
service.Handle(new(MyHandler))
// Or with proto-generated code
pb.RegisterMyServiceHandler(service.Server(), handler.New())
```
**"unauthorized" or "forbidden"**
Auth scopes are configured but the agent's token doesn't have the required scope. Check your scope configuration:
```go
// Gateway-side scopes
mcp.Options{
Scopes: map[string][]string{
"myservice.Users.Delete": {"users:admin"},
},
}
```
Verify the agent's bearer token includes the required scopes.
**"rate limited"**
The agent is making too many requests. Adjust rate limits:
```go
mcp.Options{
RateLimit: &mcp.RateLimitConfig{
RequestsPerSecond: 100, // Increase if needed
Burst: 200,
},
}
```
## Agent Makes Bad Tool Calls
**Symptom:** Agent calls tools with wrong parameters or misunderstands what a tool does.
This is almost always a documentation problem. Improve your handler doc comments:
```go
// Bad - agent doesn't know what this does
func (s *Users) Get(ctx context.Context, req *GetRequest, rsp *GetResponse) error {
// Good - agent understands purpose, parameters, and format
// Get retrieves a user by their unique ID. Returns the full user profile
// including email, display name, and account status.
//
// @example {"id": "user-123"}
func (s *Users) Get(ctx context.Context, req *GetRequest, rsp *GetResponse) error {
```
Add `description` struct tags to your request/response types:
```go
type GetRequest struct {
ID string `json:"id" description:"User ID in UUID format"`
}
```
See the [Tool Descriptions Guide](tool-descriptions.md) for detailed best practices.
## WebSocket Connection Drops
**Symptom:** WebSocket connections to `ws://localhost:3001/mcp/ws` disconnect unexpectedly.
**Check 1:** Make sure your client sends periodic pings. The WebSocket transport expects heartbeats to detect stale connections.
**Check 2:** If running behind a reverse proxy (nginx, Caddy), ensure WebSocket upgrade headers are forwarded:
```nginx
location /mcp/ws {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
```
**Check 3:** Check for connection limits. Each WebSocket connection is persistent. If you have many agents, you may need to increase file descriptor limits.
## Claude Code Can't Connect
**Symptom:** Claude Code doesn't see your MCP tools after configuring the server.
**Check 1: Test stdio transport manually**
```bash
# This should start and wait for JSON-RPC input
micro mcp serve
```
If it errors, check that your services are running and the registry is accessible.
**Check 2: Verify config syntax**
In your Claude Code MCP settings:
```json
{
"mcpServers": {
"my-services": {
"command": "micro",
"args": ["mcp", "serve"]
}
}
}
```
Common mistakes:
- Wrong path to `micro` binary (use absolute path if needed)
- Missing `"serve"` in args
- Service not running when Claude Code starts
**Check 3: Check micro is in PATH**
```bash
which micro
```
If not found, use the full path in your config:
```json
{
"mcpServers": {
"my-services": {
"command": "/usr/local/bin/micro",
"args": ["mcp", "serve"]
}
}
}
```
## OpenTelemetry Traces Missing
**Symptom:** MCP gateway calls aren't showing up in your trace collector.
The gateway only creates real spans when a `TraceProvider` is configured:
```go
mcp.Options{
TraceProvider: otel.GetTracerProvider(),
}
```
Without this, noop spans are used (no traces exported). Make sure you've initialized the OpenTelemetry SDK before starting the gateway.
## Audit Logs Not Appearing
**Symptom:** No audit records despite tool calls succeeding.
Audit logging requires an explicit callback:
```go
mcp.Options{
AuditFunc: func(r mcp.AuditRecord) {
log.Printf("[audit] tool=%s account=%s allowed=%t duration=%s",
r.Tool, r.AccountID, r.Allowed, r.Duration)
},
}
```
If `AuditFunc` is nil, no audit records are generated.
## Performance Issues
**Symptom:** MCP tool calls are slow.
**Check 1: Network round-trips**
Each MCP tool call makes an RPC call to the underlying service. If the service is on a different host, network latency applies. Use `micro mcp test` to measure raw latency.
**Check 2: Service discovery caching**
The gateway caches service/tool metadata. If you're seeing stale data, it's because of caching. The cache refreshes periodically based on registry TTL.
**Check 3: Rate limiting**
If rate limits are too low, requests queue up. Check your rate limit configuration.
## Still Stuck?
- Check the [MCP Documentation](../../mcp.md) for full API reference
- Search [GitHub Issues](https://github.com/micro/go-micro/issues) for similar problems
- Ask in [GitHub Discussions](https://github.com/micro/go-micro/discussions)