-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture and Contributing
Anna edited this page Jun 25, 2026
·
2 revisions
Aura Tracker GCP follows the Hexagonal Architecture pattern (Ports & Adapters). The central boundary is ports/gcp_service.go.
cmd/aura-tracker-gcp/main.go
│
▼
┌───────────────────────────────────────────┐
│ internal/mcp/ (protocol layer) │
│ - server.go │
│ - registry.go │
│ - tools/*.go │
│ - prompts/ │
└───────────────┬───────────────────────────┘
│ imports only ↓
ports/GCPService (interface boundary)
│ implemented by ↓
┌───────────────▼───────────────────────────┐
│ internal/gcp/ (GCP adapter) │
│ - *.go (one file per domain) │
│ - modules.go (client dependency map) │
└───────────────────────────────────────────┘
│ calls ↓
Google Cloud SDK + REST APIs
Key invariant: internal/mcp never imports internal/gcp. This is verified by:
go build ./internal/mcp/... # compiles zero GCP SDK code| Layer | Package | Purpose |
|---|---|---|
| Safety decorator | internal/safety/ |
Wraps GCPService; enforces two-step confirmation for mutations |
| Anonymization | internal/anonymize/ |
Middleware that scrubs PII from every tool result |
| Models | pkg/models/ |
Shared request/response structs (no GCP SDK types) |
| Ports | ports/ |
GCPService interface + DLPService interface |
Follow these six steps (from CLAUDE.md):
1. Add input/output structs to pkg/models/<domain>.go
2. Add the method signature to ports/gcp_service.go
3. Implement the method on gcpAdapter in internal/gcp/<domain>.go
- Call
a.rateWait(ctx, "domain.Method")first - Call
a.withTimeout(ctx)anddefer cancel() - Wrap errors with
wrapGCPError("domain.Method", err)
4. Create the tool definition + handler in internal/mcp/tools/<domain>.go
- Use
mcp.NewTypedToolHandler(t.handlerFunc)for automatic arg binding - Call
handleServiceError(toolName, err)on service errors - Declare
mcp.Required()parameters before optional ones — declaration order becomes JSON Schema order
5. Add the tool to GetTools() on the domain's *Tools struct
6. If adding a new domain, also add it to:
-
internal/gcp/modules.go(moduleClientDeps) -
internal/mcp/registry.go(AllModules)
| GCP error | Adapter output | Handler output | LLM sees |
|---|---|---|---|
codes.PermissionDenied |
*PermissionDeniedError |
mcp.NewToolResultError(...) |
IsError: true + structured JSON |
codes.NotFound |
*NotFoundError |
mcp.NewToolResultError(...) |
IsError: true + message |
| Any other error | wrapped error
|
return nil, err |
JSON-RPC -32603 |
# Always use -race
go test -race ./...
# Single package
go test -race ./internal/gcp/... -run TestAggregateBottlenecks
# Vet
go vet ./...# Verify tools/list works
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
| GCP_PROJECT_ID=my-project go run ./cmd/aura-tracker-gcpUpdate README.md whenever you:
- Add, remove, or rename a tool (update the count, Tools table, architecture diagram, Project Layout, and example prompts)
- Change environment variables, prerequisites, or architecture
Stage README changes in the same commit as the code that required them.