Skip to content

Integrations

Every GraphMind adapter exposes the same shape, so the debugger works the same way whatever you write your agents in:

const gm = graphmind({ app: 'my-agent' });
gm.wrapClient(client); // or gm.wrapModel(model) / gm.handler() for LangChain
gm.wrapTools({ ... }); // gates each tool call
gm.run(name, fn); // one run, one AbortController, one agent node
await gm.ready(); // wait for the debugger handshake (optional, recommended)

What differs is only what each framework’s extension points allow — the LangGraph page has the honest matrix for the one case where a callback-only path cannot do everything.

One integration has no code surface at all. graphmind mcp-proxy sits between an MCP host and an MCP server and debugs the server without touching it — any language, including servers you did not write.

Adapters are built strictly on public extension points — middleware, callback handlers, client hooks, tool decoration. No forks, no monkey-patching of module internals, nothing that breaks on your framework’s next minor release.

GuaranteeMeaning
Never throws into your appInternal failures degrade to a no-op plus one rate-limited warning
Identity when disabledwrapClient / wrapTools return the very object you passed in
Fast path when detachedGates resolve from a shared promise; events go to the ring buffer only. packages/client/test/overhead.test.ts asserts an average and a p99 under 1 ms per awaited gate.
Auto-continue on disconnectEvery held gate releases with continue, within 100 ms (packages/client/test/session.test.ts)
instanceId on every eventCorrect attribution when the same node runs concurrently
Kill switches honouredGRAPHMIND_DISABLED=1; off under NODE_ENV=production unless GRAPHMIND=1

What each adapter can actually do, and how each cell is known. A framework’s extension points decide what is possible. A callback can hold work but cannot replace a result; a wrapper that owns the call site can.

Legend:

  • ✅ exercised by a test in that adapter’s own suite.
  • ◐ provided by the shared session runtime (@graphmind-ai/client, or the Python / Ruby session) and tested there, but not through this adapter.
  • ○ in the code, but no test pins it.
  • ⚠ available, with the caveat in the footnote.
  • ❌ not possible at this attachment point.
Adapter / attachment pointbefore LLMbefore toolafter toolon errorinjectretryloop holdGRAPHMIND_HIDE_*GRAPHMIND_DISABLED
@graphmind-ai/sdk (AI SDK)✅ holds before the request; abort only¹✅○²✅ tool✅ tool✅ tool◐◐✅
@graphmind-ai/anthropic✅ abort only¹✅✅✅ tool✅ tool✅ tool◐◐³✅
@graphmind-ai/openai✅ with inject, retry and an after gate✅○²✅ LLM and tool✅ LLM and tool✅ LLM and tool◐◐✅
@graphmind-ai/langgraph, callback handler✅✅observe only✅❌ warns, continues❌ warns, continues◐⁴◐✅
@graphmind-ai/langgraph, wrapped tools—✅✅✅✅✅◐◐✅
@graphmind-ai/mcp (in-process)✅ sampling✅✅✅✅✅◐◐✅
graphmind mcp-proxy✅ sampling✅✅ response gate✅ JSON-RPC error and isError✅✅ re-sends the request✅✅✅⁵
Python @gm.tool / wrap_tools—✅✅✅✅✅✅✅✅
Python OpenAI / Anthropic create✅ with inject and retry——✅✅✅—◐✅
Python Anthropic messages.stream✅ in __enter__——✅❌❌—◐✅
Python LangChain handlers✅✅observe only✅❌ warns, continues❌ warns, continues✅⁴◐✅
Ruby gm.tool / wrap / wrap_method—✅✅✅✅✅✅✅✅
Ruby ruby-openai✅ with inject——✅✅✅—◐◐
Ruby RubyLLM✅ with inject and retry✅○✅✅ LLM and tool✅ LLM◐◐◐
  1. The AI SDK and Anthropic adapters hold a model call before the request goes out, and abort works there. inject and retry are treated as continue at that gate. A provider error is recorded and rethrown to your loop, not held.
  2. The code calls the after gate (packages/ai-sdk/src/wrap-tools.ts, packages/openai/src/wrap-tools.ts), but no test in that package pins a pause at after on a tool.
  3. The security suite’s export audit runs a real Anthropic-adapter agent through graphmind record (security/tests/export-redaction.test.ts). That covers export redaction, not the GRAPHMIND_HIDE_* switches.
  4. A loop hold at a callback-only gate holds, but inject there degrades to continue, as at any callback gate. Python’s case is tested (test_a_langchain_tool_called_through_the_callback_handler_is_held); the TypeScript handler’s is not.
  5. With GRAPHMIND_DISABLED=1 the proxy relays bytes, records nothing, and says so on stderr: GraphMind is disabled in this environment (…); relaying only, nothing is recorded (packages/cli/test/mcp-proxy-cli.test.ts).

The loop hold and the GRAPHMIND_HIDE_* switches live in the session every adapter emits through, so ◐ there means the same code path as the ✅ cells, reached through a different adapter. The session tests: packages/client/test/loop-hold.test.ts, redaction-session.test.ts, python/tests/test_loop_guard.py, test_redaction.py, ruby/test/test_loop_guard.rb, test_redaction.rb. The per-framework pages go deeper: the LangGraph matrix and the Python matrix.

Every row is something CI runs. A runtime or version CI does not run is not claimed.

Runtimes (.github/workflows/ci.yml):

Runs on
npm packages and the CLINode 22.x and 24.x × Linux, Windows, macOS. engines.node >=22.13.
CommonJSEach of the eight packages is packed, installed from the tarball and require()d, on Node 22 on Linux and Windows (cold-package-smoke).
Python SDKPython 3.10 and 3.13 on Linux and Windows. requires-python >=3.10.
Ruby gemRuby 3.1 and 3.3 on Linux; the gem is built and installed into a clean GEM_HOME. Not published to RubyGems yet.
ViewerThe built bundle in headless Chromium (Playwright).

SDK versions (.github/workflows/sdk-compat.yml). Each adapter’s own suite runs with the SDK pinned at the floor and at the ceiling of its declared peer range:

AdapterDeclared peer rangePinned in CI
@graphmind-ai/sdkai >=6 <86.0.270 (floor, partial: one suite, because the test fixtures use an ai@7-only mock), 7.0.0, 7.0.83
@graphmind-ai/anthropic@anthropic-ai/sdk >=0.60.0 <10.60.0, 0.121.0
@graphmind-ai/openaiopenai >=5 <85.0.0 (two tests skipped for an upstream gap fixed in 6.45.0), 6.45.0, 7.7.0
@graphmind-ai/langgraph@langchain/core >=0.3.40 <2, @langchain/langgraph >=0.3 <2core 0.3.40 + langgraph 0.3.0; core 1.2.9 + langgraph 1.4.13
@graphmind-ai/mcpoptional peers: @modelcontextprotocol/sdk >=1.26.0 <2 or @modelcontextprotocol/server >=2 <31.x: 1.30.0 from the lockfile in ci.yml, plus 1.26.0 through an aliased install (test/peer-compat.test.ts). 2.x: 2.0.0, the only 2.x release, so floor and ceiling are the same.
graphmind mcp-proxyany MCP server over stdioAgainst real SDK servers with the 1.x client, and with the 2.0.0 @modelcontextprotocol/server and client in both the 2025-11-25 and 2026-07-28 protocol eras

A weekly canary runs each adapter against that day’s latest of its SDK. It is advisory and does not block a release.

Python extras declare floors (openai>=1.40, anthropic>=0.34, langchain-core>=0.3), and the Ruby test group installs ruby-openai and ruby_llm. CI installs whatever currently resolves for those, so the floors are declared but not run — except ruby_llm, whose last 1.x runs in its own cell next to the newest 2.x, because the two majors hook different private methods. For how long each runtime stays supported, see stability.

Two paths, in increasing order of effort:

  1. Import a trace you already produce. graphmind import trace.json accepts OTLP/JSON and flat OpenInference-style span lists and turns them into a run you can read in the viewer — history only, no live control. See other frameworks.
  2. Write an adapter. The wire contract is nine event types over one WebSocket, and @graphmind-ai/client already owns the session, the gate engine and the fail-open logic. A working adapter is a few hundred lines. The guide walks the whole thing.