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.clientInfowhen 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
observe()is not on the process hosts actually hit.- You wrapped after
run(), or beforesetRequestHandler/ tool registration in a way the wrap missed. Check stderr for the wrap warning. - Origin is still serving a second copy of the server without the wrap.
- Hosts are calling a different deployment than the one with
AGENTSTATUS_AGENT_ID. - You called
track()with an MCP id, orobserve()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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| agent_status_sdk-2.4.0.tar.gz | 13.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.