Skip to main content

agent-status-sdk (Python)

Live tools/call traffic from your MCP server into AgentStatus User Traffic and Analytics.

This package does not register HTTP agents, run residential probes, open a tunnel, or expose Agent Status as an MCP server. Those were the old SDK. Gone in 2.0.0.

Your public MCP URL does not change. Hosts keep calling origin. observe() wraps the process you already run.

Install

pip install agent-status-sdk

No extra extras. Stdlib only.

What you need from the dashboard

On the MCP agent, User Traffic tab, copy the agent id. That is a UUID, not an API key.

Set it in code or in the environment:

export AGENTSTATUS_AGENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Optional:

export AGENTSTATUS_INGEST="https://api.rora.carmel.so/api/rora"

Default ingest is already that URL. You do not pass a Fabric/Rora API key. The observe route is public per agent id, same threat model as the live-mcp URL.

FastMCP

Register tools first, then wrap, then run.

from mcp.server.fastmcp import FastMCP
from agent_status import observe

mcp = FastMCP("docs")

@mcp.tool()
def search_docs(q: str) -> str:
    return "..."

observe(mcp, agent_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
mcp.run()

If AGENTSTATUS_AGENT_ID is set, observe(mcp) is enough.

Low-level MCP Server

from mcp.server import Server
from agent_status import observe

server = Server("docs")
observe(server, agent_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")

Call observe() after the server object exists. If your framework registers CallTool lazily, call it after tools are registered and before run().

If the wrap cannot find tools/call, stderr prints a warning and the server still runs. Pass observe(..., required=True) if you want boot to fail instead. Do not use track() with an MCP id.

What gets recorded

On each tools/call:

  • tool name (job)
  • duration (time inside the handler)
  • RPC / exception error text, truncated
  • host name and version from initialize.clientInfo when the wrap saw initialize
  • session id if you pass it on report_tool_call
  • a short result excerpt

User Traffic is the event list. Analytics rolls those events (mix, week vs week, errors, latency). Cost and tokens only if you send them. We do not invent them.

observe() does not store names, email, chat, or the host thread. Arguments are forwarded as a dict; do not put secrets in tool args if you cannot afford them leaving the process. The ingest strips a small blocked-key set (email, chat, prompt, …) but that is not a privacy guarantee.

Fail-open

The tool handler always runs first. Recording is a background POST with a 2 second timeout. If AgentStatus is down, DNS fails, or the wrap cannot find a handler, the tool still returns. We miss a row. The customer does not miss a response.

observe() itself never raises into your server. A bad server object is returned unchanged.

If Analytics is empty

  1. observe() is not on the process hosts actually hit.
  2. You wrapped after run(), or before setRequestHandler / tool registration in a way the wrap missed. Check stderr for the wrap warning.
  3. Origin is still serving a second copy of the server without the wrap.
  4. Hosts are calling a different deployment than the one with AGENTSTATUS_AGENT_ID.
  5. You called track() with an MCP id, or observe() with a personal-agent id. Ingest rejects that.

Connection tests from AgentStatus are our probes. They are not live user traffic.

Personal agents (track)

Use track(), not observe(). observe() is MCP only. This agent id is for a personal agent.

One wrap is User Traffic, Analytics, and whether the job landed. Channel defaults to iMessage.

from agent_status import track

with track("calendar", agent_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", user="anon_stable_id", session="thread_id") as run:
    move_dentist()
    run.landed(True)

If the wrap exits without an exception, landed defaults to true. Call run.miss() when the function succeeded but the calendar write did not.

Manual report

If you are not using the official MCP Server classes:

from agent_status import report_tool_call

report_tool_call(
    name="search_docs",
    agent_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    duration_ms=21,
    provider="cursor",
)

Never raises.

What this is not

  • Not a sidecar. Not a public URL swap.
  • Not session replay of Cursor / Claude Code.
  • Not hallucination grouping.
  • Not wrapping the host. We wrap your server.

Ingest

POST https://api.rora.carmel.so/api/rora/public/live-mcp/{agent_id}/observe

JSON body, name required. This path only records. It does not proxy to origin and does not run the tool.

Metadata

Release files for agent-status-sdk 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-status-sdk 2.2.0
File Size Uploaded Provenance
agent_status_sdk-2.2.0.tar.gz 10.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-status-sdk 2.2.0
File Interpreter ABI Platform
agent_status_sdk-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.4 kB

Release files / agent_status_sdk-2.2.0.tar.gz

Download URL agent_status_sdk-2.2.0.tar.gz
Size 10.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a8e098e3c464ccc8dcba6a0681e7db4f39c30eaa8e573207e44d4f14b7328f1b
BLAKE2b-256 checksum
How to use checksums
68da2950cb002f8742c31fef7099ba06ec68df380ad03cf46e390e1e11cfa69b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / agent_status_sdk-2.2.0-py3-none-any.whl

Download URL agent_status_sdk-2.2.0-py3-none-any.whl
Size 8.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de8ef76a9d0a26831d985717e3bde07bd45767dcc7b9a747ad636754fc0a38e5
BLAKE2b-256 checksum
How to use checksums
7b292bcaa3754ca20fd14d30ff3166834e4597a52d40d2d00d8275c28f46f7d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for agent-status-sdk 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page