public alpha · endpoint sensor

The sensor your SIEM
cannot get any other way.

EDR sees powershell.exe. It does not see which coding agent, which developer, or which MCP schema. Agentmetry records that on the laptop, with a hash chain a third party can verify, and forwards it into Splunk, Elastic, or Google SecOps. It is not a console, not a vendor cloud, and not a replacement for EDR or CNAPP.

Silent MSI. Intune user-context. Config from MDM. No callback home.

$ pip install agentmetry
$ agentmetry doctor

No account. No telemetry. Apache-2.0. Runs on the machine you already own.

EDR saw powershell.exe

this is what it missed

tool.command

Get-Content $env:USERPROFILE\.aws\credentials

agent.name
claude
actor.id
dev_01
initiator.actor_type
human
tool.qualified
PowerShell
mitre.technique_id
T1552.001
atlas.technique_id
AML.T0098

Illustrative values, real schema 1.2.0. That command is classified by the shipped mapper, not written here: it reads a credential file, so it earns T1552.001 and AML.T0098. Command capture is opt-in; the default hashes arguments and stores no command.

Records these coding agents

  • Cursor
  • Claude Code
  • Codex
  • Antigravity
  • Qwen
  • Kimi
  • Qoder
  • CodeBuddy

Hook coverage on these eight surfaces, plus an MCP stdio audit proxy. This list is what can be recorded. It is not a reading of the machine you are on.

Forwards into the console you already run

  • Splunk
  • Elastic
  • Google SecOps
  • Webhook

Native adapters. Loki is Grafana Alloy tailing the local JSONL, not a fourth native sink. Splunk TA ships with the pilot. Marks identify the consoles Agentmetry forwards into. No affiliation is claimed.

[ 01 ] the gap

EDR sees powershell.exe. It does not see the agent.

An EDR records that powershell.exe read %USERPROFILE%\\.aws\\credentials. It cannot tell you which coding agent invoked the shell tool, which developer prompted it, whether local policy allowed it, or whether the result left through an MCP server.

CNAPP inventories AI integrations in the cloud. LLM observability counts tokens. Neither one has the session on the laptop.

  • SOC and DevSecOps teams governing agents they did not choose.
  • Detection engineers who need fields, not adjectives.
  • Anyone who has to answer what the agent did, after the fact.
[ 02 ] where this sits

Complementary. It forwards into the stack. It does not replace it.

EDR

sees

The process. powershell.exe read a file. The IDE binary talked to the network.

does not see

Which agent, which prompt, which MCP server, which session.

CNAPP

sees

Cloud AI services, models, and MCP connections, agentlessly, from the cloud.

does not see

What those MCP servers returned to an agent on a laptop.

SIEM

sees

The logs you already collect. The control plane. Agentmetry lands here.

does not see

This telemetry, unless a sensor on the endpoint produces it.

Agentmetry

sees

Which agent, which human, which tool sequence, which MCP schema, with a verifiable trail.

does not see

Unmanaged ChatGPT, Copilot, and any IDE with hooks off. That is a stated limit.

Wiz inventories the AI integrations in your cloud. Agentmetry records what your developers' agents actually did on their machines, with evidence you can verify. Neither can see the other's data.
[ 03 ] product

The sensor. Your SIEM stays the console.

01 / cover

Coverage attestation

A heartbeat every 300s says the recorder is alive, which of 8 agent surfaces are covered, uncovered, absent, or unknown, how deep the spool is, and the MCP schema digest. Uncovered is the incident. Absent is Tuesday. You can tell which seats are actually recording, and the SIEM alerts when one stops.

02 / prove

A trail a third party can verify

Hash-chained JSONL on disk. RFC 6962 Merkle root on the heartbeat (1.2 KB inclusion proof against an 8.3 MB trail). External anchors. Evidence packs with SHA-256 manifests. agentmetry verify --trail walks it. Direct SIEM push is a copy, not the chain.

03 / detect

Sequence detection

15 built-in rules over the session, tagged with MITRE ATT&CK and, on the AI-specific subset, MITRE ATLAS. Credential access then egress is one finding. The public benchmark covers 13 of those rules on 50 recorded sessions. Findings are events, not blocks.

04 / ship

Deploys like a sensor

Silent Windows MSI, Intune user-context Remediation, hooks installed in the developer profile rather than LocalSystem, config from MDM. No vendor cloud and no data egress unless you set a sink. Not EV-signed. Not run against a real tenant yet.

what a heartbeat says about each surface
covered
agent is here and its hook is in place
uncovered
agent is here and is NOT recorded. The incident
absent
agent is not on this machine. Tuesday
unknown
cannot be determined, so neither is claimed

A key, not a status board. This page cannot see your machine and does not claim to. `absent` and `uncovered` are kept apart because collapsing them is what made an earlier build degrade every heartbeat forever, until operators learned to ignore the one signal that mattered.

hook_coverage.SURFACES8 checkable
covered
hook is in config
uncovered
agent present, hook missing
absent
not on this machine
unknown
service profile
  • Cursorsupported
  • Claude Codesupported
  • Codexsupported
  • Antigravitysupported
  • Qwensupported
  • Kimisupported
  • Qodersupported
  • CodeBuddysupported

The eight agent surfaces Agentmetry can record. States are per machine, per beat, and this board is the list rather than a reading of it: it does not claim any of these are covered on the machine you are reading it from.

mcp_schema.FINGERPRINTper beat
mcp_schema_digest
what tools/list actually returned. runtime
mcp_config_digest
what the config file declares. inventory
the signal is the conjunction

schema moved and config did not

A rug pull keeps the command line identical and changes what the server hands the model. postmark-mcp shipped fifteen clean versions first. Config alone never sees it.

Empty until a server is listed through the audit proxy. That is a gap, not a healthy default, and the beat reports it as empty rather than as clean.

Capture surfaces today: Cursor, Claude Code, Codex, Antigravity, Qwen, Kimi, Qoder, CodeBuddy, plus an MCP stdio audit proxy. Lead with the schema fingerprint, not the config digest: a rug pull leaves the config file identical and changes tools/list. Codex reports covered once the hook file is present. Codex also skips untrusted hooks silently, which a file check cannot see.

[ 04 ] fleet

Packaged like a sensor, not like a SaaS trial.

Silent MSI

Enterprise package. Ingest ships in the frozen binary, so a machine with no git checkout can still capture. Not EV-signed. Not a clean-room certified build.

Intune, user context

Remediation pair deploys hooks into the developer profile, not LocalSystem. Remediations need Plan 2 or Windows Enterprise E3/E5, not base Intune. Not run against a real tenant.

Config from MDM

Sinks, fleet_id, and heartbeat interval are environment. No vendor portal. No callback home.

Doctor as an exit code

agentmetry hooks status: 0 compliant, 1 needs remediation, 2 undeterminable. Deployment tooling can fail a device without scraping a dashboard.

[ 05 ] what it emits

Canonical JSON, schema 1.2.0. A detection engineer can key on these fields today.

Illustrative values, real schema. This sample is a credential-shaped Read (T1552.001). A generic file read tags T1005. The trail hashes tool arguments in the hook process, so the secret itself is not in the record. Query the technique id, not the label.

action.type = tool_calledschema doc
Full event · schema 1.2.0
{
  "schema_version": "1.2.0",
  "event_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "seq": 42,
  "session_id": "sess-abc",
  "correlation_id": "thread-8892",
  "timestamp_utc": "2026-07-12T09:14:22.041+00:00",
  "host_id": "dev-laptop",
  "fleet_id": "consulting-pilot",
  "source_topic": "external/claude/tool_called",
  "source": {
    "tier": "external",
    "app": "claude",
    "adapter": "claude_hook"
  },
  "initiator": {
    "actor_type": "human",
    "trigger": "manual",
    "operator_id": "dev_01"
  },
  "actor": {
    "type": "user",
    "id": "dev_01",
    "role": "operator"
  },
  "action": {
    "type": "tool_called",
    "outcome": "success",
    "reason": ""
  },
  "agent": {
    "name": "claude",
    "skill_id": ""
  },
  "tool": {
    "name": "PowerShell",
    "qualified": "PowerShell",
    "server": "claude",
    "input_redaction": "hash+command",
    "input_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "parameters_redacted": false,
    "command": "Get-Content $env:USERPROFILE\\.aws\\credentials",
    "mitre": {
      "tactic_id": "TA0006",
      "tactic": "Credential Access",
      "technique_id": "T1552.001",
      "technique": "Credentials In Files"
    },
    "atlas": {
      "framework": "MITRE ATLAS",
      "tactic_id": "AML.TA0013",
      "tactic": "Credential Access",
      "technique_id": "AML.T0098",
      "technique": "AI Agent Tool Credential Harvesting",
      "atlas_version": "2026.07"
    }
  }
}
agent.name

Which coding agent invoked the tool.

actor.id

Which human the run is attributed to.

initiator.operator_id

Same human, from the run origin, not a client header.

action.type

tool_called, heartbeat, detection, mcp_schema, and the rest.

action.outcome

success, denied, degraded, or the detection severity.

tool.mitre.technique_id

Query the id. The label text can change.

correlation_id

One agent session. Sequence detections key on this.

tool.input_hash

Arguments are hashed in the hook. Secrets stay off the trail.

host_id

Hostname, not a cryptographic identity. Per-host signing is an Enterprise feature, not an open-core roadmap item.

A firing rule is its own event: action.type: detection, action.outcome carries the severity. Alert with action.type:detection AND action.outcome:critical without learning the rule vocabulary.

[ 06 ] label

Two frameworks, about three percent of each, published as three percent.

ATT&CK describes what the agent did to the host. ATLAS describes what was done to or through the agent. Both can sit on one event, describing different things about it.

MITRE ATT&CK
19 / 697
techniques mapped, 10 tactics · Enterprise v19.2

what the agent did to the host

MITRE ATLAS
5 / 178
techniques mapped, 5 tactics · 2026.07

what was done to or through the agent

why not all of it

Most of ATT&CK is not reachable from here. It covers a whole intrusion: phishing for initial access, SMB for lateral movement, rootkits for evasion. Agentmetry watches one boundary, the tool calls a coding agent makes, so the techniques it could ever see are the ones an agent can perform with a file, a shell, a network call or an MCP server. 697 is the size of the matrix, not the size of the opportunity.

and some of it is a gap

Not every miss is out of reach. An archive built before an upload is T1560 and currently reads as T1059. A copy to cloud storage is T1567.002 and reads as T1059. A scheduled task the agent registers is T1053. Those are observable at this boundary and are not mapped yet, which is a backlog rather than a boundary.

A sensor that labels every call has labels that carry no information. The mapper tags what it recognises and leaves the rest blank, so two ATLAS techniques are deliberately never emitted: `AI Agent Tool Invocation` is true of every event this records, and `Command and Scripting Interpreter` is ATLAS restating ATT&CK. Both would have tripled the count and told a SOC nothing.

where ATLAS earns its place

An MCP server that ships clean, gets adopted, then swaps its advertised tool schema underneath the model has no honest ATT&CK id. The nearest is T1195, which is compromise of a distribution channel, not a running server changing its tools between calls. ATLAS names it exactly.

AML.T0109 · AI Supply Chain Rug Pull · Defense Evasion

Filed under Defense Evasion because the scrutiny happens at adoption and not at update. postmark-mcp shipped fifteen clean releases before the one that mattered.

Not an official mapping. No MITRE validation and no MITRE evaluation. Every id was resolved by name against the published matrix rather than from memory, and the ATLAS labels are newer than the ATT&CK ones by a long way.

[ 07 ] how it works

Four stages, all on the endpoint.

01

Capture

IDE lifecycle hooks and the MCP proxy record tool calls. Arguments are SHA-256 hashed in the hook process. agentmetry hooks install writes configs for agents present in that profile. If the orchestrator is down, events spool and replay.

02

Normalize

Events become canonical JSONL v1.2.0 with MITRE tags and a tamper-evident hash chain on the file sink. Detections and triage decisions append to the same chain.

03

Attest

A heartbeat every 300s carries hook coverage, spool depth, MCP config digest, MCP schema digest, and the Merkle root. Silence becomes a finding. Schema change does not degrade the beat; hook removal does.

04

Forward

Optional. The same trail can stream to Splunk, Elastic, Google SecOps, or a CloudEvents webhook. Loki tails the file. The local trail remains the source of truth.

heartbeat fields a SIEM can alert on
heartbeat.hooks_uncovered

Agents installed here whose hook is missing. The incident.

heartbeat.mcp_schema_digest

SHA of the tools/list the model was handed. Runtime, not inventory.

heartbeat.mcp_config_digest

SHA of the configured MCP command lines. Inventory, weaker signal.

heartbeat.trail_merkle_root

RFC 6962 commitment that lands in the SIEM, off the endpoint.

heartbeat.spool_depth

Events buffered because the orchestrator was down.

heartbeat.interval_seconds

Default 300. Silence after two missed beats is the finding.

saved search · degraded recorder
index=main sourcetype=agentmetry:json action_type=heartbeat action_outcome=degraded

The process is up, the port answers, and the agents on that machine are no longer recorded. A liveness ping cannot see this.

saved search · MCP schema change
index=main sourcetype=agentmetry:json action_type=mcp_schema action_outcome=changed

Config digest unchanged, schema digest moved: the tools/list the model was handed is not the one you inventoried.

local operator view · optionallocalhost
Pinned credential-exfil detection with expanded event detail in the local Agentmetry dashboard

The SIEM is the control plane. This dashboard is a local convenience. The trail on disk is the source of truth.

[ 08 ] integrations

Forward into the console you already run.

Nothing leaves the machine unless you set a sink. There is no vendor cloud and no hosted control plane.

Splunk HEC

Native adapter. Sourcetype agentmetry:json.

Elastic ECS

Native adapter.

Google SecOps UDM

Native adapter, posted as UDM.

Webhook

Canonical JSON, or CloudEvents 1.0 structured mode (application/cloudevents+json).

Loki

Not a native adapter. Grafana Alloy tails the local JSONL, which keeps the chain envelope that direct push strips.

Splunk TA

Private add-on (TA-agentmetry). Search-time fields for heartbeat.hooks_uncovered, hook_profile, mcp_schema_digest, trail_merkle_root. Not on Splunkbase, not AppInspected.

Product names and marks belong to their owners and appear here to identify what Agentmetry forwards into. No affiliation, partnership, sponsorship or endorsement is claimed by any of them.

Microsoft AGT audit files can be read back in. DLP is 18 regex rules in a YAML pack, default mode log. Tool policy also defaults to log. Block mode exists; it is not how a stock install behaves. MITRE tactic and technique ids are on the event; query the ids.

[ 09 ] evaluate / deploy

Two paths. No cart.

The sensor is Apache-2.0. The MSI, Intune, and Splunk TA live in a private repo and ship as a design-partner pilot. There is no third SKU until a real tenant has run the installer.

Path 01 · evaluate

Open source

Free · Apache-2.0

  • pip install, doctor, trail, detections, SIEM forwarders.
  • You run it on a machine you control. No account, no demo gate.
  • Issues and PRs on GitHub. One maintainer reads them.

Path 02 · deploy

Design partner

90 days · up to 25 seats

  • MSI, Intune Win32, Splunk TA, 4h remote implementation.
  • Fee is scoped in the SOW, not listed here.
  • Source archive at every delivery, perpetual licence, Apache-2.0 grant if the maintainer stops.
[ 10 ] what it does not do

The honest limits.

It is not a CASB.

It records the agents you wire in. An unmanaged ChatGPT tab, Microsoft 365 Copilot, or Cursor with hooks removed is invisible. That is network and endpoint policy territory.

It is a recorder, not a sandbox.

It does not stop an agent that avoids the hooked tools. DLP and tool policy default to log. Block mode is the only pre-execution stop, and it is off unless you turn it on.

Approvals are inferred.

When a tool runs after an ask, the trail may include an approval_response flagged inferred:*. That is a reconstruction, not a workflow the product owns.

Tamper-evident is not attributable.

The hash chain proves ordering and non-modification of what was written. Anyone with write access can build a well-formed chain. Per-host identity is an Enterprise feature, not an open-core roadmap item. The core stays single-machine by design.

Covered is not capturing, for Codex.

Codex trusts hooks by hash and skips untrusted ones silently. The heartbeat cannot see that decision.

It is alpha, and one maintainer.

APIs may still change. Fleet MSI and Intune scripts exist and have not been run against a real tenant. The Splunk TA is not on Splunkbase. The Apache-2.0 core is the floor: trails, detections, and forwarders do not depend on a vendor remaining in business. Enterprise pilots get a perpetual license, a source deposit with each delivery, and an automatic Apache-2.0 grant on a Continuity Event (cessation, insolvency, or incapacity). That clause lives in the pilot SOW, not as a slogan.

Benchmark, checkable from a pip install: 50 cases (26 attack, 24 benign), 13 of 15 rules covered, zero misses and zero false positives on that corpus. agentmetry benchmark

Know what was recorded. Know what was not.

Start on a machine you control. If the fleet packaging is what you need, the second path is a mailbox, not a cart.