Core API Reference¶
Complete reference for the mcpstat Python API.
MCPStat Class¶
The main class for usage tracking.
Constructor¶
from mcpstat import MCPStat
stat = MCPStat(
server_name: str,
db_path: str | None = None,
log_path: str | None = None,
log_enabled: bool = False,
metadata_presets: dict[str, dict] | None = None,
)
| Parameter | Type | Default | Description |
|---|---|---|---|
server_name | str | Required | Identifier for your MCP server |
db_path | str | ./mcp_stat_data.sqlite | SQLite database path |
log_path | str | ./mcp_stat.log | File log path |
log_enabled | bool | False | Enable file logging |
metadata_presets | dict | None | Pre-defined metadata |
Core Methods¶
record()¶
Record a tool, prompt, or resource invocation.
await stat.record(
name: str,
primitive_type: Literal["tool", "prompt", "resource"] = "tool",
*,
success: bool = True,
error_msg: str | None = None,
response_chars: int | None = None,
input_tokens: int | None = None,
output_tokens: int | None = None,
)
| Parameter | Type | Description |
|---|---|---|
name | str | Name of the primitive |
primitive_type | str | Type: tool, prompt, or resource |
success | bool | Whether invocation succeeded |
error_msg | str | Error message for failures (logged only) |
response_chars | int | Response size for token estimation |
input_tokens | int | Actual input token count |
output_tokens | int | Actual output token count |
Critical
Always call record() as the FIRST line in your handlers to guarantee 100% tracking coverage.
Example:
@app.call_tool()
async def handle_tool(name: str, arguments: dict):
await stat.record(name, "tool") # FIRST LINE
result = await my_logic(arguments)
return result
get_stats()¶
Query usage statistics.
stats = await stat.get_stats(
*,
include_zero: bool = True,
limit: int | None = None,
type_filter: Literal["tool", "prompt", "resource"] | None = None,
)
| Parameter | Type | Description |
|---|---|---|
include_zero | bool | Include items with zero calls |
limit | int | Maximum results to return |
type_filter | str | Filter by primitive type |
Returns:
{
"tracked_count": int, # Total tracked items
"total_calls": int, # Sum of all call counts
"zero_count": int, # Items with zero calls
"latest_access": str, # Most recent timestamp
"token_summary": {
"total_input_tokens": int,
"total_output_tokens": int,
"total_estimated_tokens": int,
"has_actual_tokens": bool,
},
"stats": [
{
"name": str,
"type": str,
"call_count": int,
"last_accessed": str | None,
"tags": list[str],
"short_description": str | None,
"total_input_tokens": int,
"total_output_tokens": int,
"estimated_tokens": int,
"avg_tokens_per_call": int,
}
]
}
get_catalog()¶
Browse and search the tool catalog.
catalog = await stat.get_catalog(
*,
tags: list[str] | None = None,
query: str | None = None,
include_usage: bool = True,
limit: int | None = None,
)
| Parameter | Type | Description |
|---|---|---|
tags | list[str] | Filter by tags (AND logic) |
query | str | Text search across names/descriptions |
include_usage | bool | Include call counts |
limit | int | Maximum results |
AND Logic
Tag filtering uses AND logic - tools must have all specified tags.
Returns:
{
"total_tracked": int, # Total tools in catalog
"matched": int, # Tools matching filters
"all_tags": list[str], # Complete tag inventory
"filters": {
"tags": list[str],
"query": str | None,
},
"results": [
{
"name": str,
"tags": list[str],
"short_description": str | None,
"call_count": int,
"last_accessed": str | None,
}
]
}
report_tokens()¶
Report token usage for a previously recorded call.
Use when actual token counts are available after the fact (e.g., from LLM API response).
Example:
# Record the call first
await stat.record("my_tool", "tool")
# Later, when you have actual tokens
response = await anthropic.messages.create(...)
await stat.report_tokens(
"my_tool",
response.usage.input_tokens,
response.usage.output_tokens
)
sync_tools()¶
Sync metadata from MCP Tool objects.
Auto-extracts tags from tool names and descriptions from tool definitions.
Example:
register_metadata()¶
Manually register metadata for a tool.
await stat.register_metadata(
name: str,
tags: list[str] | None = None,
short_description: str | None = None,
full_description: str | None = None,
)
get_by_type()¶
Get call counts grouped by type.
close()¶
Explicit cleanup (usually automatic).
Built-in Tools¶
build_tool_definitions()¶
Generate MCP tool schemas for mcpstat's built-in tools.
from mcpstat import build_tool_definitions
tools = build_tool_definitions(
prefix: str = "get",
server_name: str | None = None,
)
Returns tool definitions for:
get_tool_usage_statsget_tool_catalog
BuiltinToolsHandler¶
Handle calls to mcpstat's built-in tools.
from mcpstat import BuiltinToolsHandler
handler = BuiltinToolsHandler(stat, prefix="get")
# Check if a tool name is a stats tool
if handler.is_stats_tool(name):
result = await handler.handle(name, arguments)
Methods:
| Method | Description |
|---|---|
is_stats_tool(name) | Check if name is a built-in stats tool |
handle(name, args) | Handle the tool call, return result dict |
Prompts¶
build_prompt_definition()¶
Generate MCP prompt schema for stats prompt.
from mcpstat import build_prompt_definition
prompt = build_prompt_definition(server_name="my-server")
generate_stats_prompt()¶
Generate prompt content with current stats.
from mcpstat import generate_stats_prompt
content = await generate_stats_prompt(stat, server_name="my-server")
Utility Functions¶
normalize_tags()¶
Normalize and filter tags from text.