Coding agents and desktop telemetry
Stream Claude Code, Claude Cowork, Cursor, Codex CLI, GitHub Copilot, Gemini CLI, and Kiro activity into Reagent from developer machines, and roll out Claude Desktop under the gateway.
The tiles on this page sit in section 03, AI tools, on the Connections page. They work differently from the API pull connectors on AI tools. Nothing here polls a vendor API. Each tile pushes telemetry from developer machines into the environment's data lake, through the agent's native OpenTelemetry export, a lifecycle hook, or a managed settings channel that the vendor distributes for you.
Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not. Until it is active, the tiles cannot show an ingest endpoint and nothing will land.
Connecting requires the manage integrations permission (Administrator, MSSP Admin, or a custom role with it). Some tiles also need a role in the vendor's own admin console. Each section says which.
How these tiles report
- The Claude Code and Cursor tiles show a Connected Devices list of the machines that have reported, and check every 30 seconds. The other tiles show a connection status card with event and host counts. Every tile flips to Active on the first event. Claude Cowork, GitHub Copilot, Gemini CLI, and Kiro check when you open the tile and again hourly in the background. Codex verification is measured in its setup dialog, described in that section.
- Reagent cannot tell which machines did not receive a policy. It learns that a machine exists only when that machine reports. Silence right after a push is expected until the agent restarts and sends its first event. For delivery status, check your MDM console.
- Raw events are searchable in Lake, one table per agent.
What the telemetry feeds
- Discover inventories these discovery signals from the telemetry, all live-validated from the data lake: IDE Coding Agents, Agent Tool Calls in MCP Servers, MCP Servers (Local), MCP Servers in Cloud Applications, AI Meeting Bots. They read
claude_code_events,cursor_events, andcowork_events. The other tables feed only AI Prompts & Model Routing/Use, through template packs that are not yet validated, and no pack readskiro_eventsyet. Each section says which. - Monitor ships detector packs for Claude Code, Claude Cowork, and Cursor.
- Optimize reads token and cost figures from
claude_code_events,cowork_events,copilot_events, andcodex_events.
| Tile | Connector | Transport | Lands in |
|---|---|---|---|
| Claude Code | claude-code | Native OpenTelemetry, pushed by Anthropic managed settings | claude_code_events |
| Claude Cowork | cowork | Native OpenTelemetry, configured in claude.ai | cowork_events |
| Cursor IDE Agent Monitoring | cursor-ide | Hooks staged by a generated install script | cursor_events |
| OpenAI Codex CLI | codex | Native OpenTelemetry in config.toml, optional gateway routing | codex_events |
| GitHub Copilot | github-copilot | Native OpenTelemetry in VS Code settings | copilot_events |
| Gemini CLI | gemini-cli | Native OpenTelemetry in .gemini/settings.json | gemini_cli_events |
| Kiro | kiro | Lifecycle hook script | kiro_events |
Claude Desktop is not a credential tile. Its fleet rollout under the gateway is covered in Claude Desktop under the gateway.
Claude Code
Connector: claude-code · Auth: per-environment API key, embedded in the OTLP header of the generated settings.json · Requires: any plan, plus the Primary Owner or Owner role in your Anthropic organization
Claude Code sends its native OpenTelemetry stream to Reagent: user prompts, tool results, API requests, cost, and token metrics, with full session attribution. This tile is observe-only. It applies no permission rules, hooks, or block decisions, so it can never block a developer.
Lights up: IDE Coding Agents, Agent Tool Calls in MCP Servers, MCP Servers (Local), MCP Servers in Cloud Applications, AI Meeting Bots. Monitor ships a Claude Code detector pack, and Optimize reads cost and token usage from claude_code_events.
Before you start
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- You need the Primary Owner or Owner role in your Anthropic organization to edit managed settings.
- If the environment's Zaun Agent Gateway is enabled, read the gateway notes below before you push anything.
Setup
There are two steps: copy the generated JSON, paste it into Anthropic's managed settings. No per-machine install and no restart.
- In Reagent, open Connections and click the Claude Code tile.
- Click Copy settings.json. The Connections page generates this JSON for the environment. The real API key is embedded in the OTLP header, and the Copy button always copies the unmasked, paste-ready payload. Treat it like a secret and do not share it.
- Open claude.ai Organization settings. From any claude.ai page: click your workspace name in the top-left, then Settings. In the left sidebar, switch from your personal settings to Organization settings.
- Under Products, select Claude Code. Scroll to Managed settings (settings.json) and click Manage.
- Paste the JSON into the settings.json editor, then click Add settings. Anthropic distributes the configuration to every Claude Code session in your organization within about 60 seconds.
- Trigger a Claude Code action (any tool use) and watch the Connected Devices card on the tile. It flips to Active on the first event and checks every 30 seconds.
- If nothing arrives, click Run Connection Diagnostics on the tile.
Gateway notes
These apply only when the environment's Zaun Agent Gateway is enabled.
- The generated JSON pins
ANTHROPIC_BASE_URLto your gateway. While pinned, Claude Code Remote Control (phone and web session pushes) does not work. Say so in your rollout communications. - If the environment requires a Zaun identity, the JSON carries the placeholder
__ZAUN_IDENTITY_TOKEN__insideANTHROPIC_CUSTOM_HEADERS. Replace it with a long-lived device token before you push, either inline or through your MDM or secret tooling. Mint the token under Identity & keys. Until it is substituted, Claude Code requests to the gateway are rejected.
Roles
| Where | Role | Purpose |
|---|---|---|
| Reagent | manage integrations | Open the tile, copy the generated settings.json, run diagnostics |
| Anthropic organization | Primary Owner or Owner | Edit Managed settings (settings.json) under Products, Claude Code |
What Reagent reads
Events land in claude_code_events in Lake. Rows carry:
- Event type: prompt submitted, tool result, API request, API error, and permission decision, plus metric series for token usage, cost, session count, lines of code, commits, pull requests, code edit decisions, and active time. Session start and end rows are sent only by hook scripts on the developer machine; this observe-only setup installs no hooks, so they do not appear.
- Tool name, tool input, and tool output. Output is truncated at 10 KB.
- Policy decision columns (
decision,block_reason). The setup on this page is observe-only and does not produce block decisions. - Model,
prompt_id(links every event from one prompt turn),cost_usd, input and output tokens, cache read and cache creation tokens, and duration. - Hostname, OS username, and session id. Git remote and branch context is also hook-sourced and does not appear with this setup.
- MCP server name, MCP tool name, and skill name, when
OTEL_LOG_TOOL_DETAILS=1is set in managed settings. - Full prompt text only when
OTEL_LOG_USER_PROMPTS=1is set in managed settings. Otherwise only the prompt length is recorded.
The copied settings.json contains a live API key. Paste it only into the Anthropic managed settings editor. If the gateway is enabled and the environment requires a Zaun identity, a JSON pushed with the __ZAUN_IDENTITY_TOKEN__ placeholder still in place makes every Claude Code request to the gateway fail until you replace it.
Claude Cowork
Connector: cowork · Auth: per-environment API key, entered in the OTLP headers field in claude.ai · Requires: any plan, plus the Primary Owner or Owner role in your Anthropic organization
Claude Cowork emits native OpenTelemetry for desktop agent activity. You configure the exporter once inside your Anthropic organization and Anthropic pushes it to every Cowork desktop session. There is no agent install. All configuration lives in claude.ai. Anthropic's own guide is at Monitor Claude Cowork activity with OpenTelemetry.
Lights up: MCP Servers (Local), MCP Servers in Cloud Applications, AI Meeting Bots. AI Prompts & Model Routing/Use also reads cowork_events, through a template pack that is not yet validated. Monitor ships a Claude Cowork detector pack, and Optimize reads token and cost figures from cowork_events.
Before you start
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- You need the Primary Owner or Owner role in your Anthropic organization.
- Keep the Connections page open next to claude.ai. You will copy three values from it: the OTLP endpoint, the OTLP headers value (
x-api-key=<key>), and the resource attributes.
Setup
- In Reagent, open Connections and click the Claude Cowork tile. The tile shows the OTLP endpoint, the API key (click Reveal & copy real value), the OTLP headers value, and the resource attributes generated for the environment. If the tile says no ingest endpoint is configured, activate the data lake under Settings → Data Lake first.
- Open claude.ai Organization settings. From any claude.ai page: click your workspace name in the top-left, then Settings. In the left sidebar, switch from your personal settings to Organization settings.
- Under Capabilities, select Cowork. Scroll to the Monitoring section. The four fields live there.
- OTLP endpoint: paste the endpoint from the Connections page.
- OTLP protocol: choose
http/json. Reagent's ingest accepts only the HTTP/JSON transport. gRPC and protobuf are rejected. - OTLP headers: paste the value from the OTLP headers box on the tile. The value is
x-api-key=<key>, and the copy button pulls the real key into that format. Anthropic stores it encrypted and masks the field after save. - Resource attributes: paste the comma-separated list from the Connections page. These tag every emitted span with your tenant.
zaun.tenantroutes events into the correct environment, so cross-tenant mixing is impossible even if the same API key is shared by mistake. - Click Save in the Monitoring panel. Anthropic pushes the configuration to every Cowork desktop session in the workspace within about 60 seconds. No client restart is needed.
- Run a harmless Cowork action, for example ask it to open an app or take a screenshot. Events land in
cowork_eventswithin a minute. - Back on the tile, the credential shows Pending first event, then Active. The tile checks when you open it, and a background check re-runs hourly. Either one promotes it on the first event.
Fields
| Field in claude.ai | Value | Purpose |
|---|---|---|
| OTLP endpoint | Generated on the Connections page | Where Cowork sends spans |
| OTLP protocol | http/json | The only transport Reagent's ingest accepts |
| OTLP headers | x-api-key=<key>, copied from the OTLP headers box on the tile | Authenticates the export. Independently revocable from the Claude Code key |
| Resource attributes | Generated on the Connections page, comma-separated, includes zaun.tenant | Routes events to the correct environment |
What Reagent reads
Events land in cowork_events in Lake, isolated from claude_code_events so the two agents keep independent retention and detector rules. Rows cover:
- User prompts.
- Tool and MCP invocations.
- File access, read and modify, with the approval state.
- Skill usage.
The Cowork detector pack on Monitor uses this telemetry to flag prompt injection (including the Files API exfiltration class), credential theft through mounted folders, auto-approval abuse of destructive tools, cross-connector data aggregation, and MCP supply-chain attacks.
Anthropic masks the OTLP headers field after you save and never displays the key again. If you need it later, reveal and copy it from the Connections page. This key is separate from the Claude Code key. Revoking one does not affect the other.
Cursor IDE Agent Monitoring
Connector: cursor-ide · Auth: generated install script that stages Cursor hooks for the environment · Requires: any plan
Cursor has no native OpenTelemetry export, so this tile installs hooks on developer machines through a generated install script. The default is monitor mode: it records and reports activity without denying actions. Published enforce-mode artifacts can deny configured command, file, and prompt violations.
Lights up: IDE Coding Agents. Monitor ships a Cursor detector pack.
Before you start
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- For fleet rollout, an MDM that can run a script policy against a device scope.
- For a direct install, root on macOS or Linux (
sudo), or an Administrator PowerShell on Windows.
Setup
Fleet rollout through MDM:
- In Reagent, open Connections and click the Cursor IDE Agent Monitoring tile.
- Choose macOS / Linux or Windows, then click Generate Install Script. The Connections page generates
install-cursor.shorinstall-cursor.ps1for the environment. Click Download. - Under Deploy through MDM, choose the tool or platform that will run the script. The tile shows deployment directions for that target, summarized under MDM targets below.
- Push the artifact as a script policy to a small pilot device scope.
- On a pilot machine, quit and reopen Cursor. Hooks take effect only after a restart.
- Verify: confirm
hooks.jsonexists in the Cursor config directory, start a Cursor session, and run any agent command. The machine should appear in Connected Devices within 1 to 2 minutes, and new rows should appear incursor_eventsin Lake. - When the pilot machines appear in Connected Devices, widen the MDM policy scope to the intended fleet.
Direct installation for one machine. Use this for a one-off or a test machine; fleet deployment should use the MDM script policy above.
- macOS or Linux: download or copy the script to the machine, run
chmod +x install-cursor.sh, then runsudo ./install-cursor.sh. - Windows: open PowerShell as Administrator and run
.\install-cursor.ps1. - Afterwards, run the same verification checks as step 6.
MDM targets
| Target | Directions |
|---|---|
| Jamf Pro | Use the Bash file from the macOS / Linux tab; Jamf Pro deploys it to managed Macs only. Add it under Settings > Computer Management > Scripts, then add it to the Scripts payload of a computer policy. Set the trigger and execution frequency, then scope the policy to pilot computers or a pilot smart group. Policy scripts run as root. |
| Microsoft Intune | Create separate scripts and assignments for macOS and Windows; one policy does not deploy both files. macOS: upload the Bash file to Shell scripts, set Run script as signed-in user to No so it runs as root, and assign it to a pilot Entra device group. Windows: upload the PowerShell file to Platform scripts, set Run this script using the logged on credentials to No so it runs in system context, disable signature enforcement unless you sign the file, use the 64-bit PowerShell host, and assign it separately to a pilot device group. |
| Kandji | Use the Bash file; Kandji Custom Scripts run on enrolled Macs only. Create a Custom Script Library Item, paste the file into the Audit Script field, choose an install-once execution frequency, and assign the item to a Blueprint containing only pilot Macs. Custom Scripts run as root. |
| Workspace ONE | Create a separate Scripts resource per platform: the Bash file for macOS, the PowerShell file for Windows. It does not deploy to Linux. Set Execution Context to System, assign each script to a pilot Smart Group, and publish it with a run-once trigger. |
| Other / manual | Use the Bash file for macOS or Linux, or the PowerShell file for Windows. Deliver it with the script runner your organization already trusts, to a small pilot group first. Run Bash as root and PowerShell as Administrator or an equivalent system context. |
For every target, the console reports success when the script exits 0. That does not prove Cursor is reporting. Cursor loads hooks at startup, so the machine stays absent from Connected Devices until the developer quits and reopens Cursor.
Machines without Cursor
The installer looks for Cursor's own binary. When it finds none, it writes nothing and exits successfully, and the run output ends with Install skipped. Exiting successfully is deliberate, so MDM does not retry the policy forever on machines that simply do not run Cursor. Detection only knows the standard install locations. To stage hooks anyway, for a Cursor installed somewhere unusual or a fleet you want pre-staged before rollout, re-run with --force (-Force on Windows).
What Reagent reads
Events land in cursor_events in Lake. The table has the same core shape as claude_code_events, from hook events only:
- Event types: PreToolUse, PostToolUse, SessionStart, SessionEnd, policy_violation, compliance_check.
- Tool name, tool input, and tool output.
decisionandblock_reason.- Hostname, username, session id, and metadata.
- No
prompt_id, cost, token, or cache columns. Cursor does not export those.
Connected Devices shows only machines that have reported. If a pilot machine is absent, the policy may not have been delivered, Cursor may not have been restarted, or the machine may not run Cursor at all. Those cases look identical here. Check your MDM console for delivery status.
Claude Desktop under the gateway
This is not a credential tile and it ingests nothing. It is the Claude Desktop 3P tile at the front of section 03, AI tools, on the Connections page. Pilot observations render below that grid once a device fetches a profile. Use it when you want Claude Desktop inference to pass through the environment's Zaun Agent Gateway instead of going straight to Anthropic.
Default Cowork does not route through the Zaun Agent Gateway. The Claude Cowork tile above gives you telemetry from that default posture. This section gives you custody of the traffic itself.
How it works
The governed posture is Cowork on 3P:
- Claude Desktop sends Anthropic-compatible inference to the environment's custody listener.
- The listener authenticates the client, through OIDC/SSO or a Zaun device token.
- The gateway attaches the organization credential upstream.
The device never holds the upstream Anthropic key.
Before you start
- The gateway is enabled for the environment, with a stable public HTTPS custody hostname.
- Upstream inference is configured, either as an organization Anthropic API key or as AWS SigV4 for Claude on AWS.
- The custody profile path targets macOS devices on a Cowork-capable Claude Desktop build, enrolled in MDM. The Claude Desktop 3P bootstrap dialog also renders Windows artifacts (Intune Windows and Group Policy, as ADMX and ADML files).
- 3P mode replaces claude.ai subscription inference for the whole desktop app. Plan the rollout with that in mind.
- Google Workspace is not supported as the identity provider on this path. Do not deploy it from the wizard.
- You need the agent-enforcement management permission to arm bootstrap or change the generated artifact. Without it, the Claude Desktop 3P dialog is view only.
- Gateway setup itself is documented on AI gateway.
Setup
Custody profile, on Enforce:
- In Reagent, open Enforce → Gateways → Zaun Agent Gateway → Identity & keys → Authentication & key custody.
- Under Client tokens & Cowork enrollment, click Generate profile, then choose the client authentication method: OIDC / SSO or Device-token placeholder.
- For device tokens, mint one device token per managed Mac (TTL up to 90 days) and keep its device label in inventory. Never reuse a device token across the fleet.
- Download the generated macOS
.mobileconfig, or the plain managed-preferences.plistif your MDM prefers it. - Substitute
__ZAUN_DEVICE_TOKEN__and, if present,__ZAUN_COWORK_OTLP_API_KEY__through your MDM secret tooling. A placeholder left in place makes every request from that device fail. - Upload the resulting
.mobileconfigto the device scope in your MDM and push it. - Fully quit and reopen Claude Desktop on each device. The config is read once at launch.
- Verify sessions at the gateway as devices pick up the profile.
If a Claude Code managed-settings.json is present on the same Macs, it can silently override the Desktop profile, including coworkEgressAllowedHosts, unless it sets parentSettingsBehavior: "merge". No error is produced. If you also push Claude Code managed settings to this fleet, including through the Claude Code section at the top of this page, set parentSettingsBehavior: "merge" there first.
Bootstrap dialog, on Connections:
- Open Connections and click the Claude Desktop 3P tile. The dialog has four steps.
- Identity provider. Claude Desktop must send a JWT access token with an exact configured
issandaud, requiredexpandnbfclaims, and a signature using RS256/384/512, PS256/384/512, ES256/384/512, or EdDSA. Entitlement lookup joins onoidorsuband falls back only to email. Leave entitlement cutover off during the pilot: when it is on, an absent assignment is a deny, so anyone not yet provisioned and assigned is locked out. Turn it on only for full deploy. - MDM. Pick the target: Jamf Pro, Intune macOS, Kandji / Iru, Mosyle, Workspace ONE macOS, Intune Windows, Group Policy Windows, or Generic / manual. Download the Direction pack and the Pilot profile for that target. Both are bound to the current profile revision. Push the pilot profile to a pilot device scope.
- Review. Five readiness conditions must pass:
response_schema_valid(the rendered bootstrap response validates against the supported schema),idp_token_verified(a current token from the configured identity provider was verified),deployment_organization_uuid_matches(the MDM artifact and the bootstrap response use the same deployment organization UUID),current_revision_fetched(at least one real device fetched the current revision), andscim_and_entitlement_cutover(SCIM provisioning, assignment, and entitlement cutover are active). - Deploy to everyone. This arms bootstrap for the next MDM push. It is not a live switch: deploying changes what the MDM artifact contains, so it takes effect on the next MDM push, and reversing it needs a push too. Reverting serves the last good response, but a refetch does not change a running session. Users on a bad configuration stay on it until they relaunch.
What the Claude Desktop 3P tile shows
The tile reports bootstrap readiness: blocking checks, the target-specific artifact for your MDM, and arming the next MDM push. Pilot observations render below the AI tools grid once a device fetches a profile. Zaun reports which devices fetched. It cannot know how many were targeted, so it never shows a total.
The tile never changes a running Claude session.
Listener hostnames, upstream credentials, and client authentication are configured on Enforce, not on Connections. See AI gateway for the full gateway guide.
OpenAI Codex CLI
Connector: codex · Auth: Observe lane: a provisioned ingest key in config.toml. Control lane: the environment gateway listener · Requires: any plan. The Control lane needs the gateway enabled with a listener hostname
Codex CLI exports OpenTelemetry under the GenAI semantic conventions. Codex setup has one shared dialog on the Connections page: Observe telemetry, Control gateway routing, delivery, the exact generated config, and measured verification all live together there.
Lights up: AI Prompts & Model Routing/Use, through a template pack that is not yet validated. No other Discover pack reads codex_events yet. Optimize reads token and cost figures from codex_events.
The two lanes
| Lane | Config | Prerequisite | What it gives you |
|---|---|---|---|
| Observe | An [otel] section in config.toml, sending OTLP over HTTP to the environment's Codex ingest endpoint | Data lake active, plus a provisioned key. No gateway | Telemetry in codex_events |
| Control | openai_base_url pointed at the environment gateway | Gateway on, with a listener hostname | Real-time rejection before the request leaves the machine, DLP prompt guard, tool rules, budgets, kill and freeze scopes, model routing |
The Observe lane runs async ABBA (embed, cluster, classify, dedup, alert, investigation) on every event. The Control lane adds the inline gate (embed, per-environment kNN vote, LLM confirm, reject in flight) on the newest message only. It fires only on a decisively adversarial neighborhood, so it adds no latency. Deploy both lanes to get both.
Control's detector gets sharper the more Observe has run. Observe builds the vector history that Control reads. With no labeled history, the inline score is NOVEL and nothing blocks. Events missed at ingest are not examined later, because there is no catch-up path.
Before you start
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- Rendering config that may contain a live credential requires the agent-enforcement management permission.
- For the Control lane, the gateway must be enabled with a listener hostname. See AI gateway.
Setup
- In Reagent, open Connections and click the OpenAI Codex CLI tile, then click Open Codex setup.
- Pick a lane: Observe or Control.
- Choose delivery: MDM delivery or Single machine test. For MDM delivery, pick a target. The managed install path depends on the OS: macOS uses the
com.openai.codexpreference domain (Codex has no managed-config file path on macOS), Linux uses/etc/codex/managed_config.toml, and Windows uses%ProgramData%\OpenAI\Codex\managed_config.toml. - Review the rendered
config.toml. The Connections page renders it for the environment. It contains a live ingest credential. Regenerate and redistribute the package, or fetch a replacement config for a test machine, after that key rotates. - Copy or download the package.
- Distribute it through the delivery path you chose, then open the dialog's Verify step. For Observe it shows events in the last 30 days, distinct hostnames in 30 days, and last seen. For Control it sorts hosts into four coverage buckets:
governed(telemetry seen and routing through the gateway; Control confirmed on that host),shadow(telemetry seen, never routed; Observe works, Control did not land),gateway_only(routing with no telemetry; Control landed, Observe is missing), and attribution incomplete (account_unconfirmedorgateway_env_unattributed, not a governance verdict). A host absent from every bucket remains unknown. Zaun cannot distinguish a machine that never received the config from one that has not relaunched.
Single machine test, for one developer machine:
- Merge the exact rendered
[otel]table into~/.codex/config.toml. - Keep
exporterandotlp_http_endpointexactly as rendered. - Keep the rendered
[otel.otlp_http_headers]value, then run a Codex session.
This test path enforces nothing on any OS. A developer can remove an edit to ~/.codex/config.toml or override it with -c.
Identity
| Where | Fields |
|---|---|
| In the data lake | host.name, user.email, user.account_id, conversation.id |
| At the gateway | session-id, chatgpt-account-id, x-codex-installation-id request headers |
What Reagent reads
Events land in codex_events in Lake:
- Tool calls, API requests, prompts, and cost and token metrics, as Codex CLI emits them.
- Hostname, username, and session id.
- Model,
prompt_id,cost_usd, input and output tokens, cache tokens, and duration, when the event carries them. - MCP server and tool names, skill name, and
file_path, when populated. - OTLP trace, span, and parent span ids, and the span name and status.
- Full prompt text only if prompt logging is enabled. Otherwise the prompt length.
OpenAI has not published the exact event_type, tool_name, and model values for Codex CLI's OpenTelemetry export. Search codex_events in Lake over a broad time range to see the values your fleet actually sends before writing Monitor rules that assume specific strings. In the Observe lane, decision and block_reason are always null; there is no hook emitter for Codex. Treat missing cost or token values as not reported, not zero.
GitHub Copilot
Connector: github-copilot · Auth: per-environment API key in the github.copilot.chat.otel.otlpHeaders object · Requires: any plan
Copilot Chat in VS Code and Copilot CLI export OpenTelemetry under the GenAI semantic conventions, pushed from each developer machine. This tile is separate from the GitHub org tile on Developer tools. That tile reads GitHub's org REST API with a different credential and covers seat assignment, org-wide usage summaries, and audit log entries. The two are not merged.
Lights up: AI Prompts & Model Routing/Use, through a template pack that is not yet validated. No other Discover pack reads copilot_events yet. Optimize reads token and cost figures from copilot_events.
Before you start
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- Decide how you will deliver the settings: one machine to test, or the whole org through MDM.
Setup
- In Reagent, open Connections and click the GitHub Copilot tile. The tile shows the VS Code
settings.jsonkeys generated for the environment and the API key (click Reveal & copy real value). If the tile says no ingest endpoint is configured, activate the data lake under Settings → Data Lake first. - Choose a delivery method (see the table below). Both use the same keys.
- Set the three OpenTelemetry settings keys exactly as shown on the tile:
github.copilot.chat.otel.enabledtotrue,github.copilot.chat.otel.exporterTypeto"otlp-http", andgithub.copilot.chat.otel.otlpEndpointto the endpoint generated on the Connections page.exporterTypemust be"otlp-http", not"otlp-grpc". Reagent's ingest accepts only HTTP/JSON; gRPC is rejected. - Add the API key as
"x-api-key"inside the separategithub.copilot.chat.otel.otlpHeadersobject, alongside the settings from step 3. - Use Copilot Chat or Copilot CLI on a configured machine. The tile shows Pending first event, then Active.
| Delivery method | Best for | Notes |
|---|---|---|
Single-machine settings.json | Fastest to test with | Edit one developer's VS Code settings.json directly |
| Org-wide managed settings | A whole engineering org | Pushed through MDM or a managed-settings.json file. Individual developers cannot opt out or misconfigure it |
What Reagent reads
Events land in copilot_events in Lake:
- Tool calls, chat completions, and suggestions, as Copilot emits them.
- Hostname, username, and session id.
- Model,
prompt_id,cost_usd, input and output tokens, cache tokens, and duration, when the event carries them. - MCP server and tool names, skill name, and
file_path, when populated. - OTLP trace, span, and parent span ids, and the span name and status.
- Full prompt text only if prompt logging is enabled. Otherwise the prompt length.
Exact managed-settings key names can shift between VS Code Copilot releases. If the keys shown on the tile do not appear in your installed extension, verify them against that version's documentation. GitHub has not published the exact event_type, tool_name, and model values for Copilot's export, so search copilot_events in Lake to see what your fleet sends before writing Monitor rules that assume specific strings. decision and block_reason are always null for Copilot device telemetry.
Gemini CLI
Connector: gemini-cli · Auth: x-api-key in otlpHeaders · Requires: Gemini Code Assist Enterprise or equivalent enterprise licensing
Gemini CLI is Google's terminal coding agent. It has native OpenTelemetry export and no hook mechanism, so this is a pure OTLP push configured in .gemini/settings.json or through GEMINI_TELEMETRY_* environment variables.
Lights up: AI Prompts & Model Routing/Use, through a template pack that is registered but disabled pending validation. No other Discover pack reads gemini_cli_events yet.
Before you start
- This is an enterprise-licensed tier feature only. Google ended the consumer and free Gemini CLI telemetry offering on June 18, 2026. If your org is not on Gemini Code Assist Enterprise or equivalent enterprise licensing, this setup will not work regardless of configuration, and deployments still pointing at the retired consumer service show no events.
- Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- This is not the same tile as Gemini in Google Workspace. That connector pulls Workspace admin and audit data over OAuth. The two do not share credentials.
Setup
- In Reagent, open Connections and click the Gemini CLI tile. The tile shows the
telemetryblock generated for the environment and the API key (click Reveal & copy real value). If the tile says no ingest endpoint is configured, activate the data lake under Settings → Data Lake first. - Add the
telemetryblock to.gemini/settings.json(project-local) or~/.gemini/settings.json(a user-wide default).otlpProtocolmust be"http". Reagent's ingest accepts only OTLP over HTTP/JSON; gRPC is rejected. - If you prefer environment variables over the settings file, set the same values with
GEMINI_TELEMETRY_OTLP_ENDPOINTandGEMINI_TELEMETRY_OTLP_PROTOCOL. - Add
"x-api-key"with the key tootlpHeadersin the sametelemetryblock, or set it as theGEMINI_TELEMETRY_OTLP_HEADERS="x-api-key=<key>"environment variable instead. - Restart any running Gemini CLI sessions to pick up the new config, then run a command. Events land within a minute or two. The tile also re-polls hourly in the background.
| Setting | Environment variable | Value |
|---|---|---|
| OTLP endpoint | GEMINI_TELEMETRY_OTLP_ENDPOINT | Generated on the Connections page |
otlpProtocol | GEMINI_TELEMETRY_OTLP_PROTOCOL | "http" |
otlpHeaders | GEMINI_TELEMETRY_OTLP_HEADERS | "x-api-key" with the key from the Connections page. As an environment variable, the value is "x-api-key=<key>" |
What Reagent reads
Events land in gemini_cli_events in Lake, normalized onto the same columns as the other agent tables:
gemini_cli.user_prompt: prompt length and prompt id. Prompt text only when you opt in withlogPromptsorGEMINI_TELEMETRY_LOG_PROMPTS.gemini_cli.tool_call:function_name, duration, and the execution outcome (success,decision,error).gemini_cli.file_operation: tool name, operation, lines, extension, and diff stats.gemini_cli.api_requestandgemini_cli.api_response:input_token_count,output_token_count,cached_content_token_count.gemini_cli.api_error,gemini_cli.slash_command, andgemini_cli.config.- Metrics: token usage, tool call count, API request latency, file operation count.
Gemini CLI's attribute vocabulary (function_name, input_token_count, and so on) differs from the gen_ai.* conventions other agents use, so some fields may parse less richly than for Claude Code or Codex until the mapping is verified against live traffic. This affects how richly events are parsed, not whether they arrive. Cost is not a Gemini CLI telemetry field; only raw token counts are real, so do not filter on cost_usd for this table. The decision on a tool call is an execution outcome, not a policy block: Gemini CLI has no enforcement layer. Google Antigravity has no telemetry export and is not covered.
Kiro
Connector: kiro · Auth: X-API-Key header, embedded in the generated hook script · Requires: Kiro for Enterprise
Kiro is Amazon Web Services' spec-driven AI coding agent (IDE, companion CLI, and IDE plugins). It has no native telemetry export. Its hook lane runs a shell command on lifecycle events (prompt, tool use, MCP calls, file access, block decisions) that POSTs to the environment's Kiro ingest endpoint. This is the one lane that captures tool, MCP, and block activity, and it is what this tile sets up.
Lights up: nothing yet. No Discover pack reads kiro_events today. Rows are still searchable in Lake.
Before you start
- Kiro for Enterprise is required (IAM Identity Center or external OIDC SSO plus the admin Kiro Console). Free and individual tiers expose no logging surfaces, so on those tiers
kiro_eventsstays empty. - Prerequisite: the data lake must be active for this environment. Activate it under Settings → Data Lake if you have not.
- You need the manage integrations permission in Reagent.
- For fleet coverage, a way to place a file on every machine: a repo commit plus MDM.
Setup
- In Reagent, open Connections and click the Kiro tile. The tile shows the hook POST endpoint, the API key (click Reveal), and the generated
zaun-kiro-hook.sh. The script embeds the key in theX-API-Keyheader; the copy button pulls the real value in for you. - Save the script to
~/.kiro/hooks/zaun-kiro-hook.sh(user-wide) or to.kiro/hooks/in the repository (per-repo). - Run
chmod +xon it. - Register it in your Kiro hooks config for the lifecycle events you want to capture: UserPromptSubmit, PreToolUse, PostToolUse, SessionStart, Stop, PostFileCreate/Save/Delete.
- For fleet coverage, ship it through a repo commit plus MDM.
- Run a prompt in Kiro. The tile shows Pending first event, then Active.
Kiro's exact hook config format and the event context it exposes vary by version. The script reads common KIRO_* variables and falls back gracefully. Adjust the field names to your installed Kiro version if they differ. Unknown keys are still preserved in _raw.
Lanes
All lanes land in kiro_events, distinguished by the kiro_source column.
Lane (kiro_source) | Captures | Limits | Wired today |
|---|---|---|---|
hook | Tool calls, MCP usage, file access, PreToolUse block decisions | Best-effort, per-machine. A user can edit or remove the hook | Yes. This tile |
prompt_log | Full prompt and assistant response, inline completions | Highest fidelity, but no tool or MCP calls, model, tokens, cost, or policy decisions | Not yet. Uses Kiro's native S3 prompt logging |
activity_csv | Per-user daily identity plus a credit proxy | Credits are not tokens or dollars. No prompts, tool calls, or MCP usage | Not yet. Uses Kiro's daily S3 CSV |
cloudtrail | Coarse AWS admin and API audit for the Kiro service principal | Never in-IDE prompts, tool calls, MCP usage, model, tokens, or cost | Not set up from this tile |
What Reagent reads
From the hook lane, rows in kiro_events carry:
- Tool name, tool input, tool output, and MCP server name.
- File name or path for file events.
decision(blockwhen a PreToolUse hook denies a call) andblock_reason.- Prompt text on UserPromptSubmit, when the hook authors it.
- Hostname, session id, and username. Username is the OS user unless enriched with SSO identity.
Hooks are best-effort endpoint telemetry, not a tamper-proof audit trail. They live in .kiro/hooks/ or ~/.kiro/hooks/ as local config with no central admin enforcement, and coverage depends on the hook reaching every machine. No model id, token counts, or dollar cost exist in any Kiro export; do not compute token or dollar spend from this table. Absence of a block decision is not proof nothing was blocked. A machine may simply have no hook deployed.
AI tools
Connect the AI platforms your teams use, from Claude and ChatGPT to Copilot, Atlassian Rovo, Snowflake Cortex, ServiceNow, Slack, Agentforce, Devin, Glean, Perplexity, and Replit, through their admin, compliance, and audit APIs.
AI Gateway
Put an inline control point in front of agent LLM and MCP traffic: the built-in Zaun Agent Gateway, or the LiteLLM, agentgateway, Kong, AgentCore, Azure AI Foundry, and Google gateways you already run.