Skip to main content
Glama

MCP Standards

by airmcp-com
autolog.py8.35 kB
"""Autolog system for Claude Memory Automatically captures and centralizes knowledge across all Claude instances """ import json import sqlite3 from datetime import datetime from pathlib import Path from typing import Dict, Any, Optional # Significant tool patterns to auto-capture TOOL_SIGNIFICANCE = { # High priority (always log) "github_issue": 0.9, "github_pr": 0.9, "notion_create": 0.8, "notion_update": 0.8, "file_write": 0.7, "file_edit": 0.7, # Medium priority (log if significant file) "bash_command": 0.5, "file_read": 0.3, # Low priority (rarely log) "list_files": 0.1, "search": 0.1, } # Important files to track SIGNIFICANT_FILES = { "claude.md": 1.0, "readme.md": 0.9, "package.json": 0.8, "pyproject.toml": 0.8, "dockerfile": 0.8, ".env": 0.7, "requirements.txt": 0.7, } class AutoLogger: """Automatic knowledge capture from tool executions""" def __init__(self, db_path: Path): self.db_path = db_path self._ensure_db() def _ensure_db(self): """Ensure database exists with proper schema""" with sqlite3.connect(self.db_path) as conn: # Tool execution logs conn.execute(""" CREATE TABLE IF NOT EXISTS tool_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, tool_name TEXT NOT NULL, args TEXT, result TEXT, significance REAL, session_id TEXT, metadata TEXT ) """) # Extracted knowledge episodes conn.execute(""" CREATE TABLE IF NOT EXISTS episodes ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, name TEXT NOT NULL, content TEXT NOT NULL, source TEXT, tool_log_id INTEGER, tags TEXT, FOREIGN KEY(tool_log_id) REFERENCES tool_logs(id) ) """) # Search index conn.execute(""" CREATE VIRTUAL TABLE IF NOT EXISTS episodes_fts USING fts5( name, content, tags, content=episodes ) """) conn.commit() def should_log(self, tool_name: str, args: Dict[str, Any]) -> float: """Calculate if tool execution should be logged""" # Base significance from tool type base_score = TOOL_SIGNIFICANCE.get(tool_name, 0.2) # Boost for significant files if "file_path" in args or "path" in args: file_path = str(args.get("file_path", args.get("path", ""))).lower() for pattern, boost in SIGNIFICANT_FILES.items(): if pattern in file_path: base_score = min(1.0, base_score + boost) break # Boost for create/update operations if any(word in tool_name for word in ["create", "write", "update", "commit"]): base_score = min(1.0, base_score + 0.3) return base_score def log_tool_execution( self, tool_name: str, args: Dict[str, Any], result: Any, session_id: Optional[str] = None ) -> Optional[int]: """Log tool execution if significant""" significance = self.should_log(tool_name, args) if significance < 0.3: # Skip low significance return None with sqlite3.connect(self.db_path) as conn: cursor = conn.execute(""" INSERT INTO tool_logs (tool_name, args, result, significance, session_id) VALUES (?, ?, ?, ?, ?) """, ( tool_name, json.dumps(args), json.dumps(str(result)[:1000]), # Truncate large results significance, session_id or "default" )) log_id = cursor.lastrowid # Extract episode if highly significant if significance > 0.6: episode = self._extract_episode(tool_name, args, result) if episode: conn.execute(""" INSERT INTO episodes (name, content, source, tool_log_id, tags) VALUES (?, ?, ?, ?, ?) """, ( episode["name"], episode["content"], episode["source"], log_id, json.dumps(episode.get("tags", [])) )) # Update FTS index conn.execute(""" INSERT INTO episodes_fts (name, content, tags) VALUES (?, ?, ?) """, ( episode["name"], episode["content"], " ".join(episode.get("tags", [])) )) conn.commit() return log_id def _extract_episode(self, tool_name: str, args: Dict[str, Any], result: Any) -> Optional[Dict[str, Any]]: """Extract knowledge episode from tool execution""" if tool_name.startswith("github"): return self._extract_github_episode(tool_name, args, result) elif tool_name.startswith("notion"): return self._extract_notion_episode(tool_name, args, result) elif "file" in tool_name: return self._extract_file_episode(tool_name, args, result) return None def _extract_github_episode(self, tool_name: str, args: Dict[str, Any], result: Any) -> Dict[str, Any]: """Extract GitHub knowledge""" if "issue" in tool_name: return { "name": f"GitHub Issue: {args.get('title', 'Unknown')}", "content": f"Issue #{args.get('number', '?')} in {args.get('repo', 'unknown repo')}\n{args.get('body', '')}", "source": "github", "tags": ["github", "issue", args.get('repo', '')] } elif "pr" in tool_name: return { "name": f"Pull Request: {args.get('title', 'Unknown')}", "content": f"PR #{args.get('number', '?')} in {args.get('repo', 'unknown repo')}", "source": "github", "tags": ["github", "pr", args.get('repo', '')] } return None def _extract_notion_episode(self, tool_name: str, args: Dict[str, Any], result: Any) -> Dict[str, Any]: """Extract Notion knowledge""" return { "name": f"Notion: {args.get('title', 'Untitled')}", "content": args.get('content', ''), "source": "notion", "tags": ["notion", "documentation"] } def _extract_file_episode(self, tool_name: str, args: Dict[str, Any], result: Any) -> Dict[str, Any]: """Extract file operation knowledge""" file_path = args.get('file_path', args.get('path', 'unknown')) file_name = Path(file_path).name return { "name": f"File: {file_name}", "content": f"Modified {file_path}", "source": "file_operation", "tags": ["file", file_name.split('.')[-1]] # Extension as tag } # Global autologger instance _autologger = None def get_autologger(db_path: Optional[Path] = None) -> AutoLogger: """Get or create global autologger instance""" global _autologger if _autologger is None: if db_path is None: db_path = Path.home() / ".mcp-standards" / "knowledge.db" db_path.parent.mkdir(parents=True, exist_ok=True) _autologger = AutoLogger(db_path) return _autologger def autolog_tool(tool_name: str, args: Dict[str, Any], result: Any): """Simple interface for autologging tool executions""" logger = get_autologger() return logger.log_tool_execution(tool_name, args, result)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/airmcp-com/mcp-standards'

If you have feedback or need assistance with the MCP directory API, please join our Discord server