Skip to main content
Isthmus follows hexagonal architecture (ports & adapters). The core business logic is decoupled from infrastructure, making it straightforward to add new database backends or change the transport layer.

Directory structure

Everything is under internal/ — Go’s convention enforces module privacy. There is no pkg/ directory.

Ports (interfaces)

The core defines three port interfaces that adapters implement:

Data flow

  1. The MCP client sends a tool call (e.g. describe_table) over stdio or HTTP
  2. The MCP adapter routes it to the appropriate service
  3. The service calls the port interface (e.g. SchemaExplorer.DescribeTable)
  4. The Postgres adapter executes SQL against the database
  5. The policy engine enriches the response and applies column masks (if configured)
  6. The result is serialized to JSON and returned to the client
  7. If OpenTelemetry is enabled, spans and metrics are recorded at each step

Dependency injection

All dependencies are wired at startup in cmd/isthmus/main.go. There is no global state, service locator, or runtime reflection:

Adding a new database adapter

To add support for a new database (e.g. MySQL):
  1. Create internal/adapter/mysql/
  2. Implement port.SchemaExplorer and port.QueryExecutor
  3. Wire the new adapter in cmd/isthmus/main.go based on the connection string scheme
  4. Add integration tests using testcontainers
The MCP layer, services, domain validation, and policy engine all work unchanged — they only depend on port interfaces.

Testing

Isthmus uses no mocks. Integration tests use testcontainers-go to spin up real PostgreSQL containers:
Domain tests (SQL validation, cardinality classification) run without Docker. Adapter and E2E tests require Docker for testcontainers.