Skip to content
Console
Browse documentation
Guide

See every agent that is running

Ask your agent for the fleet and the asset inventory: which agents somebody declared, which ones Anectico found on its own, what needs review, and which credential each one is using.

On this page

You cannot govern an agent you cannot see. Your own agent can ask Anectico two questions. The fleet answers "what is running". The asset inventory answers "and what do we know about it", including the records nobody created on purpose. The agent reads both through MCP or the CLI. You decide what to do about what it finds.

Ask your agent

"Which agents ran in this project in the last 24 hours, and how many of their runs failed?"

"List the agents that nobody declared. For each one, which API key produced its telemetry?"

Job MCP tool or action CLI command
See the fleet with 24-hour run and failure counts list_agent_fleet anectico fleet list
List the inventory, filtered by kind, origin, owner, review state or risk list_agent_assets (read action) anectico asset list
Read one asset get_agent_asset (read action) anectico asset get
See every version of an asset list_agent_asset_versions (read action) anectico asset versions
Find which credential produced an agent's telemetry resolve_agent_asset_attribution (read action) anectico asset attribution
Read the review queue list_agent_review_signals (read action) anectico review-signals list
Read who authorized what list_authority_edges (read action) anectico authority-edges list
Declare an agent, workflow, tool or model register_agent_asset (confirmed write action) anectico asset register --file declaration.json --idempotency-key KEY
Record an owner for assets set_agent_asset_ownership (write action) anectico asset own
Approve or reject assets review_agent_asset (write action) anectico asset review
Classify the data an asset handles set_agent_asset_data_classification (write action) anectico asset classify
Withdraw a declared delegation revoke_authority_edge (write action) anectico authority-edges revoke
Declare what an agent depends on in a signed bill of materials sign_abom_manifest (write action) anectico abom sign
Read a signed bill of materials get_abom_manifest (read action) anectico abom get

Read actions are reached through list_read_actions and execute_read_action. Write actions are reached through list_write_actions and the execute tools; each one shows a preview first and applies only with the confirm_token that the preview returns. The key needs mcp:read and agents:read for the reads, and mcp:write and agents:write for the writes. See Scope recipes for agent jobs.

What your agent gets back

  • Fleet. One row per agent, workflow or A2A peer in the project, busiest first. Each row has the last 24 hours of activity (runs, and how many ended as anything other than completed), the count of open review signals, and the containment state. It also lists the row's immutable observation_keys. The response states the activity it could not account for. See Activity the fleet cannot account for.
  • Inventory. One row per asset, with its lifecycle state, review decision, assessed risk tier, data classification, owner team, owner principal, environment, whether it was declared or discovered, and when it was last seen. MCP marks customer-written environment text as untrusted. Use its whole value as a filter only when available is true; the marked display_label is for reading.
  • Attribution. For one asset or observation key, each observed identity and the credentials seen producing its telemetry. See What produced this agent's telemetry.

Open the proof

The fleet and the inventory have no proof page. They describe many things at once. To check one agent's work, ask your agent for its runs with list_agent_runs (or anectico agent-runs list). Each run row carries a link that opens the run as a read-only proof page, with its steps, tools, tokens and cost.

Stopping an agent is a human decision. Containment and revoking a key happen in the Console, in Agent safety (/agent-safety) and Agents and keys (/agents). See Contain an agent and Revoke an agent's access.

Declared and discovered are different things

Every record in the inventory has an origin, and the difference is the point of the page.

Origin What it means
Declared A person registered this agent. Its name is an identity somebody chose.
Discovered Telemetry created this record because something was running that nobody declared. Its name is evidence, not an identity. The CLI and the API call this origin shadow.

A discovered record is not an error and not an accusation. It is what an agent looks like before anybody has reviewed it. It behaves like any other record: you can read its activity, see which credential produced its telemetry, and contain it. What it has not had is a decision.

Every discovered record also opens a review signal, so "we found something" and "somebody dealt with it" stay separate questions. See What needs review.

The fleet

The fleet lists the agents, workflows and A2A peers in the active project, busiest first, with the last 24 hours of activity beside each one: how many runs, and how many of those ended as anything other than completed. A live containment shows as containment metadata on the row, and open review signals show as a count.

Activity the fleet cannot account for

Anectico matches a run to an inventory record by the stable observed identity carried with the run, not by its display name. Two agents may therefore use the same name without absorbing each other's runs. To read one agent's runs, your agent passes that row's observation_keys to list_agent_runs (agent_observation_keys) or to anectico agent-runs list --agent-observation-key <key>. The name remains a label. The run list therefore stays on the selected agent after a rename and does not widen to another same-named agent.

There are still two gaps, and the response states them rather than hides them:

  • Runs that named an agent with no record in this project. The record may live in another environment, or the inventory has not caught up with a new agent yet.
  • Runs that carried no mapped observed identity and reported no agent name at all. Nothing can attribute those to an inventory record. The fix is in your instrumentation: set an agent name (gen_ai.agent.name or agent.name) on the spans your agent emits, and the discovery path can create and map the record.

If either number is non-zero, the response says so. A read that quietly dropped those runs would show a calm fleet over a busy one.

The list uses cursor pagination. Its 24-hour activity window ends at the first page's read snapshot, and the opaque continuation keeps later pages on that same window. has_more comes from the same ordered population as the page, rather than from a count taken at another instant. The totals describe the complete measured population, not only the rows on one page.

The window selects a run when any of its steps started during those 24 hours. Once selected, the fleet folds the complete run, including an earlier root, so its stable identity and terminal outcome do not disappear merely because the execution crossed the window boundary.

An empty fleet is a successful measurement with zero agents. If inventory or activity cannot be measured, the read fails instead of returning an empty, apparently healthy fleet. Containment is a separate permission: without it, containment_visibility is WITHHELD, which is not evidence that no agents are contained.

The inventory

The inventory is more than the agents. A row is an agent, a workflow, a tool or a model. Eleven more kinds exist in the vocabulary (MCP servers, A2A peers, gateways, model routers, prompts, retrieval corpora, memory stores, sandboxes, skills, workload identities and policies); see below for what they are. Your agent can filter by kind, and by origin: all, declared or discovered. "All" is the default deliberately: it is a different question from "declared", and starting at "declared" would hide exactly the records worth looking at.

What gets discovered from telemetry, and what does not

Four kinds appear on their own, from standard agent telemetry, with nothing to configure:

Kind Discovered from Identity
Agent A declared agent id or name, else the emitting service Per project and environment
Workflow A declared workflow name on a span that also names its agent Scoped to that agent — two agents' main are two workflows
Tool A declared tool name, with its type Shared across the project: one tool, however many agents call it
Model The provider plus the model that actually served the call Shared across the project

A model that was requested and then replaced by a different served model does not become its own row. The row is the model that ran; the substitution is still visible on the call itself.

Every other kind is never an inventory row. Nothing in today's telemetry conventions identifies an MCP server, a sandbox, a prompt, a retrieval corpus or a policy in a way that stays the same between calls — an MCP session id, for instance, changes every time a client reconnects, so a row keyed on it would be a new row per reconnect rather than a record of the server. Rather than guess, Anectico records no inventory row for those kinds. They are valid as component kinds in a signed bill of materials (sign_abom_manifest over MCP, or anectico abom sign), where you declare what an agent depends on. Filtering the inventory on one of them is refused with 400 and a message naming the kind, so that a refusal is never mistaken for an empty page that means "none were seen".

Which agent uses this tool

A tool and a model are one shared record however many agents call them, so the caller is recorded as a link rather than folded into the record. Pass a tool's or a model's id as related_asset_id and Anectico lists the agents observed using it. Pass an agent's id and it lists the workflows, tools and models that agent uses.

The link is only recorded when a single span named both — the tool and the agent running it. Some frameworks do not repeat the agent's identity on a tool call, so an empty list means "no telemetry linked them", never "unused".

Each row carries its lifecycle state, its review decision, its assessed risk tier, its environment and when it was last seen.

What produced this agent's telemetry

Ask for the attribution of an asset or of an observation key. Anectico lists each observed identity that maps to that asset and the credentials seen producing telemetry under it, with a sighting count and a last-seen time. A credential used once and one on today's hot path are therefore distinguishable before you act.

Three of the answers are not API keys, and each means something different:

What you see What it means
An API key id A containment or a revocation can act on this.
A signed-in person's session There is no key to revoke; the control is that person's access.
A development-only trust setting No credential was presented at all, and nothing can revoke it. Outside development, this means that setting is on where it should not be.
Nothing recorded Not the same as "no credential was used" — nobody recorded one for this identity. A containment naming this asset may reach nothing.

This is the read to run before containing an agent: containment is only a request until something can name the credential to stop. See Revoke an agent's access.

What needs review

The review queue (list_agent_review_signals, or anectico review-signals list) collects six conditions that need a person to decide what happens next:

Signal What it means What to do What clears it
Undeclared agent discovered Something is running that nobody registered. Declare it, or contain it. Recording a review decision on the asset
No review decision An asset has been in the inventory past the review window and nobody has approved or rejected it. Decide. Recording a review decision on the asset
No owner An asset has been in the inventory past the same window with neither an owner team nor an owner principal. Name an owner. Setting either owner field
Configuration disagrees with its attestation The configuration in the field is not the one that was attested. Find out which is right. Registering a matching configuration
No registered configuration to compare Nobody can tell whether it drifted, because no configuration was ever registered. Register one. Registering one
Credential seen on a killed agent Telemetry authenticated by the named API-key id resolved to the named agent while the named kill containment was active. Inspect the key and containment, then revoke the key or lift the containment as appropriate. Revoking the key, or lifting the containment

"No registered configuration" is not a quieter version of "disagrees with its attestation". "We cannot see this" reported as "this is clean" is the failure the separate signal exists to prevent. The same reasoning separates the review and owner gaps: they are answered by different people through different writes, and an asset can have either without the other. To check a signed bill of materials or attestation yourself rather than trusting a summary, see Verify attestations.

The review and owner windows exist so that discovery is not itself an alert. A newly discovered asset is given a grace period — 24 hours unless your deployment changes it — before either gap is raised. Retiring an asset clears both, because a retired asset needs no owner and no decision.

Each discovered asset carries its lifecycle, current review decision, owner team and owner principal. To record a decision, the agent calls review_agent_asset, or you run anectico asset review. The key needs agents:write. A reason is required. After the write, the asset shows the reviewer, reason and review time, so the decision never becomes an unexplained label. An approval does not lift a quarantine: a quarantined asset stays quarantined until its lifecycle is changed through the separate containment workflow.

To set owners, the agent calls set_agent_asset_ownership, or you run anectico asset own. The write replaces the asset's team and principal assignments. Leaving a value out clears it, so state both current values when you want to keep them. Your agent can filter the inventory by review decision, owner team and owner principal to check the result.

The killed-agent signal is observable in this queue and through the review-signals API. Its opening and clearing are sent to enabled notification channels, and an alert rule using the review_signals source can target its project, kind, severity, or subject. It never disables a key on its own. Repeated spans from the same key under the same containment refresh one row without re-sending the opening, and the row closes when that key is revoked or the containment is lifted.

The same queue also carries a seventh condition, opened by labelling a memory item quarantined rather than by telemetry discovery: see Memory provenance and quarantine for what that label means and how it is set.

Every condition in the queue has both an opening and a clearing, and both are sent to enabled notification channels — so an alert rule using the review_signals source can page while a condition is open and stop on its own when somebody deals with it, without anybody clearing the alert by hand.

Who authorized what

The authority graph (list_authority_edges, or anectico authority-edges list) shows who granted an agent the right to act, for what purpose, and on what evidence. Each edge is either declared (a delegation somebody wrote down) or observed (one a signed action receipt proves actually happened). Those are not the same claim, and an exercised delegation must never read as an approved one.

Revoked edges are hidden by default: a reviewer asking what an agent can do should not be shown history unless they ask for it.

Permissions

Reading the fleet, the inventory, the review queue and the delegation graph needs agents:read, which every role from viewer up holds. The containment metadata on a fleet row additionally needs quarantine:request or quarantine:approve. Without either, the rest of the fleet is still returned.

Registering a deployment, a configuration or an attested manifest, assigning an asset owner, or recording an asset review needs agents:write. See Permission scopes.

The same answers over the API

GET /api/v1/fleet?project_id={projectId}&limit=100
GET /api/v1/assets?kind=agent&shadow=true
GET /api/v1/assets?kind=tool&related_asset_id={agentAssetId}
GET /api/v1/assets/{assetId}
PUT /api/v1/assets/{assetId}/ownership
POST /api/v1/assets/{assetId}/reviews
PUT /api/v1/assets/{assetId}/data-classification
GET /api/v1/assets/{assetId}/attribution
GET /api/v1/review-signals?status=open
GET /api/v1/authority-edges
GET /api/v1/authority-edges?include_revoked=true
POST /api/v1/authority-edges/{edgeId}/revoke

The same fleet contract is available from the CLI:

anectico fleet list --limit 100

MCP clients can call list_agent_fleet directly. The CLI and the tool use the same opaque next_cursor and has_more values as the REST response, so an automation never has to recreate the join. Each fleet row also returns its sorted observation_keys; use those immutable values, rather than name, when selecting that row's runs.

related_asset_id answers the usage question in whichever direction you ask it: pass an agent's id to list what that agent uses, or a tool's or model's id to list the agents using it. Combine it with kind to narrow. Leave it off for no narrowing at all — it never widens a page.

shadow is three-valued: leave it off for both kinds, true for discovered records only, false for declared ones. Every one of these is scoped to a project — pass project_id or you will read an empty inventory rather than the whole organization. Full parameters and response shapes are in the REST API reference.

/authority-edges answers which delegations exist — who may act through what, for what purpose, how often it has been exercised and when it last was. The revoke route withdraws one of them with a required reason; the withdrawal is attributed to your credential, the edge keeps its sighting history, and it drops out of the default read until you pass include_revoked=true. Using a withdrawn delegation does not restore it — it raises a review signal instead. See Revoke an agent's access.

The ownership route replaces owner_team and owner_principal; empty values deliberately clear an assignment. The review route accepts unreviewed, approved or rejected with a required reason and a required risk tier — unassessed, low, medium, high or critical. The response records who reviewed it and when. Approval is independent of containment, so approving a quarantined asset never restores its lifecycle state.

The risk tier is part of the review because it is part of the same judgement: the same reviewer, at the same moment, saying how much is at stake. An asset carries unassessed until somebody reviews it, and a reviewer who has not assessed the blast radius records unassessed deliberately rather than leaving the field out. That is what makes ?risk_tier=high mean "a person put this here".

The data classification is NOT part of the review, for the mirror-image reason. It says what the asset handles rather than how the review went, and it changes when the asset's data flows change — which happens without anybody reopening an approval. So it is its own route, and it records its own classified_by, classification_reason and classified_at rather than borrowing the reviewer's. Accepted values are unclassified, public, internal, confidential and restricted. An asset carries unclassified until somebody classifies it, and a classifier who examined it and found nothing to classify records unclassified deliberately — the difference between the two is whether classified_by is set. Classifying an asset changes no approval state, risk tier, owner or lifecycle state.

The CLI exposes the inventory and the ownership, review and classification writes, including bulk ownership and review:

anectico asset list --origin shadow --approval-state unreviewed --limit 200 -o json
anectico asset list --risk-tier high --risk-tier critical -o json
anectico asset own <asset-id> [<asset-id>...] --owner-team platform
anectico asset review <asset-id> [<asset-id>...] \
  --approval-state approved --risk-tier high --reason "Matched the reviewed deployment"

asset list returns the raw page, so .assets[].asset_id can be selected with jq and passed to either write through xargs; use --cursor for later pages. A bulk write continues after an item failure, reports every asset in input order, and exits non-zero if any item failed. Ownership is a complete replacement: an omitted owner flag clears that field, at least one owner flag must be explicit, and supplying both as empty values clears both deliberately. The commands require agents:write. A successful HTTP status is not enough on its own: the response must confirm the requested asset and new governance fields, or that item is reported with an unknown outcome.

The rest of the inventory is reachable the same way:

anectico asset get <asset-id>
anectico asset versions <asset-id>                    # every version seen, and which is current
anectico asset attribution --observation-key <key>    # or: anectico asset attribution <asset-id>
anectico asset classify <asset-id> --classification restricted --reason "Handles card data"
anectico review-signals list --kind shadow_asset --status open
anectico authority-edges list --from user:alice --include-revoked
anectico authority-edges revoke <edge-id> --reason "Delegation no longer needed" --confirm-token <token>
anectico memory-items label get <memory-item-key>
anectico memory-items label set <memory-item-key> --label quarantined --reason "Prompt injection found"
anectico memory-items propagation <memory-item-key>

Revoking an authority edge withdraws the declaration only. The credential keeps working and the agent keeps running; a later use of the revoked authority opens a review signal instead. To stop an agent, contain it.

An MCP agent reaches all of this through the gateways. The reads come from list_read_actions: list_agent_assets, get_agent_asset, list_agent_asset_versions, resolve_agent_asset_attribution, list_agent_review_signals, list_authority_edges, get_memory_item_label, list_memory_item_labels and get_memory_item_propagation. The writes come from list_write_actions: set_agent_asset_ownership, review_agent_asset, set_agent_asset_data_classification, revoke_authority_edge and set_memory_item_label. Each write previews what it replaces and applies with the returned confirm_token. Approving an asset never lifts a quarantine on it.

Declare deployments and configurations

Telemetry tells you an agent ran with some configuration: spans and receipts carry its effective_config_hash, not its content. Register what the hash means, and where it runs, from your CI pipeline or release tooling:

anectico deployments register --environment production --asset-id <asset-id> \
  --asset-version-id <version-id> --external-ref "$CI_RUN_ID" --deployed-by ci --confirm-token <token>
anectico config-snapshots register --environment production --file snapshot.json --confirm-token <token>
anectico config-snapshots get <effective-config-hash> --environment production

A deployment is identified by the asset and your --external-ref: registering the same pair again updates that deployment instead of adding one, so a retried pipeline step is safe. A registered configuration never changes — the same hash again returns the stored one, and a different composition under the same hash is refused. Naming a deployment_id in the snapshot moves that deployment onto the configuration, and the one it ran before stays readable as superseded. Both are recorded as your declarations, never as observed telemetry, and both require the server preview and confirmation because what they replace cannot be read back by a key that can only write.

Over MCP, get_config_snapshot is a read action, and register_deployment and register_config_snapshot are write actions that preview and then apply with the returned confirm_token. To sign a bill of materials or keep your own action receipts, see Verify a signed attestation offline.

Every inventory row includes its environment. Asset review accepts approved, rejected or unreviewed (an explicit reset). All three require a reason and an explicit risk_tier; use unassessed when you have not assessed the blast radius. The same rule applies through MCP and CLI.

Read saved deployments and drivers

Use get_agent_deployment, or anectico deployments get <deployment-id>, to read every saved deployment setting. You can also use anectico deployments get --asset-id <id> --external-ref <reference> --environment production to resolve the same deployment by its natural key. The response includes its exact asset version, discovery source, actor, deployment and retirement times, and record times.

get_agent_asset and anectico asset get <id> include driver_configuration: the endpoint, saved connection id, enabled state, revision, actor and record times. Disabled drivers retain their saved endpoint and connection. withheld_fields names connection_secret; secret values are never returned. Reading these settings sends no message.

Keep the complete result of sign_receipt_checkpoint outside Anectico. Later, pass it as retained_checkpoint to verify_receipt_chain, or save the CLI checkpoint result and run anectico receipt-chains verify <chain-id> --checkpoint-file <checkpoint.json>. Verification checks its signed scope, sequence and digest. retained_checkpoint_state=contradicted exposes a missing or changed retained tail even when the shortened chain is internally consistent. outside_retained_range means the assertion predates the surviving segment; it is not a match. A checkpoint records chain integrity, not whether a reported action really happened.

Saved settings and confirmed changes

get_agent_deployment and anectico deployments get return the complete saved declaration, including its environment, asset version, external reference, source, deployer, retirement, timestamps and current configuration binding. Select either anectico deployments get <id> or both --asset-id <id> and --external-ref <reference>; use the same --environment for a natural key. An inventory row also carries its exact environment.

get_agent_asset and anectico asset get <id> include driver_configuration: enabled state, endpoint, connection id, revision, actor and times. The saved connection's secret is withheld and named in withheld_fields. Reading these settings sends no message.

All evaluation and agent-governance CLI writes use the server preview. Run the command without --confirm-token first. Review complete before and proposed state, required scopes and external effects. Repeat identical flags and file contents with the returned --confirm-token. Keep the same --idempotency-key through both calls and retries. Updates refuse a stale preview. For multiple assets, --confirm-tokens-file maps each asset id to its own preview token; one token cannot approve several different assets. Read back every changed record.

Configuration reads return the complete settings and one page of current or superseded deployment bindings. Pass cursor and limit through MCP, or --cursor and --limit through the CLI. Each response states that it is a page; continue with identical hash, environment and filters.

Declare an asset before it runs

Your agent can register a technical agent, workflow, tool or model before sending any telemetry. This records what you declare. It does not establish execution, approval, risk assessment or deployment. A new declaration is registered, unreviewed, unassessed and unobserved; first-seen and last-seen are absent until genuine telemetry arrives.

Save a technical declaration such as this to declaration.json:

{
  "project_id": "PROJECT_UUID",
  "environment": "production",
  "kind": "agent",
  "agent_identity": {"declared_agent_id": "agent:checkout"},
  "name": "Checkout agent",
  "version": "v1"
}

Preview with anectico asset register --file declaration.json --idempotency-key declare-checkout-1. Read the complete proposal, then repeat identical arguments with --confirm-token TOKEN. MCP uses execute_internal_action with action: "register_agent_asset" and the same JSON fields plus idempotency_key. It needs agents:write, agents:read, mcp:write and mcp:read.

Choose the complete technical identity

Kind Selector What must match future telemetry
agent agent_identity: {declared_agent_id} An explicit declared agent ID; service and name fallback is insufficient.
workflow workflow_identity: {parent_agent_observation_key, workflow_name} The exact agent key already declared or observed in this project and environment, plus workflow name.
tool tool_identity: {tool_type, tool_name} Exact type and name. Use TOOL_TYPE_FUNCTION, TOOL_TYPE_EXTENSION, TOOL_TYPE_DATASTORE, TOOL_TYPE_MCP, or explicitly TOOL_TYPE_UNSPECIFIED.
model model_identity: {provider, model_name} Exact provider and name. Provider is required; explicitly "" selects the unknown provider and never matches a known one.

Use exactly one selector matching kind. The preview returns the derived observation_key; read it from the declaration or authorized observation instead of guessing a parent key from a name. Equal names with different parent agents, tool types or providers remain separate. Display names never establish a link. Only the four kinds above can be declared.

Environment is required and at most 128 UTF-8 bytes; display name 256; technical identity components 512; optional version 128. Technical identifiers accept letters, numbers and ._:/+-; display names also accept spaces. Controls, URLs and query payloads, profile objects and arbitrary metadata refuse. Optional content_sha256 requires a version and exactly 64 hexadecimal SHA-256 characters. Stable keys use 1–128 printable non-space ASCII bytes. Never put tracked-person identifiers or profile and telemetry content in these control fields.

Adopt an exact discovered asset

Supply asset_id only to adopt that exact eligible shadow. The preview shows its current identity, ownership, review, risk, and lifecycle, genuine sightings, versions and shadow-review transition. The complete typed selector must match the shadow's existing observation key. A service and name fallback cannot be silently changed into an explicit declared agent ID. Confirmation binds that exact state; a change requires a new preview. Direct state-bound requests can carry the returned expected_state_digest.

Adoption preserves real observations, ownership and version history. It closes only the existing shadow-review signal. Reviewed, quarantined, retired, non-shadow, foreign-project or conflicting targets refuse. A fresh key updating an existing declaration likewise requires a complete state-bound preview and changes only the allowed name, version, and hash; it does not change identity or lift containment.

Recover an original result

Repeat identical arguments with the same stable key after a lost response. The returned replayed result describes the original commit, including its declaration revision, operator and time, receipt identity, version and hash and observation_state_at_commit. Later telemetry or edits may make the current asset different; use asset get and asset versions (or get_agent_asset and list_agent_asset_versions) to read current state. Never reuse a key for another body or operator. There is no asset proof link.

There are at most 1,000 distinct declarations per project across environments and kinds. Replacement and exact replay consume no new slot; a new declaration and adoption at capacity refuses with asset_declaration_limit. No paid capability upgrade or ingestion charge is required for this management operation.

Declarations and original results retain bounded technical or operator control records until the owning project or organization is deleted. They are excluded from tracked-person archives because they describe technical inventory and an operator's act. Owner deletion removes them and prevents retries or late observations from recreating them.