+32
-9
@@ -8,2 +8,4 @@ #!/usr/bin/env node | ||
| const pkg = require('./package.json'); | ||
| const command = process.argv[2]; | ||
@@ -17,20 +19,19 @@ const args = process.argv.slice(3); | ||
| Commands: | ||
| server Run as MCP server (recommended — agent self-reports all actions) | ||
| dashboard [--port <n>] Start the web dashboard | ||
| check [--last <n>] Show latest session details | ||
| stats Show aggregate session stats | ||
| start <description> Start a recording session (manual mode) | ||
| stop <session-id> End a recording session | ||
| log <session-id> Log a tool call (pipe JSON on stdin) | ||
| proxy [--desc <text>] [--agent <type>] -- <command...> | ||
| Transparent MCP proxy — intercepts all tool calls | ||
| server Run as MCP server (agents self-report via MCP tools) | ||
| check [--last <n>] Show latest session summary (or last n sessions) | ||
| stats Show aggregate stats across all sessions | ||
| dashboard [--port <n>] Start the web dashboard | ||
| proxy [--desc] -- ... Transparent MCP proxy (fallback — MCP-only capture) | ||
| inspect <session-id> Show session details in terminal | ||
| Examples: | ||
| agent-obs proxy --desc "fix login bug" -- npx @modelcontextprotocol/server-filesystem /tmp | ||
| agent-obs server | ||
| agent-obs dashboard | ||
| agent-obs check | ||
| agent-obs check --last 3 | ||
| agent-obs stats | ||
| agent-obs dashboard | ||
| agent-obs proxy --desc "fix login bug" -- npx @modelcontextprotocol/server-filesystem /tmp | ||
| agent-obs inspect abc12345 | ||
@@ -53,4 +54,25 @@ | ||
| function printSummary() { | ||
| console.log(`agent-obs v${pkg.version}`); | ||
| try { | ||
| const stats = getDashboardStats(); | ||
| const sessions = getSessions({ limit: 1 }); | ||
| const lastGrade = sessions.length ? sessions[0].grade || '?' : '?'; | ||
| if (stats.totalSessions === 0) { | ||
| console.log('No sessions yet'); | ||
| } else { | ||
| console.log(`${stats.totalSessions} sessions · ${stats.totalToolCalls} tool calls · last grade ${lastGrade}`); | ||
| } | ||
| } catch (_) { | ||
| console.log('No sessions yet'); | ||
| } | ||
| console.log('Dashboard: http://localhost:9400'); | ||
| } | ||
| async function main() { | ||
| if (!command || command === 'help' || command === '--help' || command === '-h') { | ||
| if (command === 'help' || command === '--help' || command === '-h') { | ||
| printSummary(); | ||
| usage(); | ||
@@ -252,2 +274,3 @@ process.exit(0); | ||
| // Default: start dashboard | ||
| printSummary(); | ||
| await startServer(9400); | ||
@@ -254,0 +277,0 @@ } |
+23
-1
@@ -286,2 +286,24 @@ const Database = require('better-sqlite3'); | ||
| function closeStaleSessions() { | ||
| const db = getDb(); | ||
| const stale = db.prepare(` | ||
| SELECT id FROM sessions | ||
| WHERE status = 'running' | ||
| AND started_at < datetime('now', '-1 hour') | ||
| AND ended_at IS NULL | ||
| `).all(); | ||
| for (const s of stale) { | ||
| const calls = getToolCalls(s.id); | ||
| const errors = calls.filter(c => c.status === 'error').length; | ||
| const grade = computeGrade({ errorCount: errors, totalCalls: calls.length, durationMs: 0 }); | ||
| endSession(s.id, { | ||
| status: 'timeout', | ||
| errorMessage: 'Auto-closed: no activity for over 1 hour', | ||
| grade: grade.grade | ||
| }); | ||
| } | ||
| return stale.length; | ||
| } | ||
| module.exports = { | ||
@@ -295,3 +317,3 @@ getDb, initSchema, | ||
| recordHealthCheck, getLatestHealthChecks, getHealthHistory, | ||
| getDashboardStats, computeGrade, estimateCost, | ||
| getDashboardStats, computeGrade, estimateCost, closeStaleSessions, | ||
| }; |
+6
-1
@@ -129,2 +129,3 @@ const readline = require('readline'); | ||
| capabilities: CAPABILITIES, | ||
| instructions: "After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves.", | ||
| }); | ||
@@ -134,3 +135,6 @@ } | ||
| function handleToolsList(id) { | ||
| sendResponse(id, { tools: TOOLS }); | ||
| sendResponse(id, { | ||
| tools: TOOLS, | ||
| instructions: "After every tool call (Read, Write, Edit, Bash, Glob, Grep, or any MCP tool), you MUST call log_tool_call on the agent-obs server with: toolName, status (success/error), outputSummary, and durationMs. Never skip a call — even fast operations. Start a session with start_session at task start. End it with end_session when done. The only tools you do NOT log are the agent-obs tools themselves." | ||
| }); | ||
| } | ||
@@ -337,2 +341,3 @@ | ||
| function startServer() { | ||
| database.closeStaleSessions(); | ||
| log('Starting MCP server (stdio)'); | ||
@@ -339,0 +344,0 @@ |
+1
-1
| { | ||
| "name": "agent-obs", | ||
| "version": "1.0.0", | ||
| "version": "1.0.1", | ||
| "description": "Open source agent observability — see what your agents did, why they failed, and what it cost. Runs locally.", | ||
@@ -5,0 +5,0 @@ "main": "cli.js", |
+66
-10
@@ -96,2 +96,4 @@ # agent-observability | ||
| > **Note:** Proxy mode is a fallback for agents that cannot self-report. It only captures MCP tool calls (~30% of typical agent actions). Prefer the MCP server approach above. | ||
| All data is written to a local SQLite database in `~/.agent-observability/`. No data leaves your machine. | ||
@@ -115,2 +117,53 @@ | ||
| ## Agent-Specific Setup | ||
| ### Claude Code | ||
| 1. **MCP Config** — Create `.mcp.json` in your project root: | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "agent-obs": { | ||
| "command": "npx", | ||
| "args": ["-y", "agent-obs@latest", "server"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| 2. **Self-reporting instruction** — Create `.claude/instructions.md` (or reference the existing SKILL.md under `.claude/skills/agent-obs/SKILL.md`): | ||
| ```markdown | ||
| After every tool call, report to agent-obs's log_tool_call. | ||
| Start each task with start_session. End with end_session. | ||
| ``` | ||
| 3. **Verify** — Run `agent-obs dashboard`, open http://localhost:9400, and look for your session after the agent completes a task. | ||
| ### Cursor | ||
| 1. **MCP Config** — Add to Cursor's MCP settings (`~/.cursor/mcp.json`, or Settings → MCP → Add new global MCP server): | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "agent-obs": { | ||
| "command": "npx", | ||
| "args": ["-y", "agent-obs@latest", "server"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| 2. **Self-reporting instruction** — Create `.cursorrules` (or `.cursor/rules/agent-obs.md`): | ||
| ``` | ||
| After every tool call, you MUST call the agent-obs MCP server's log_tool_call tool. | ||
| Include toolName, status (success/error), outputSummary, and durationMs. | ||
| Start each session with start_session and end with end_session. | ||
| ``` | ||
| 3. **Verify** — Run `agent-obs dashboard`, open http://localhost:9400, and look for your session after the agent completes a task. | ||
| ## Architecture | ||
@@ -120,11 +173,2 @@ | ||
| ┌──────────────────────────┐ | ||
| │ agent-obs proxy │ | ||
| │ (transparent capture) │ | ||
| │ │ | ||
| MCP Client ───────▶│ intercepts tool calls ──▶│ MCP Server | ||
| (Claude/Cursor) │ logs to SQLite │ (filesystem, | ||
| └──────────┬───────────────┘ github, etc.) | ||
| │ | ||
| ▼ | ||
| ┌──────────────────────────┐ | ||
| │ agent-obs server │ | ||
@@ -143,2 +187,11 @@ │ (self-reporting) │ | ||
| ┌──────────────────────────┐ | ||
| │ agent-obs proxy │ | ||
| │ (fallback — MCP-only) │ | ||
| │ │ | ||
| MCP Client ───────▶│ intercepts tool calls ──▶│ MCP Server | ||
| (Claude/Cursor) │ logs to SQLite │ (filesystem, | ||
| └──────────┬───────────────┘ github, etc.) | ||
| │ | ||
| ▼ | ||
| ┌──────────────────────────┐ | ||
| │ ~/.agent-observability │ | ||
@@ -291,4 +344,7 @@ │ SQLite DB │ | ||
| ### MCP Observatory | ||
| MCP Observatory sits on top of Model Context Protocol servers and scores their health: uptime, response latency, tool success rate, error rate. It implements pass/fail gating — if a server's health score drops below a threshold, it's automatically excluded from the agent's available tools. **Pattern adopted here:** tool health scoring, session grading (A-F), and automatic degradation flags. | ||
| [**MCP Observatory**](https://github.com/KryptosAI/mcp-observatory) secures MCP servers — testing them for vulnerabilities, schema drift, and attack surfaces before agents depend on them. It's used by 850+ developers weekly and powers CI pipelines for MCP server security. **Use Observatory to secure your MCP servers. Use agent-obs to trace the agents that depend on them.** Observatory validates; agent-obs observes. | ||
| **Pattern adopted here:** tool health scoring, session grading (A-F), and automatic degradation flags. | ||
| ## Open Source vs Cloud | ||
@@ -295,0 +351,0 @@ |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
95559
4.14%1616
2.86%368
17.95%4
-20%