Skip to content

Planned Integrations

This page catalogs integrations that are not production-ready: scaffolded SDKs, stub applications, and adapter surfaces named in the original v1 design that are not implemented. For shipped integrations, see the dedicated reference pages (Python SDK, REST API, gRPC API, MCP Tools, CLI, VSCode Tooling, Rule Packs).

Each entry declares a Status of one of:

  • Shipped — in-tree, tested, documented, and reachable from a release artifact.
  • Partial — in-tree with working code but missing tests, packaging, or CI coverage.
  • Planned — named in the original v1 design with no implementation in the source tree.

Go SDK — packages/fathom-go/

Status: Partial.

Location: packages/fathom-go/ — a hand-written REST client plus generated gRPC bindings. Package contents: client.go (181 lines), client_test.go (818 lines), grpc_test.go (230 lines, build-tagged integration), tools.go, go.mod, go.sum, Makefile, and proto/ with fathom.pb.go + fathom_grpc.pb.go. go.mod declares module github.com/KrakenNet/fathom-go at go 1.25.0.

What works today:

  • NewClient(baseURL, opts...) constructor at client.go:39-48, with functional options WithBearerToken (client.go:25-27) and WithHTTPClient (client.go:31-33).
  • Four request/response pairs covering the REST surface: Evaluate, AssertFact, Query, Retract (client.go:74-144).
  • Shared transport at client.go:148-180: JSON marshal/unmarshal, Content-Type: application/json, optional Authorization: Bearer <token> header, and error surfacing on any non-2xx status with the server body embedded in the returned error.
  • Unit tests in client_test.go exercise the REST surface against httptest servers.
  • Generated gRPC stubs live in packages/fathom-go/proto/ (built from protos/fathom.proto); grpc_test.go is a -tags=integration test that spawns the Python gRPC server and dials it via those stubs.

What is missing:

  • No released module. Consumers must vendor the package from a local clone; nothing is published to a Go proxy. Tracked as issue #41.

The Go suite is wired into CI: .github/workflows/go-ci.yml runs go vet, go build, and go test ./... on every pull request, with a second integration job that spins up the Python gRPC server and runs go test -tags integration ./.... A verify-grpc step also fails the build if the generated bindings drift from protos/fathom.proto.

How to use today: Clone the monorepo, go get against the local path (or add a replace directive), and point the client at a running REST server. For the current public API surface, see the generated reference at Go SDK.

TypeScript SDK — packages/fathom-ts/

Status: Partial.

Location: packages/fathom-ts/ — published identity @fathom-rules/sdk, versioned in lockstep with the engine (release-please writes package.json from the same tag, and scripts/check_version_sync.py fails the build if the two drift). Source lives in src/client.ts (215 lines), src/errors.ts (77 lines), and src/index.ts (26 lines). Vitest suites in test/client.test.ts and test/errors.test.ts.

What works today: A hand-written FathomClient plus a typed error hierarchy. The package ships with 34 vitest tests passing (15 in test/client.test.ts, 19 in test/errors.test.ts), and the typedoc reference is generated into docs/reference/typescript-sdk/ by the docs npm script in package.json. The suite is wired into CI: .github/workflows/ts-ci.yml runs typecheck, build and vitest as the required ts-test check on every pull request.

There is no generated client. src/generated/ used to hold one, and this page used to describe it as working. It was generated once, in April 2026, from a copy of the spec at the repo root that was frozen at API version 0.3.0 — two endpoints behind the live one — and nothing in the package ever imported it. Its generate script emitted zero files against the pinned @hey-api/openapi-ts, so it could not be refreshed either. Both the dead tree and the stale root spec are gone; the single spec is docs/reference/rest/openapi.json, regenerated by scripts/export_openapi.py and held to the running app by tests/test_scripts/test_export_openapi.py.

What is missing:

  • The client covers 4 of the 11 documented endpoints/v1/evaluate, /v1/facts (assert and retract) and /v1/query. /v1/compile, /v1/templates, /v1/modules, /v1/rules, /v1/rules/reload, /v1/status, /v1/data/{path} and /health have no method on FathomClient.
  • No published npm release. repository.url in package.json points at the monorepo; no dist/ is published. Tracked as issue #40.

How to use today: Clone the monorepo, pnpm install in packages/fathom-ts/, and import from the local workspace path. The generated API reference lives at TypeScript SDK.

Visual Rule Editor

Status: Planned.

The original v1 design named a browser-based rule editor. A React scaffold lived at packages/fathom-editor/ and was removed: six component stubs, no tests, no backend wiring, and a CI job whose only assertion was that the tree still compiled. It never round-tripped against a live Fathom server, and Policy Studio (below) had meanwhile shipped a working browser UI over a real engine. Building the editor out is tracked as issue #43; the scaffold is in git history if it is ever the right starting point.

Framework adapters

The original v1 design listed four framework adapters. All four are now shipped.

Adapter Status Location
LangChain callback handler Shipped src/fathom/integrations/langchain.py
CrewAI before-tool-call hook Shipped src/fathom/integrations/crewai.py
OpenAI Agents SDK tool guardrail Shipped src/fathom/integrations/openai_agents.py
Google ADK before-tool callback Shipped src/fathom/integrations/google_adk.py

Each adapter follows the same pattern: intercept tool calls, then evaluate a tool_request fact against the policy through Engine.evaluate_once, which asserts the fact, runs, and withdraws it again so one call cannot be decided on the previous call's working memory.

The guard is allowlist-only: it permits the call when — and only when — the decision is exactly allow. Every other outcome (deny, escalate, route, scope, a missing decision, or any value a future release adds) blocks the call. A denylist of known-bad decisions would fail open on anything it had not heard of.

How each adapter blocks is dictated by its framework, and only LangChain blocks by raising. CrewAI, the Agents SDK and ADK all wrap the handler call in try/except, log whatever it raises, and then run the tool anyway — so in those three a raised exception is a fail-open, and the block has to be a return value:

Adapter Block signal Carries the reason?
LangChain raises PolicyViolation (needs raise_error = True on the handler, or LangChain swallows it) yes
CrewAI hook returns False no — CrewAI's own rejection message replaces it
OpenAI Agents SDK guardrail returns ToolGuardrailFunctionOutput.raise_exception(output_info=violation), which the runner turns into ToolInputGuardrailTripwireTriggered yes, on output_info
Google ADK callback returns {"error": ...} yes

PolicyViolation is one class, defined in fathom.integrations and re-exported by every adapter, so one except covers every adapter that raises.

raise_error = True is necessary but not sufficient on the async LangChain handler. langchain_core honours it in both its dispatchers, but only for a handler method that runs there: the sync dispatcher calls the method, sees a coroutine come back, and defers it to _run_coros, which catches everything, logs Error in callback coroutine, and never reads raise_error. That is not an exotic path — StructuredTool.ainvoke falls back to run_in_executor(config, self.invoke, …) for any tool with no coroutine=, which is every plain @tool-decorated function. FathomAsyncCallbackHandler therefore defines on_tool_start as a plain def; both dispatchers run it inline (the async one via run_in_executor) and both propagate. The engine is synchronous anyway.

Blocking covers every failure to reach a decision, not only deny. An exception other than PolicyViolation — a ValidationError from a pack whose tool-call template is spelled differently, a ScopeError, an EvaluationLimitError — means no decision was produced, and the CrewAI hook turns it into the block signal and logs it rather than letting it escape into CrewAI's except, which would log it and then run the tool.

The CrewAI hook reads the calling agent off the ToolCallHookContext CrewAI hands it (agent.role, else agent.id), falling back to the agent_id given to fathom_before_tool_call only when CrewAI supplies no agent. CrewAI's hook registry is process-global and every registered hook runs on every call, so an identity frozen at registration labels the whole crew with one name — and one hook per member is not a workaround, because any hook returning False blocks, so each member's allowed calls would be blocked by everybody else's hook.

Install via pip install fathom-rules[langchain], fathom-rules[crewai], fathom-rules[openai-agents], or fathom-rules[google-adk]. The CrewAI and Agents SDK extras carry floors of crewai>=1.5 and openai-agents>=0.4 — the releases that introduced crewai.hooks and agents.tool_guardrails respectively. Earlier releases have no hook to attach to at all.

Policy Studio — packages/fathom-studio/

Status: Partial.

Location: packages/fathom-studio/ — package identity fathom-studio at 0.1.0, a uv workspace member of this repo. It depends on fathom-rules like any other consumer; the engine wheel ships no Studio code.

What works today: A browser UI over a real engine — five views (Reasoning Bench, Live Wire, Rules, Templates, Audit) served as a zero-build React SPA, a JSON backend under /studio/api, server-rendered HTMX panels, and the production REST app mounted in the same process under /api. Nine demo scenarios ship as package data, held byte-identical to the repo's examples/0N-* directories by a test. Its pytest suite runs in CI: root testpaths includes packages/fathom-studio/tests, so the required test job covers it.

What is missing:

  • No published release. fathom-studio is not on PyPI and no workflow builds or publishes it; run it from a checkout with uv run fathom-studio.
  • No stability promise. The /studio/api/* routes are unversioned and explicitly excluded from VERSIONING.md.
  • In-memory audit only. The Audit view's chain is process-local, capped at 200 records, and signed with a keypair minted at startup. The durable equivalent is fathom.chained_log.ChainedAttestationLog.

How to use today: Running Policy Studio.

Known blockers

  • Proto ↔ go.mod path alignment — previously flagged as REVIEW.md M2 (proto declared github.com/KrakenNet/fathom/gen/go/fathom/v1 while go.mod declared github.com/KrakenNet/fathom-go, which would have broken protoc output). Resolved at HEAD: protos/fathom.proto:12 now declares go_package = "github.com/KrakenNet/fathom-go/proto;fathomv1", matching packages/fathom-go/go.mod:1. Generated bindings now live in packages/fathom-go/proto/{fathom.pb.go,fathom_grpc.pb.go}.
  • Every in-tree package is now covered by CI. The Python suite (.github/workflows/ci.yml, which also covers the Studio), the Go suite (.github/workflows/go-ci.yml, unit + -tags integration) and the TypeScript suite (.github/workflows/ts-ci.yml, the required ts-test check, closing issue #39) all run on every pull request.

See also

  • Python SDK — the reference implementation; all shipped adapters (including LangChain) live here.
  • REST API — the wire protocol the Go and TypeScript SDKs target.
  • gRPC API — the proto surface, which the Go SDK now implements through the generated bindings in packages/fathom-go/proto/.
  • Go SDK — gomarkdoc output for the clients described above.
  • TypeScript SDK — typedoc output for @fathom-rules/sdk.