agent-analytics-mcp-server 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .env
8
+ keys.env
9
+ .mcp.json
10
+ analytics.db
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-analytics-mcp-server
3
+ Version: 0.1.0
4
+ Summary: Usage analytics and monitoring for AI agent tool calls — track, analyze and optimize agent behavior
5
+ Project-URL: Homepage, https://github.com/AiAgentKarl/agent-analytics-mcp-server
6
+ Project-URL: Repository, https://github.com/AiAgentKarl/agent-analytics-mcp-server
7
+ Author: AiAgentKarl
8
+ License: MIT
9
+ Keywords: ai-agents,analytics,mcp,monitoring,usage-tracking
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: mcp>=1.0.0
16
+ Requires-Dist: pydantic>=2.0.0
17
+ Description-Content-Type: text/markdown
18
+
19
+ # Agent Analytics MCP Server 📊
20
+
21
+ Usage analytics and monitoring for AI agent tool calls. Track, analyze, and optimize how agents use your tools.
22
+
23
+ ## Features
24
+
25
+ - **Event Tracking** — Log every tool call with duration, success/failure, metadata
26
+ - **Dashboard** — Overview with total calls, error rates, top tools, daily trends
27
+ - **Per-Tool Analytics** — Deep dive into individual tool performance
28
+ - **Per-Agent Analytics** — See how specific agents use your services
29
+ - **Error Tracking** — Monitor and debug failures
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ pip install agent-analytics-mcp-server
35
+ ```
36
+
37
+ ## Usage with Claude Code
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "analytics": {
43
+ "command": "uvx",
44
+ "args": ["agent-analytics-mcp-server"]
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## Tools
51
+
52
+ | Tool | Description |
53
+ |------|-------------|
54
+ | `track_event` | Log a usage event |
55
+ | `get_dashboard` | Overview dashboard |
56
+ | `tool_analytics` | Per-tool deep dive |
57
+ | `agent_analytics` | Per-agent usage |
58
+
59
+ ## License
60
+
61
+ MIT
@@ -0,0 +1,43 @@
1
+ # Agent Analytics MCP Server 📊
2
+
3
+ Usage analytics and monitoring for AI agent tool calls. Track, analyze, and optimize how agents use your tools.
4
+
5
+ ## Features
6
+
7
+ - **Event Tracking** — Log every tool call with duration, success/failure, metadata
8
+ - **Dashboard** — Overview with total calls, error rates, top tools, daily trends
9
+ - **Per-Tool Analytics** — Deep dive into individual tool performance
10
+ - **Per-Agent Analytics** — See how specific agents use your services
11
+ - **Error Tracking** — Monitor and debug failures
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install agent-analytics-mcp-server
17
+ ```
18
+
19
+ ## Usage with Claude Code
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "analytics": {
25
+ "command": "uvx",
26
+ "args": ["agent-analytics-mcp-server"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## Tools
33
+
34
+ | Tool | Description |
35
+ |------|-------------|
36
+ | `track_event` | Log a usage event |
37
+ | `get_dashboard` | Overview dashboard |
38
+ | `tool_analytics` | Per-tool deep dive |
39
+ | `agent_analytics` | Per-agent usage |
40
+
41
+ ## License
42
+
43
+ MIT
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agent-analytics-mcp-server"
7
+ version = "0.1.0"
8
+ description = "Usage analytics and monitoring for AI agent tool calls — track, analyze and optimize agent behavior"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [{name = "AiAgentKarl"}]
13
+ keywords = ["mcp", "analytics", "monitoring", "ai-agents", "usage-tracking"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ ]
20
+ dependencies = [
21
+ "mcp>=1.0.0",
22
+ "pydantic>=2.0.0",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/AiAgentKarl/agent-analytics-mcp-server"
27
+ Repository = "https://github.com/AiAgentKarl/agent-analytics-mcp-server"
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src"]
File without changes
@@ -0,0 +1,181 @@
1
+ """Datenbank — SQLite-basiertes Analytics-Tracking."""
2
+
3
+ import sqlite3
4
+ import json
5
+ import os
6
+ from datetime import datetime, timezone, timedelta
7
+ from pathlib import Path
8
+
9
+
10
+ _DB_PATH = os.getenv("ANALYTICS_DB_PATH", str(Path(__file__).resolve().parent.parent / "analytics.db"))
11
+
12
+
13
+ def _connect() -> sqlite3.Connection:
14
+ conn = sqlite3.connect(_DB_PATH)
15
+ conn.row_factory = sqlite3.Row
16
+ conn.execute("PRAGMA journal_mode=WAL")
17
+ conn.execute("""
18
+ CREATE TABLE IF NOT EXISTS events (
19
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
20
+ event_type TEXT NOT NULL,
21
+ tool_name TEXT,
22
+ service_id TEXT DEFAULT 'default',
23
+ agent_id TEXT,
24
+ duration_ms INTEGER,
25
+ success INTEGER DEFAULT 1,
26
+ error_message TEXT,
27
+ metadata TEXT,
28
+ created_at TEXT NOT NULL
29
+ )
30
+ """)
31
+ conn.execute("CREATE INDEX IF NOT EXISTS idx_event_type ON events(event_type)")
32
+ conn.execute("CREATE INDEX IF NOT EXISTS idx_tool ON events(tool_name)")
33
+ conn.execute("CREATE INDEX IF NOT EXISTS idx_created ON events(created_at)")
34
+ conn.commit()
35
+ return conn
36
+
37
+
38
+ def track_event(
39
+ event_type: str,
40
+ tool_name: str = None,
41
+ service_id: str = "default",
42
+ agent_id: str = None,
43
+ duration_ms: int = None,
44
+ success: bool = True,
45
+ error_message: str = None,
46
+ metadata: dict = None,
47
+ ) -> dict:
48
+ """Event tracken."""
49
+ conn = _connect()
50
+ now = datetime.now(timezone.utc).isoformat()
51
+ conn.execute(
52
+ """INSERT INTO events
53
+ (event_type, tool_name, service_id, agent_id,
54
+ duration_ms, success, error_message, metadata, created_at)
55
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
56
+ (event_type, tool_name, service_id, agent_id,
57
+ duration_ms, 1 if success else 0, error_message,
58
+ json.dumps(metadata) if metadata else None, now),
59
+ )
60
+ conn.commit()
61
+ conn.close()
62
+ return {"tracked": True, "event_type": event_type, "created_at": now}
63
+
64
+
65
+ def get_dashboard(service_id: str = None, days: int = 30) -> dict:
66
+ """Dashboard-Daten abrufen."""
67
+ conn = _connect()
68
+ cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
69
+
70
+ sql_where = "WHERE created_at >= ?"
71
+ params = [cutoff]
72
+ if service_id:
73
+ sql_where += " AND service_id=?"
74
+ params.append(service_id)
75
+
76
+ # Gesamtstatistiken
77
+ total = conn.execute(f"SELECT COUNT(*) as c FROM events {sql_where}", params).fetchone()["c"]
78
+ successful = conn.execute(
79
+ f"SELECT COUNT(*) as c FROM events {sql_where} AND success=1", params
80
+ ).fetchone()["c"]
81
+ failed = total - successful
82
+
83
+ # Top Tools
84
+ top_tools = conn.execute(
85
+ f"""SELECT tool_name, COUNT(*) as calls, AVG(duration_ms) as avg_duration
86
+ FROM events {sql_where} AND tool_name IS NOT NULL
87
+ GROUP BY tool_name ORDER BY calls DESC LIMIT 10""",
88
+ params,
89
+ ).fetchall()
90
+
91
+ # Tägliche Nutzung
92
+ daily = conn.execute(
93
+ f"""SELECT DATE(created_at) as date, COUNT(*) as calls
94
+ FROM events {sql_where}
95
+ GROUP BY DATE(created_at) ORDER BY date DESC LIMIT {days}""",
96
+ params,
97
+ ).fetchall()
98
+
99
+ # Error-Rate
100
+ error_rate = (failed / total * 100) if total > 0 else 0
101
+
102
+ conn.close()
103
+ return {
104
+ "period_days": days,
105
+ "total_events": total,
106
+ "successful": successful,
107
+ "failed": failed,
108
+ "error_rate_pct": round(error_rate, 1),
109
+ "top_tools": [dict(r) for r in top_tools],
110
+ "daily_usage": [dict(r) for r in daily],
111
+ }
112
+
113
+
114
+ def get_tool_analytics(tool_name: str, days: int = 30) -> dict:
115
+ """Analytics für ein spezifisches Tool."""
116
+ conn = _connect()
117
+ cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
118
+
119
+ rows = conn.execute(
120
+ """SELECT COUNT(*) as calls,
121
+ SUM(CASE WHEN success=1 THEN 1 ELSE 0 END) as successes,
122
+ AVG(duration_ms) as avg_duration_ms,
123
+ MIN(duration_ms) as min_duration_ms,
124
+ MAX(duration_ms) as max_duration_ms
125
+ FROM events WHERE tool_name=? AND created_at >= ?""",
126
+ (tool_name, cutoff),
127
+ ).fetchone()
128
+
129
+ # Letzte Fehler
130
+ errors = conn.execute(
131
+ """SELECT error_message, created_at FROM events
132
+ WHERE tool_name=? AND success=0 AND created_at >= ?
133
+ ORDER BY created_at DESC LIMIT 5""",
134
+ (tool_name, cutoff),
135
+ ).fetchall()
136
+
137
+ # Täglicher Trend
138
+ daily = conn.execute(
139
+ """SELECT DATE(created_at) as date, COUNT(*) as calls
140
+ FROM events WHERE tool_name=? AND created_at >= ?
141
+ GROUP BY DATE(created_at) ORDER BY date""",
142
+ (tool_name, cutoff),
143
+ ).fetchall()
144
+
145
+ conn.close()
146
+ return {
147
+ "tool_name": tool_name,
148
+ "period_days": days,
149
+ "total_calls": rows["calls"],
150
+ "success_rate_pct": round(rows["successes"] / rows["calls"] * 100, 1) if rows["calls"] > 0 else 0,
151
+ "avg_duration_ms": round(rows["avg_duration_ms"] or 0),
152
+ "min_duration_ms": rows["min_duration_ms"],
153
+ "max_duration_ms": rows["max_duration_ms"],
154
+ "recent_errors": [dict(r) for r in errors],
155
+ "daily_trend": [dict(r) for r in daily],
156
+ }
157
+
158
+
159
+ def get_agent_analytics(agent_id: str, days: int = 30) -> dict:
160
+ """Analytics für einen spezifischen Agent."""
161
+ conn = _connect()
162
+ cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
163
+
164
+ tools_used = conn.execute(
165
+ """SELECT tool_name, COUNT(*) as calls
166
+ FROM events WHERE agent_id=? AND created_at >= ? AND tool_name IS NOT NULL
167
+ GROUP BY tool_name ORDER BY calls DESC""",
168
+ (agent_id, cutoff),
169
+ ).fetchall()
170
+
171
+ total = conn.execute(
172
+ "SELECT COUNT(*) as c FROM events WHERE agent_id=? AND created_at >= ?",
173
+ (agent_id, cutoff),
174
+ ).fetchone()["c"]
175
+
176
+ conn.close()
177
+ return {
178
+ "agent_id": agent_id,
179
+ "total_events": total,
180
+ "tools_used": [dict(r) for r in tools_used],
181
+ }
@@ -0,0 +1,24 @@
1
+ """Agent Analytics MCP Server — Usage-Tracking für AI-Agent-Tools."""
2
+
3
+ from mcp.server.fastmcp import FastMCP
4
+
5
+ from src.tools.analytics import register_analytics_tools
6
+
7
+ mcp = FastMCP(
8
+ "Agent Analytics",
9
+ instructions=(
10
+ "Track and analyze AI agent tool usage. Monitor call frequency, "
11
+ "success rates, response times, and errors. "
12
+ "Get dashboards and per-tool analytics."
13
+ ),
14
+ )
15
+
16
+ register_analytics_tools(mcp)
17
+
18
+
19
+ def main():
20
+ mcp.run(transport="stdio")
21
+
22
+
23
+ if __name__ == "__main__":
24
+ main()
File without changes
@@ -0,0 +1,77 @@
1
+ """Analytics-Tools — Usage-Tracking und Monitoring für AI-Agents."""
2
+
3
+ from mcp.server.fastmcp import FastMCP
4
+
5
+ from src import db
6
+
7
+
8
+ def register_analytics_tools(mcp: FastMCP):
9
+ """Analytics-bezogene MCP-Tools registrieren."""
10
+
11
+ @mcp.tool()
12
+ async def track_event(
13
+ event_type: str,
14
+ tool_name: str = None,
15
+ service_id: str = "default",
16
+ agent_id: str = None,
17
+ duration_ms: int = None,
18
+ success: bool = True,
19
+ error_message: str = None,
20
+ metadata: dict = None,
21
+ ) -> dict:
22
+ """Ein Usage-Event tracken.
23
+
24
+ Zeichnet einen Tool-Aufruf oder ein anderes Event auf
25
+ für spätere Analyse.
26
+
27
+ Args:
28
+ event_type: Art des Events (z.B. "tool_call", "error", "login")
29
+ tool_name: Name des aufgerufenen Tools
30
+ service_id: ID des Services (Standard: "default")
31
+ agent_id: ID des aufrufenden Agents
32
+ duration_ms: Dauer in Millisekunden
33
+ success: War der Aufruf erfolgreich?
34
+ error_message: Fehlermeldung falls nicht erfolgreich
35
+ metadata: Zusätzliche Daten als JSON
36
+ """
37
+ return db.track_event(
38
+ event_type, tool_name, service_id,
39
+ agent_id, duration_ms, success, error_message, metadata,
40
+ )
41
+
42
+ @mcp.tool()
43
+ async def get_dashboard(service_id: str = None, days: int = 30) -> dict:
44
+ """Analytics-Dashboard abrufen.
45
+
46
+ Zeigt: Gesamtaufrufe, Erfolgsrate, Top-Tools, tägliche Nutzung.
47
+
48
+ Args:
49
+ service_id: Optional — nur für diesen Service
50
+ days: Zeitraum in Tagen (Standard: 30)
51
+ """
52
+ return db.get_dashboard(service_id, days)
53
+
54
+ @mcp.tool()
55
+ async def tool_analytics(tool_name: str, days: int = 30) -> dict:
56
+ """Detaillierte Analytics für ein spezifisches Tool.
57
+
58
+ Zeigt: Aufrufe, Erfolgsrate, Durchschnittsdauer,
59
+ letzte Fehler und täglichen Trend.
60
+
61
+ Args:
62
+ tool_name: Name des Tools
63
+ days: Zeitraum in Tagen (Standard: 30)
64
+ """
65
+ return db.get_tool_analytics(tool_name, days)
66
+
67
+ @mcp.tool()
68
+ async def agent_analytics(agent_id: str, days: int = 30) -> dict:
69
+ """Analytics für einen bestimmten Agent.
70
+
71
+ Zeigt welche Tools ein Agent wie oft nutzt.
72
+
73
+ Args:
74
+ agent_id: ID des Agents
75
+ days: Zeitraum in Tagen (Standard: 30)
76
+ """
77
+ return db.get_agent_analytics(agent_id, days)