6b61495e3b
phase 2 (part 5): MCP server with official Go SDK
...
- MCP server at /mcp using github.com/modelcontextprotocol/go-sdk v1.6.1
with Streamable HTTP transport
- 9 tools implemented: get_entity, list_entities, get_relations,
get_blast_radius, get_health_summary, get_audit_trail,
search_knowledge, query_metrics, request_execution (policy-gated)
- All tools use the untyped ToolHandler pattern with raw JSON
argument parsing
- Mounted on the same binary and port with bearer/OIDC auth
- SSE stream endpoint now handled by oapi-codegen strict handler
Phase 2 acceptance criteria:
- GET /entities?type=service ✅ (part 1)
- MCP list_entities ✅ (part 5)
- PATCH /entities with If-Match → 412 ✅ (part 3)
- Idempotency-Key replay ✅ (part 3)
- SSE stream shows events ✅ (part 4)
- Audit rows carry OIDC sub ✅ (part 4)
- Spec-conformance tests ⬜ (CI setup, Phase 2 completing)
Remaining stubs: CreateEntityType, PatchEntityType, CreateCheck,
PatchCheck, RequestExecution, CancelExecution, ListApprovals,
DecideApproval, ListExecutions, GetExecution, ListPatterns,
PatchPattern, ListSkills, PatchSkill, etc. (Phase 3)
2026-07-07 12:27:36 +02:00
1bfc18ea3a
phase 2 (part 4): SSE stream via io.Pipe, OIDC JWT auth middleware
...
- SSE stream: GET /events/stream using io.Pipe to bridge the SSE
goroutine to the response body. Replay from Last-Event-ID via
in-memory broker with DB fallback. LISTEN/NOTIFY fan-out to all
subscribers. Heartbeat every 15s. Bounded channels.
- OIDC JWT auth: validates Bearer tokens against Authentik/OIDC
issuer via JWKS discovery + key caching. Extracts sub/email into
context actor. Falls back to static bearer tokens. Dev mode (no
OIDC + no tokens) = open.
- Config: OIDCIssuer, OIDCClientID env vars
- SSE + OIDC infrastructure complete, build passes, all tests pass
Remaining: MCP server, conformance tests, wire audit middleware
2026-07-07 09:40:11 +02:00
f2fe812cda
phase 2 (part 1): OpenAPI-generated API server, first 9 endpoints
...
- api/openapi.yaml converted 3.1 → 3.0.3 (oapi-codegen/kin-openapi
supports 3.0; nullable syntax + example keywords), still redocly-clean
- oapi-codegen (v2.4.1, strict server + chi) generates
internal/httpapi/gen from the spec; `make generate` wired
- internal/httpapi: chi router, /healthz (unauthenticated, SG18),
RFC 9457 problem+json mapping from domain sentinels (SG11), 5xx detail
logged server-side only, request logging with request IDs, graceful
shutdown (SG4), interim static bearer auth (constant-time; dev-open
when no token; OIDC JWT still to come in Phase 2)
- Implemented: listEntities (type filter walks the hierarchy, keyset
pagination), getEntity (UUID or slug, ETag), getEntityRelations,
getBlastRadius, getGraph (nodes+edges for UIs), getOntology,
listSignals, getFleetHealth, exportSeeds. Remaining 38 ops return 501
problem+json stubs (compiler-enforced interface completeness)
- `oikos api` role live: migrate-on-start, serves :8090
- 15 API integration tests (auth, pagination, hierarchy filter, ETag,
404/501 problem shapes, graph, export)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
2026-07-07 08:25:19 +02:00