Skip to content

Feature matrix

Telem ships six surfaces: a typed Python SDK (with optional OpenAI and LangChain integrations layered on top), an MCP server, a Claude Skill, and three coding-agent plugins — OpenClaw, opencode, and pi. They don’t all support the same things. This page is the side-by-side comparison; each surface’s own page has the full detail.

Legend: ✅ supported · ➖ not applicable to this surface · ❌ missing

Feature Python SDK MCP server Claude Skill OpenClaw plugin opencode plugin pi package
V2 search block (tier / fields / providers)
Requires the server’s V2 normalized contract
Trajectory v5 identity (session/fingerprint/node identity) ✅ [note 1]
Flat message history sent with every search ✅ [note 1]
Automatic ancestor lineage across delegated/child agents ✅ [note 2]
Batch queries in one call ✅ [note 3]
telem_fetch (read whole pages, not just search snippets)
Rich result rendering (provider tags, answer/related, excerpts) ❌ [note 4]
Per-call config resolution from a project/home config file ➖ [note 5]
Blocks the host’s own web-search/fetch tools while enabled ✅ [note 6]
  1. Trajectory identity and message history, Python SDK column: the bare Telem/AsyncTelem client has no trajectory concept at all — this is support from the optional OpenAI wrap or LangChain tool integrations, not the client itself. The LangChain tool only sends history when LangGraph injects a ToolRuntime (i.e. called from inside a graph); called directly, it’s history-free by design.
  2. Ancestor lineage, Python SDK column: supported, but explicit rather than automatic — the caller passes parent=<wrapped client> to the OpenAI wrap, or calls create_telem_child_config() for the LangChain tool, at the moment it delegates to a child agent. OpenClaw, opencode, and pi all derive ancestry automatically by walking the host’s own session/conversation tree.
  3. Batch queries, Python SDK column: search() itself accepts a list of queries and batches them into one interaction. The OpenAI-wrap’s and LangChain-tool’s model-facing tool schemas still accept only one query per call, though — batching isn’t exposed to the model in either integration, only to a caller using the client directly.
  4. Rich result rendering, Python SDK column: calling search() directly already gets you everything this row is about, as typed data — SearchResponse/ProviderRun carry provider attribution, answer, related, and partial-failure status natively. This row is specifically about a pre-rendered text block for feeding a model, and the built-in formatter the OpenAI-wrap and LangChain-tool integrations use for that only emits URL/Title/Content — no provider tags, no answer/related, no excerpt budget, and a failed provider run doesn’t render a line at all.
  5. Per-call config resolution, OpenClaw column: OpenClaw resolves options fresh on every tool call too, but from the host’s own plugin config plus environment variables — it has no project/home config-file layer of its own the way opencode and pi do. See OpenClaw configuration.
  6. Blocks the host’s own web tools, opencode column: opencode denies its built-in webfetch permission by default while the plugin is loaded (opt out with TELEM_ALLOW_BUILTIN_WEBFETCH=1) — opencode has no separate built-in web-search tool to block. OpenClaw’s equivalent blocks both its built-in web_search and web_fetch outright. See opencode and OpenClaw.

In rough priority order:

  1. The Python SDK has no fetch surface. OpenClaw, opencode, and pi all ship telem_fetch; the bare client has no fetch() method, so neither the OpenAI wrap nor the LangChain tool can expose one either.
  2. The OpenAI-wrap and LangChain-tool schemas don’t expose batch queries to the model. The core SDK accepts a query sequence and preserves each run’s batch_index, but both integrations’ tool schemas still accept one query per invocation.
  3. The Python SDK’s built-in text formatter is minimal. The formatter the OpenAI-wrap and LangChain-tool integrations use to render results for a model emits URL/Title/Content only — no provider attribution, no query-level answer/related block, no excerpt budget, and a failed provider run is silently invisible rather than rendering one line. (Code reaching for the full data directly — SearchResponse/ProviderRun — sees everything; this gap is in the text rendering only.)