01 / Cross-org integration reliability

Your integration didn’t break. It started being wrong.

Every call succeeded. That’s why nothing caught it.

Flanj watches the calls your agents and services already make — agents most of all, since an agent reads a tool’s description to decide what to do. It catches the moment the other side’s contract moves, and carries evidence that organization can check against its own systems.

Out-of-band by design. The SDKs are Apache License 2.0; the collector is Elastic License 2.0. They run in your environment; no request or response body leaves it.

  • Schema drift
  • Tool description changed
  • Agent picks another tool
  • Missing webhooks
  • Tool renamed or removed
  • Perf. degradation
  • Tool output drift
  • Outages
  • Scheduled downtime
  • Tech support

02 / How it works

See what changed. Give both organizations the same context.

A / See what changed

The tool description changed. Your schema didn’t. Your agent started choosing differently and nothing anywhere logged an error.

This half works on its own, on day one, with nobody else’s permission.

One line to install, no source change. The SDK captures the request and response bodies of the calls your service makes and receives, and redacts sensitive fields inside your own process — before anything is written, stored or exported. The collector re-applies redaction, validates live traffic against the contract, and keeps a rolling window of redacted calls behind a UI on localhost.

Fig. 01 — REST needs a spec; MCP does not
RESTa spec somebody published

Flow: an OpenAPI spec, published separately, becomes the baseline only if one exists and is current; live calls are compared against that baseline to produce a finding.

Contract
OpenAPI spec
Published out of band. You paste its URL or upload the document.
if one exists, and is current
Compare
Live calls against the baseline
The calls your service makes.
Result
Finding
As good as the spec you were given.
MCPthe contract, from the server itself

Flow: the tools/list response, answered by the server itself, is the baseline from the first call; live calls are compared against it to produce a finding.

Contract
tools/list
The server answers it itself. The response is the spec.
from the first call
Compare
Live calls against the baseline
The calls your agent makes.
Result
Finding
For every MCP server it touches.
Dashed = present only under a condition.Same machinery either side — the difference is where the baseline comes from.

REST drift detection needs a spec somebody published and kept accurate. MCP servers publish their contract on every single call — tools/list is the spec. So the collector has the baseline from the first call your agent makes, for every MCP server it touches, with nothing to configure.

Fig. 02 — The collector UI, local and read-only

Every tab below works. It is the collector’s own UI with sample data and fictional counterparties — nothing here leaves your environment; the thread is the only thing that crosses the boundary.

Flanj Collectorlocalhost:5335 · sample data
Acme CorpConnected ↗
Drift detected on Globex
  • REST Globex · api.globex.example — 1 contract drift finding on GET /v1/orders/{id} — 14 calls since 2026-09-20 16:42:08.
No drift in the rest of what was checked: 1 REST provider · 1 inbound consumer.
observed here, by collector acme-prod
DescriptionInitech MCP reworded the description of search_orders. Wording only, no schema change.

Edges discovered from traffic — external only

Outbound4 providers · 2 of 3 providers checked against a contract · 1 MCP server self-reports theirs
CounterpartyStatusCallsFirst seenLast seen
Globexapi.globex.example12042026-08-022026-09-21 · 2m ago
Initech MCPMCPNewmcp.initech.exampleself-reported· tools/list862026-09-172026-09-21 · 6m ago
Umbrellaapi.umbrella.examplechecked572026-08-112026-09-21 · 3m ago
api.hooli.exampleNewnot checked92026-09-192026-09-21 · just now
Inbound1 consumer · checked against the contract you publish (self, v3.1)
CounterpartyStatusCallsFirst seenLast seen
Hoolihooks.hooli.examplechecked3122026-08-202026-09-21 · 1m ago
Flanj Collector · ELv2Redacted at source · outbound only · UI on localhost

Agent access

Your agents can ask it too: the collector answers over MCP on localhost, so a coding agent can check what actually changed on a dependency before it writes against it — read-only, and over the same local surface as the UI above.

Capture is out-of-band: it never sits in the path of your response, each body is capped at 16 KiB, and when it cannot keep up it tells you we stopped collecting — never that your integration went down. No request or response body leaves your environment.

Where this stops, said out loud. Node is supported; Python is early, and MCP only. A REST provider needs a spec — paste a URL or upload one — and an MCP server needs none. Flanj does not judge what your agent should have chosen; that call is yours. What it tracks is what the tool promised, and what it promises now. Where nothing has been validated against a contract, the collector says exactly that rather than showing you a green light.

B / Give both organizations the same context

Seeing it is half the job. The change is in somebody else’s code.

This half needs a counterparty — the one part you cannot install.

A detection becomes a flag only when it carries something the other organization can check against their own systems: their request ids, their responses, their spec version. The flag opens a thread both teams read, holding the same evidence and the same history, and the other side reads and replies without installing anything.

Read from the other direction: a flag that lands on you carries your own request ids and your own responses, redacted, and scoped to the call the sender pointed at. You can check it against your own logs without taking anybody’s word for it.

Where there is nobody to flag — a provider that will not answer, or one you have no relationship with — the first half still stands on its own: you know what changed, and when.

03 / Live from drift.flanj.io

The same classifier, run in public, every day.

drift.flanj.io is not a statistic assembled for this page. It is this product’s own contract and diff code — the packages the collector runs against your traffic — pointed at a public set of MCP servers you will recognize, once a day, with every snapshot and every caveat published beside the result. The figures below are read from that page. Nothing here is remembered.

The live figures could not be read from drift.flanj.io just now, so none are shown. The dataset itself is published there, updated daily.

We measure how often contracts move, in the open, on a public set of MCP servers — and publish the caveats next to the number.

04 / Open source

The half that reads your traffic is yours.

Capture, redaction, detection and storage are open and run inside your own environment. That is the half that touches sensitive and regulated traffic, so it is the half you get to read, audit and self-host.

Apache License 2.0

flanj-io/sdk

Supported · HTTP out + in, MCP client

An OpenTelemetry distribution for Node. Captures the request and response bodies of the HTTP calls your service makes and receives, and the tools/list and tools/call traffic of every MCP server your agent talks to. Redacts them in your process, and exports over OTLP.

Apache License 2.0

flanj-io/sdk-py

Early · MCP client only

The Python SDK. Instruments an MCP client session: records the tools/list each MCP server hands your agent and the tools/call traffic that follows, redacts it in your process, and exports over OTLP. It captures MCP client calls, not HTTP.

Elastic License 2.0

flanj-io/collector

Required · both SDKs export to it

A single-binary OpenTelemetry Collector distribution. Re-applies redaction, validates live traffic against the provider's contract, keeps a rolling window of redacted calls, and serves a local UI on localhost. Deploy it with the Helm chart, or run the image with Docker.

Run it

Preferred · stateless fronts and one store pod

  1. Step 1: Run the collector

    Both SDKs export to a collector you run yourself, so it comes first: nothing works without one. The Helm chart is the preferred way to deploy it — one install gives you stateless front collectors and one store pod, where the UI and the rolling window live. The token is a secret you generate, not one Flanj issues: the store serves the contracts you upload to the fronts over an in-cluster port, and will not open that port without it.

    From the collector README · Run it on Kubernetes — the README is the full setup, and the source of truth.

    Install the chart
    helm install flanj oci://registry-1.docker.io/flanj/flanj-collector \
      --namespace flanj --create-namespace \
      --set specToken.value="$(openssl rand -hex 32)"
  2. Step 2: Add the SDK

    Supported · HTTP out + in, MCP client

    No source change — the preload patches node:http and instruments every MCP client your app constructs. NODE_OPTIONS is that preload, so your image’s command does not change either. The SDK runs in your workload’s pod, where localhost is not the collector, so the patch names it. The chart answers at a fixed Service name — this line is the same on every cluster that ran the install above. node:http/node:https — and everything built on them (axios, got, node-fetch, superagent) — and, from@flanj/sdk 0.4.0, global fetch/undici are captured (see What is captured).

    From the sdk README · Quick start and the sdk README · On Kubernetes — the README is the full setup, and the source of truth.

    Install
    npm install @flanj/sdk
    Add to your container
    env:
      - name: FLANJ_OTLP_ENDPOINT
        value: http://flanj-collector.flanj:4318/v1/logs
      - name: NODE_OPTIONS
        value: "--require @flanj/sdk/register"
  3. Step 3: Open the local UI

    The UI is never a Service: it binds the store pod’s loopback, by design, and nothing the collector serves is reachable off-host. Port-forward to it, make a call, then open http://localhost:5335 — your calls are in Traffic, redacted. If 5335 is taken on your machine, forward 15335:5335 instead and open http://localhost:15335.

    From the collector README · Run it on Kubernetes — the README is the full setup, and the source of truth.

    Port-forward the UI
    kubectl -n flanj port-forward sts/flanj-flanj-collector-store 5335:5335
  4. Step 4: Connect it to Flanj (optional)

    The image and the chart already point at the hosted control plane, and the collector sends nothing until you press Connect. Open the local UI, Settings → Connect, and give it a collector name and a contact email — no token. The confirmation mail adds this collector to your workspace at app.flanj.io. Connect with the same email you sign in with there, or the collector lands in that person’s workspace instead.

    From the collector README · Point your app at the collector — the README is the full setup, and the source of truth.

Languages. Node — supported. Python — early, MCP only. A language is called supported here only once the whole loop runs on it end to end in our own harness; until then it says early, and says it everywhere.

05 / Contact

Got a question?

Write it here and it lands in a mailbox we read. We answer by email.

Ask

Your address is used only to reply to you. Separately, this page keeps which link brought you here in a 30-day cookie, so signing up can record it; there is no visitor id.