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 (Agent)

Use Agent, not observe(). Bind once per thread. Wrap the dispatcher once. get_calendar maps to calendar.

from agent_status import Agent

ember = Agent(agent_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")

def handle_thread(thread):
    bound = ember.bind(user=thread.anon_id, session=thread.id)
    call_tool = bound.wrap_tools(call_tool)
    return call_tool("get_calendar", {"when": "tomorrow"})

That one wrap is User Traffic and the lookup. After book_table the wrap calls get_calendar itself and scores whether it showed up. You do not set a second URL. You do not pass landed=. If the read tool is missing, the dashboard says we don't know. landed= still overrides.

track("calendar", ...) still works for a single job.

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.4.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.4.0
File Size Uploaded Provenance
agent_status_sdk-2.4.0.tar.gz 13.3 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 23.5 kB

Release files / agent_status_sdk-2.4.0.tar.gz

Download URL agent_status_sdk-2.4.0.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
d06b6624e964afbf2d64fcf756d56084e22c79c8760b8be30f816a8d87280447
BLAKE2b-256 checksum
How to use checksums
eb3cabd0765d8e2b151d40cd95e6e703388bbc3b92a07e7711381cd2262fff7c
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.4.0-py3-none-any.whl

Download URL agent_status_sdk-2.4.0-py3-none-any.whl
Size 10.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
682f2fa0337ae106efcc87e906073628c0fbd568b42352e29476d77e6bc0a621
BLAKE2b-256 checksum
How to use checksums
884bff25319e5c1c4e890764109eeb48d9cf0b65113b190d9444775d2850b811
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.4.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