Skip to content

Supported Agents

Not all agents work the same. Lander supports four agents today, but “supported” means something different on each: Claude Code and Codex expose every prompt, response, and exact token count; Claude Desktop takes managed MCP servers but has no skills concept at all. This page is the reference for what will and won’t work on a given agent before you plan a rollout.

For the servers those agents connect to, see Supported MCPs. For the discovery mechanics see AI agents; for how interposition works see MCP mirroring.

Six things, in the order they usually matter to a rollout:

  • Inventory — read the agent’s own configuration and report what’s there: MCP servers, extensions and plugins, enabled state, transport. Reading only; Lander never sends the credentials it finds.
  • MCP management — install, update, and remove managed MCP servers through the Connector’s request → approve → install flow, and remove blocklisted servers wherever they appear.
  • Skills management — the same lifecycle for skills, content-addressed so a skill is refetched only when it actually changes.
  • Policy enforcement — allow or deny each tools/call, and filter tools/list so the model never learns a disallowed tool exists.
  • MCP tool-call telemetry — one event per MCP tool call: which tool, on which server, from which agent and device, allowed or denied, and how long it took. This is the MCP wire, not the model — it is not a record of LLM API calls, and it contains no conversation.
  • Prompt and response observability — the conversation itself: what the user asked, what the model answered, which built-in tools and skills it used, and what it cost. This comes from the agent’s own on-disk transcript, so it is a different mechanism from telemetry and it lands on different agents.

Telemetry and prompt observability answer different questions. Telemetry says “this agent called github.create_issue and it was denied.” Prompt observability says “here is the conversation in which it tried.” A proxied server gives you the first on every agent; only a transcript gives you the second.

Two conditions cut across everything below, and between them they explain almost every gap in the matrix:

  1. Enforcement and tool-call telemetry require proxied routing. A directly-routed server talks to the agent without Lander in the path, so there is nothing to enforce with and nothing to record. This is a property of the install, not of the agent — it applies equally on all four.
  2. Prompt observability and cost require a local transcript. Prompts, responses, thinking, built-in tool calls, exact token counts, the model name, and every cost figure derived from them come from the agent’s own on-disk logs. Claude Code and Codex both write them and both are read; Gemini CLI and Claude Desktop produce no equivalent artifact, so those rows are about missing data rather than a missing adapter.

These four have shipping adapters. The capability matrix refers to this set.

AgentIdentifierConfiguration sourceFormat
Claude Codeclaude-code~/.claude.jsonJSON (global + per-project scopes)
OpenAI Codex CLIcodex~/.codex/config.tomlTOML
Gemini CLIgemini-cli~/.gemini/settings.jsonJSON
Claude Desktopclaude-desktop~/Library/Application Support/Claude/claude_desktop_config.jsonJSON (flat)

✅ full · 🔵 partial, read the note · ❌ not available · — nothing of that kind on this agent

CapabilityClaude CodeCodexGemini CLIClaude Desktop
Inventory
MCP management🔵
Skills management
Policy enforcement
MCP tool-call telemetry
Agent configuration visibility🔵🔵
Prompt and response observability
Token and cost accounting🔵🔵
Connector visibility🔵

Two things to read out of this.

Claude Code and Codex behave identically. Inventory, MCP install and removal, skills, enforcement, configuration visibility down to hooks, and the full transcript stream with prompts, responses, and computed cost — the two adapters do the same work, and a rollout can treat them as one tier. Connectors are the only row where they differ, and only because Codex has nothing of that kind to see.

Claude Desktop’s marks are product constraints, not adapter gaps. It is stdio-only, so managed remote servers go through a bridge, and it has no skills concept for Lander to manage.

Uniform across all four agents. Lander reads each agent’s configuration and reports:

  • Config-declared MCP servers, local (stdio) and remote (http/sse) alike, with enabled/disabled state and classified transport. Gemini CLI additionally distinguishes sse (a url key) from http (an httpUrl key).
  • Bundled extensions and plugins — Claude Code plugins, Claude Desktop Extensions (DXT/MCPB, read from manifest.json), Gemini extensions, Codex plugins.
  • A proxied server still reports under its real name, not as a stub. Hiding it would make the Connector see it as missing and reinstall it forever.

Secrets stay on the device. The inventory omits command, args, and env; the Connector learns which servers exist, never the credentials they hold. Drift detection works on a fingerprint computed on-device and never transmitted.

What inventory covers is everything declared in a config file or bundled on disk. Servers authorized through an app’s own UI are a separate case — see Connector visibility.

Install, update, remove, restore, and blocklist enforcement work on all four agents, with a managed ledger so Lander only ever removes what it installed. Both routing modes are available everywhere: direct (the agent talks to the server itself) and proxied (lander serve-stdio --proxy <name> for stdio, or mcp-remote pointed at the local proxy for http/sse, with the calling agent’s identity in LANDER_AGENT_ID / X-Lander-Agent). Enforcement mode is set per kind, and an unset value fails safe to report-only. If the Connector is unreachable, the last known-good desired state still applies.

Claude Desktop is the 🔵. It is stdio-only, so managed remote servers are bridged through npx -y mcp-remote, and it takes credential values as command arguments rather than structured header fields — meaning a directly-routed credentialed server writes its credentials into claude_desktop_config.json. Route credentialed servers through the proxy on Claude Desktop so the credential stays with the proxy.

Claude Code is the only agent with a global vs per-project scope distinction, from the two-level ~/.claude.json layout.

Install, update, removal, and content-addressed (SHA-256) sync, under a per-agent root:

AgentSkill root
Claude Code~/.claude/skills
Codex~/.agents/skills (plus a machine-wide /etc/codex/skills)
Gemini CLI~/.gemini/skills

Claude Desktop has no skills concept — Extensions are its rough analogue, and those are inventoried, not managed. MCP and skill provisioning use separate allowlists, so approving a server for an agent does not approve a skill for it.

Deny-by-default on tools/call, with an explicit allow winning; disallowed tools are stripped from tools/list so the model never learns they exist. Identical on all four agents — and available only on proxied installs. A directly-routed server gets no enforcement anywhere.

Lander is read-only with respect to the agent’s own settings: it never writes an agent’s permissions or hooks.

One event per proxied MCP tool call, identical on all four agents: which tool on which server, the calling agent and device, the outcome (allowed / denied / error), the deny code, deny reason and rule applied, plus session ID and duration — enough for an audit to answer why a call was blocked, not just that it was.

Call arguments travel with every event, de-identified and truncated on-device. Payload capture (the content a server sends back — a query result set, a document body, a file listing) is opt-in per server through capture_payloads, off by default.

Events go through a bounded queue that never blocks a tool call, so a short tail can be lost if the process exits abruptly.

All four report a raw configuration snapshot with secrets redacted, and each adapter ships a note naming exactly what it does not read — Codex, for instance, records that cached tokens in auth.json are never opened and only the configured credential-storage mode is reported. What the snapshot contains differs by agent:

AgentCapability categories reportedPermissions and hooks
Claude Codeskill, plugin, command, subagent, connectorsettings.json passed through whole
Codexskill, command, plugin, profile, hook✅ hooks reported as their own category
Gemini CLIskill, extension, command
Claude Desktopextension

Claude Code and Codex are the two that surface the agent’s own permission and hook configuration; Gemini CLI and Claude Desktop are the 🔵 because they report capabilities but not that layer. Categories are free-form name/category pairs, so an agent can report a new kind without a schema change.

The transcript stream, on Claude Code and Codex:

  • Prompts, responses, and thinking, kept separate from one another
  • Tool inputs and results, including whether the result was an error
  • Built-in (non-MCP) tool calls — file edits, shell commands, and similar, which never travel over MCP
  • Skill invocations
  • The model name and exact token counts, reported by the model itself
  • Exactly-once delivery, via a local acknowledgement store that survives restarts

These are also correlated back onto the same agent’s proxied MCP events, backfilling the exact token counts and model name onto calls the proxy could only estimate.

The ingest channel on the Connector side is agent-agnostic: raw log lines are stored first and normalized second, so adding an agent is a matter of adding a reader for its on-disk logs, not new plumbing. On Gemini CLI and Claude Desktop, which write nothing comparable, a call can be attributed to an agent and a device but not to a model.

Cost is computed, not estimated from a rate card you maintain:

  • Per-model rates come from the LiteLLM public pricing dataset, cached locally with a pinned snapshot compiled in so a fresh or air-gapped device still prices correctly. Set USAGE_PRICING_OFFLINE to keep a deployment from reaching for the network at all.
  • Pricing is date-effective — a turn is priced at the rate in effect on the day it ran, not today’s rate. Input, output, cache-creation, and cache-read tokens are priced separately, including Anthropic’s higher 1-hour cache-write tier.
  • When a model appears that the dated history can’t price, the server backfills a rate and recalculates the affected sessions, so old figures don’t stay wrong.
  • On the device, lander renders a statusline with session and today’s cost plus context-window occupancy.

This chain starts from exact token counts, so it runs where the transcript does — Claude Code and Codex. On Gemini CLI and Claude Desktop, proxied calls carry token counts estimated from payload size, flagged as estimates by a token_source field, and no cost figure is derived from them.

Connectors — the MCP servers a user authorizes in a UI rather than declaring in a config file — are the one category endpoint tooling barely reaches. They are also the highest-privilege one, since they hold live OAuth access to Gmail, Drive, or GitHub under a real user’s account.

Claude Code is the 🔵: Lander reads claudeAiMcpEverConnected from ~/.claude.json and reports each entry as a connector capability (claude.ai Gmail, and so on). That gives you names, and nothing else — no auth scope, no last-used, and no removal signal, because the list is append-only and nothing clears it on disconnect. Read it as “this device has connected to these at some point,” which is genuinely useful for discovery and misleading if read as current coverage.

Claude Desktop is the ❌: it has connectors, and they are unreadable — they live in the app’s internal storage with their OAuth tokens in the OS keychain. Codex and Gemini CLI have no connector concept at all, which is why the matrix marks them rather than a gap.

Govern connectors through the provider’s admin console, and treat Lander’s list as a lead rather than an inventory.

These are absent everywhere, so they don’t appear as rows above.

Not supportedWhy, and what to do instead
Enforcement or telemetry on direct installsNo interposition point exists. Install proxied for anything that needs a policy applied or a call recorded.
Writing agent permissions or hooksRead-only by design. Lander never writes an agent’s own settings.json.
Connector auth scope, last-used, or removalEven where connector names are visible, the surrounding detail lives in the OS keychain and the app’s internal storage. See Connector visibility.
Machine-wide vs per-user install scopeNot distinguished in inventory. Claude Desktop is the only agent that separates the two locations on disk.
IDE inline completionsAutocomplete and fill-in-the-middle don’t travel over MCP, so no IDE agent will reach Claude Code-level coverage. Relevant to the agents in progress below.

Each agent below stores its MCP configuration in a local file in a format the adapter layer already handles or can extend to, so it follows the pattern in the matrix. Marks are confirmed per agent as its adapter ships.

Once an adapter exists, the agent appears in inventory and in the control plane’s agent views with no control-plane changes.

AgentIdentifierConfiguration sourceFormatWhat to expect
Cursorcursor~/.cursor/mcp.json (+ per-project .cursor/mcp.json)JSONMCP slice only
Windsurfwindsurf~/.codeium/windsurf/mcp_config.jsonJSONMCP slice only
ClineclineVS Code globalStorage/.../cline_mcp_settings.jsonJSONMCP slice only
Kilo Codekilo-codeVS Code globalStorage/.../mcp_settings.jsonJSONMCP slice only
GitHub CopilotcopilotVS Code settings.json / workspace .vscode/mcp.jsonJSONMCP slice only
Zedzed~/.config/zed/settings.json (context_servers)JSONMCP slice only
Kirokiro~/.kiro/settings/mcp.jsonJSONMCP slice only
OpenCodeopencode~/.config/opencode/opencode.jsonJSONFull CLI-agent pattern
Continue.devcontinue~/.continue/config.yamlYAMLFull CLI-agent pattern; needs YAML parsing
Goosegoose~/.config/goose/config.yamlYAMLFull CLI-agent pattern; needs YAML parsing
Claude Coworkclaude-coworkClaude desktop app config (Claude Desktop family)JSONClaude Desktop pattern
Google AntigravityantigravityConfirmed at ship timeConfirmed at ship time

Reading the last column:

  • MCP slice only — these are IDE agents. Lander sees agent mode plus MCP traffic; inline completions stay invisible to the proxy.
  • Full CLI-agent pattern — the Gemini CLI shape: inventory, managed install and skills, and proxied enforcement and telemetry. An agent that writes its own session logs can go further, as Claude Code and Codex do.
  • Claude Desktop pattern — inherits Claude Desktop’s constraints, including the stdio-only bridge for remote servers.
  • Needs YAML parsing — the adapter layer reads JSON and TOML today; these agents add a parser first.

Identifiers and exact paths are finalized when each adapter ships.

These agents run locally but don’t reach their tools through MCP, so there is nothing for the proxy to interpose on. An adapter can record that the application is present on a device — useful for inventory and policy — but it cannot emit tool-call events.

AgentWhy presence-only
AiderLocal git-native CLI, but drives its own built-in tool model rather than MCP
GranolaLocal macOS meeting app; the data path is system audio → vendor cloud
TactiqLocal transcript capture; activity goes to the vendor cloud
JamieLocal bot-free meeting capture; audio → vendor cloud

Browser-based AI — browser extension (planned)

Section titled “Browser-based AI — browser extension (planned)”

The largest gap by volume is AI that runs inside the browser, including agentic browsers that act under the user’s logged-in session. None of it touches a local MCP config, so the config-file-plus-proxy model cannot reach it. A browser extension to detect and attribute this usage, deployed alongside Lander, is planned.

  • Web chat: ChatGPT, Gemini, Claude.ai, Microsoft Copilot, Perplexity, Grok, DeepSeek.
  • Agentic browsers and computer-use agents: Perplexity Comet, OpenAI Atlas, Claude in Chrome, Gemini in Chrome / Project Mariner, Browser Use, Skyvern, Stagehand, MultiOn.

Cloud-only agents — out of endpoint scope

Section titled “Cloud-only agents — out of endpoint scope”

Fully hosted agents leave no footprint on the endpoint — no local config, no interposable transport — so neither the endpoint proxy nor a browser extension reaches them. Inventorying these belongs at the network, IdP, or CASB layer.

  • Cloud “digital coworkers”: ChatGPT Agent, Manus, Lindy, Microsoft Copilot Studio, Relevance AI, Martin, cloud-hosted Devin.
  • Cloud automation: Zapier, Make, Gumloop, Bardeen, cloud-hosted n8n and Activepieces.
  • Writing and knowledge SaaS: Notion AI, Grammarly, NotebookLM, Jasper.
  • Cloud meeting note-takers: Otter.ai, Fireflies.ai, Fathom, Read AI, tl;dv, Avoma, Grain.

Support for a new agent is an adapter in the Lander codebase that knows the agent’s config path and format and maps it into the common MCP shape. Once the adapter exists, the agent shows up in inventory and in the control plane’s agent views with no changes on the control-plane side.

Adding the adapter is what moves an agent from expected to verified — and the capability rows it lands on are whatever that agent’s configuration and transport actually support, not a copy of another agent’s row.