Chronicle MCP
Chronicle MCP is a local, offline stdio MCP server that lets agents search, read, import, organize, and persist AI chat transcripts and handoff state on disk.
Search archived chats with BM25 semantic, keyword, date-range, and related-chat methods; active handoff receipts are ranked first.
Browse or read chats with pagination, message ranges, summaries, metadata, and token-saving truncation/code-block summarization.
Import/sync transcripts from pasted content, local files, or editor transcript folders, normalizing ChatGPT, Claude, Cline/Continue, JSONL, and Markdown formats.
Compile insights: extract action items, build topic indexes, compare chats, and generate Markdown project briefs.
Maintain storage: compress old chats, find/remove duplicates, update settings, and report server capabilities.
Manage live sessions: save, register/trigger auto-save, merge messages, export Markdown, delete with confirmation, and watch folder changes.
Save and check handoff receipts to track obligations, work state, evidence, blockers, stale conditions, and next safe actions.
Use MCP prompts/resources for starting/recalling sessions and exposing capabilities or archived chat listings.
Chronicle MCP: Local AI Chat History Search & Memory
Private, offline memory for your AI coding agents. Chronicle MCP (chronicle-mcp-server) is a local stdio MCP server that indexes your Cursor, Claude, ChatGPT and Cline chat transcripts on your own machine and serves BM25 search over them, so agents can recall past conversations without re-pasting them, using up to 40% fewer context tokens. Your archive and index stay on disk: no cloud service, account, or API key.
Chronicle is a Model Context Protocol (MCP) server that syncs, cleans, formats, and indexes AI chat transcripts entirely on your machine. By bridging the gap between local editor history and large language model contexts, Chronicle allows agents to search, compare, retrieve, and reference past conversation logs. It features optimized token-saving heuristics that compress code blocks and limit message lengths, reducing context window utilization by up to 40 percent.
Listed on
What's new in 1.6.2
Fixes fresh installs. Earlier releases let pip install mcp 2.x, which the server cannot run on. The dependency is now
mcp>=1.22,<2.Rewritten tool definitions. Every tool has a title, a description of what it does and when to use it, side effects and return value, and annotations (
readOnlyHint,destructiveHint, ...). Every parameter is documented and every operation selector is an enum.Real error results. Failures now come back with
isError: true, and unknown operation names are rejected instead of silently running a different operation.New ways to run it:
uvx chronicle-mcp-server,chronicle serve,chronicle --versionand a Dockerfile.Server instructions, a
recall_past_workprompt, and two resources:chronicle://capabilitiesandchronicle://chats.
What's new in 1.6.1
CI on Python 3.10 to 3.13, plus build and
twine checkon every push and pull request.Accurate tool catalog: 8 tools plus the
start_sessionprompt, whichmaintain_storage(op_type="capabilities")now reports too.Richer PyPI metadata (project links, keywords, classifiers) and a cleaner repository with no committed build artifacts.
See the full CHANGELOG for earlier releases.
Related MCP server: conversation-history-mcp
Key Architectural Capabilities
Format Normalization Engine
AI providers and editor clients save conversation logs in diverse formats. Chronicle normalizes these structures into a standard role-and-content message format:
ChatGPT Exports: ChatGPT exports conversation histories in recursive mapping node structures. Chronicle traverses and flattens these maps, sorts messages chronologically by creation timestamp, and extracts the plain-text message threads.
Claude Exports: Claude structures messages as flat lists nested under the chat_messages field. Chronicle parses these lists, maps custom sender roles (such as human and assistant) to standard roles, and cleans the text strings.
Generic and Markdown Formats: Chronicle includes parsers for flat JSON message lists (such as Cline or Continue) and structured Markdown logs (mapping headers like User and Assistant to message boundaries).
Context Token Optimization
Large chat logs can quickly exhaust context windows and increase API costs. Chronicle implements proactive token-saving mechanisms:
Code Block Summarization: Automatically replaces verbose code blocks with metadata summaries indicating the programming language and line count. This behavior can be disabled on demand to read full code snippets.
Length Limiting: Truncates extremely long individual messages at a configurable character threshold, appending a notice that the user can re-run the tool with expanded limits if necessary.
Context Window Token Savings Graph
To verify these savings, we executed multi-turn conversation benchmarks. The graph below displays total token usage over a sequence of message turns:

By condensing repetitive syntax and large raw code snippets, Chronicle achieves up to 40 percent token savings, directly lowering API usage costs and preventing context-window exhaustion.
Hybrid Splitting & BM25 Scoring Search Engine
To make workspace searches extremely sharp and retrieve context-aware answers, Chronicle incorporates a state-of-the-art retrieval pipeline:
Hybrid Document Splitting: Slices long conversations into logical parts at indexing time. Splits are triggered temporally if a gap of more than 1800 seconds (30 minutes) occurs between consecutive messages, or lexically if the Jaccard similarity of vocabulary sliding groups of 4 messages drops below 0.12. Each split is stored and queried as a virtual document (
filename__chunk_idx).Okapi BM25 Scorer: Replaces naive keyword matching and raw TF-IDF with Okapi BM25 scoring (
k1 = 1.5andb = 0.85). The parameterb = 0.85enforces an aggressive length penalty, which ensures long, rambling chat logs do not overshadow short, precise bug fixes.Handoff Receipts Prioritization: Integrates a direct tool to save compact agent state files documenting modified paths, commitments, skipped tests, and next actions. Active handoff receipts are automatically prioritized and bubbled to the very top of search results.
Command Line Interface Mechanics
The cli.py file serves as the system's entry point, registering a unified chronicle command on the system path via the pyproject.toml configuration (chronicle = "cli:main").
1. Interactive Setup Wizard
Chronicle features an interactive, zero-dependency TTY setup wizard. Running chronicle setup or executing chronicle without arguments in an interactive terminal starts the setup flow:
The setup wizard is styled with a premium purple theme, supporting arrow-key navigation, spacebar toggles, inline input editing, and real-time path validation!
Keyboard Navigation & Controls
Use the following controls when interacting with the select menu:
Command / Action | Key Control | Description |
Move Highlight |
| Navigates the interactive list focus |
Toggle Checkbox |
| Selects or deselects the highlighted app |
Enter Custom IDE | Navigate to Other & type | Type custom app directory directly inline |
Erase Character |
| Removes characters inside the custom entry |
Confirm & Inject |
| Validates target existence and runs config injection |
Cancel Setup |
| Aborts setup process cleanly |
Wizard Phases & Actions
The wizard guides you through the following phases:
Step | Phase Name | What You Do | Result & Behavior |
Step 1 | Monolithic Split Engine | Input JSON file path (or press | Automatically partitions unified chat history exports |
Step 2 | Storage Directory Configuration | Specify directory path (or press | Creates local storage folder for transcripts |
Step 3 | Interactive IDE Selection | Toggle checkboxes, navigate submenus, type custom targets | Performs TTY selection and checks path validation |
Step 4 | Config Injection & Live Dashboard | Review final summary configuration | Injects server configs into target IDE settings |
HOW TO USE THE WIZARD — A STEP-BY-STEP SHOWCASE GUIDE
Start the Process: Launch the wizard with
chronicle setupin your terminal.Split Monolithic Files: Paste the path to your exported
conversations.json(from ChatGPT or Claude). This splits them into clean individual threads inside your chats folder.Define Your Chats Directory: Keep the default
~/universal-chatsfolder or type a custom path.Select Your Target IDEs:
Press
Down Arrowto scroll down to VS Code, Trae, etc.Press
Spaceto toggle selections.If you select Antigravity, checking it will automatically expand sub-choices (Antigravity IDE, Antigravity 2.0, Antigravity CLI) right underneath!
Scroll down to Other (Enter custom entry) and type any system-specific folder name to add emerging editors.
Real-time Path Validation: If the custom configuration path parent doesn't exist, a warning alerts you at the bottom:
⚠ App/IDE "<name>" was not found on your system.. Erase it withBackspaceor type a valid path to proceed.
Complete and Launch: Press
Enterto write the JSON configuration file for all selected apps. The Live Environment Dashboard will display a complete summary of your workspace configs.
Step 1: Launch the Setup Wizard
Run the setup command:
chronicle setupStep 2: The Monolithic Split Engine
The wizard asks if you want to partition any monolithic chat logs (such as the single conversations.json from ChatGPT/Claude exports) into separate files in your new storage folder:
── Chronicle Archive Setup ─────────────────────────────────────
Do you want to split a single conversations.json file?
Enter path to export file (or press ENTER to skip): Step 3: Configure Storage Path
Define the folder path where Chronicle will clean and store all conversation history:
Enter path to folder containing your conversations [Default: ~/universal-chats]:
✓ Using existing storage directory: /Users/username/universal-chats
Successfully set chats directory to: /Users/username/universal-chatsStep 4: Interactive IDE Selector
An interactive selection menu with a premium purple theme. Navigate with the arrow keys, toggle checkboxes with the Spacebar, edit custom inputs inline, and press Enter to confirm:
Please select the applications/IDEs where you want to install Chronicle MCP:
(Use arrow keys to navigate, Space to toggle, Enter to confirm)
[✓] Cursor
[ ] VS Code (Cline / Roo Code)
[ ] Trae IDE
[ ] Claude Code
[ ] Windsurf
[ ] Claude Desktop
[ ] ChatGPT Desktop
❯ [✓] Antigravity
[✓] Antigravity IDE
[ ] Antigravity 2.0
[ ] Antigravity CLI
Other (Enter custom entry): If you enter a custom app/IDE name under "Other" that does not exist on your system, the wizard's built-in path validation checker will instantly display a warning at the bottom:⚠ App/IDE "mycustomide" was not found on your system.
Step 5: Inject Configs & Live Environment Dashboard
Once selections are confirmed, Chronicle automatically resolves uvx paths on your system, writes the MCP server configuration into each selected app, and presents a live environment dashboard summary:
── Chronicle Environment Live ──────────────────────────────────
✓ Storage Folder : /Users/username/universal-chats
✓ Auto-Saved Configs for: [Cursor, Antigravity IDE]
How to run the server manually:
$ uvx --from chronicle-mcp-server chronicle
recalled in <1ms · 100% local · zero cloud
────────────────────────────────────────────────────────────────2. Unified Chronicle Global Command
When run without subcommands, the chronicle command behaves contextually:
Interactive TTY Terminal: Launches the interactive setup wizard.
Non-TTY/Subprocesses: Launches the stdio transport server for MCP clients.
It accepts options like --chats-folder to configure custom storage directories, and exposes the subcommands add and split.
3. Cross-Platform Path Resolution Rules
The CLI implements path resolution logic using Python's sys.platform and pathlib.Path to match standard OS conventions for user directories:
macOS (Darwin): Resolves configurations to the user's home Library folder, typically under
~/Library/Application Support/.Windows (Win32): Leverages the
%APPDATA%environment variable, falling back to~/AppData/Roaming/if the variable is not set.Linux: Follows the XDG base directory specification, resolving to
~/.config/.
4. Native IDE Integration and Fallback Engine
The CLI wrapper provides out-of-the-box support for leading AI-assisted development tools and editors:
Cursor: Reads and writes configurations to
~/.cursor/mcp.json.Claude Code: Integrates with
~/.claude.json.VS Code (Cline/RooCode/Continue): Standardizes pathing across platforms:
macOS:
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.jsonWindows:
%APPDATA%/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.jsonLinux:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
Trae: Resolves configuration to:
macOS:
~/Library/Application Support/Trae/mcp.jsonWindows:
%APPDATA%/Trae/mcp.jsonLinux:
~/.config/Trae/mcp.json
Dynamic Fallback Engine: For emerging platforms (such as Kiro, MiniMax, Qwen Code, Grok Build, or Antigravity), the CLI employs a fallback search pattern. It first checks for a user home dot-directory configuration (such as
~/.<app_name>/mcp.json). If that directory is missing, it creates the app-specific configuration in the standard application support folder for the respective platform (e.g.~/Library/Application Support/<app_name>/mcp.jsonon macOS).
5. Prevent ENOENT Errors with shutil.which
Host clients (like Claude Desktop or Cline) spawn MCP servers within isolated subprocesses that often do not inherit the user's login shell environment variables (such as custom paths defined in .bashrc or .zshrc).
To solve this, the chronicle add utility uses Python's shutil.which("uvx") to scan the host machine path during configuration. It resolves the absolute system path of uvx (such as /opt/homebrew/bin/uvx or /usr/local/bin/uvx) and writes this absolute path directly to the IDE's JSON configuration file.
6. Structural Split Engine Subcommand
Users downloading conversational archives from ChatGPT or Claude are often provided with a single monolithic JSON file (such as conversations.json) containing hundreds of distinct threads.
The chronicle split subcommand parses these large payloads and splits them into individual JSON files:
Automatically detects the schema format (nested conversation trees or flat lists).
Identifies thread titles using key fallback fields (checking
title,name, andchat_title).Sanitizes file names to remove platform-forbidden characters (such as
/,\,*,?,:,",<,>, and|) and limits length.Resolves filename collisions by appending incremental numeric suffixes.
chronicle split /path/to/conversations.json --out /path/to/output_directory7. Global Chats Folder Configuration
By default, Chronicle stores processed archives in ~/.chronicle/chats. You can configure a custom global storage folder using the --chats-folder parameter:
chronicle --chats-folder /path/to/custom/chatsThis saves the target path to a local settings file (~/.chronicle_settings.json), allowing you to centralize your archives across multiple development environments.
Tool Reference Catalog
Chronicle consolidates its behaviors into 8 parameterized tools (six core tools plus two handoff tools), two prompts and two resources. This design avoids cognitive overhead for client AI models while preserving the server's complete feature set. Everything runs locally: no tool contacts the network (openWorldHint: false).
Tool | Title | Read-only | Destructive | Idempotent |
| Search Chat History | yes | no | yes |
| Read Chat Logs | yes | no | yes |
| Get Handoff Status | yes | no | yes |
| Import Chats | no | no | no |
| Compile Project Insights | no | no | yes |
| Save Handoff Receipt | no | no | no |
| Maintain Storage | no | yes ( | yes |
| Manage Session State | no | yes ( | no |
Validation and errors. The operation selectors (method, view_type, source_type, insight_type, op_type, action) are enums, and counts such as limit, top_k, page and per_page must be at least 1. Invalid values are rejected before the tool runs. Execution failures, such as a missing chat file, an invalid date or a missing required argument for the chosen operation, are returned as MCP results with isError: true and a message explaining what to fix.
1. search_history
Description: Unified search and filter interface for local chat transcripts. Supports keyword, Okapi BM25 semantic, date range, and related chat lookups.
Parameters:
query(str, default: ""): The search query string or keywords list.method(str, default: "semantic"): Search methodology. Supported options:semantic: Standard semantic retrieval using Okapi BM25 scoring with exponential temporal decay.keyword: Exact string matching against terms in files.date_range: Filters files modified within a date interval (requiresstart_dateandend_date).related: Finds archives semantically close to a reference file.
keywords(list of strings, optional): Optional list of keywords for keyword search.start_date(str, optional): Start date string (YYYY-MM-DD) for date range filtering.end_date(str, optional): End date string (YYYY-MM-DD) for date range filtering.limit(int ≥ 1, default: 50): Maximum result count for keyword or date range searches.top_k(int ≥ 1, default: 10): Maximum matches for semantic or related chat searches.client(str, default: "default"): Subfolder client identifier.file_name(str, optional): Reference chat filename for related search.
2. get_chat_logs
Description: Unified read interface for stored transcripts. Fetches paginated file lists, summaries, file metadata, or message ranges with token-saving options.
Parameters:
chat_id(str, optional): Filename of the target chat. If omitted, lists all available files.view_type(str, default: "content"): The type of information to retrieve. Supported options:content: Message text slice within specified index ranges.metadata: File statistics including message counts and modification dates.summary: Structural summary highlighting the opener and closer context.
start_msg(int ≥ 1, default: 1): Message slice start index (1-indexed).end_msg(int ≥ 1, default: 20): Message slice end index.max_msg_len(int, default: 1000): Character limit for messages to prevent token inflation. Set to 0 for unlimited.summarize_code(bool, default: True): Summarizes markdown code blocks into metadata headers.page(int ≥ 1, default: 1): Page index for folder listing (used whenchat_idis omitted).per_page(int ≥ 1, default: 50): Page result limit for folder listing.client(str, default: "default"): Subfolder client identifier.
3. sync_workspace_data
Description: Ingests, imports, and syncs external conversation transcripts or workspace logs from various tools and formats.
Parameters:
source_type(str): Source type identifier. Supported options:raw_content: Direct JSON import from text buffers or clipboard paste.local_path: Copies a JSON file from a local path on disk.agent_transcripts: Syncs transcripts (JSON, JSONL, MD) from configured third-party client folders.cursor_agent_transcripts: Deprecated. Scans Cursor workspace project transcript folders.
payload(str, dict, or list, optional): Input data payload (raw JSON text, file path on disk, or folder path).title(str, optional): Target file name or title for imports.source_dir(str, optional): Override folder directory for scanning transcripts.limit(int ≥ 1, default: 50): Maximum files to synchronize.client(str, default: "default"): Subfolder client identifier.
4. compile_project_insights
Description: Aggregates and compiles insights from chat logs, including action item extraction, index indexing, chat comparisons, and brief generation.
Parameters:
insight_type(str): Compilation format. Supported options:action_items: Extract todos, checkboxes, and task lists.knowledge_index: Rebuild or list the topic-categorized index of files.compare_chats: Analyze and detail shared and unique terms across two files.project_brief: Synthesize summaries and action items from multiple chats into one markdown document.
target_chats(list of strings, optional): List of target chat filenames for briefs or comparisons.file_name(str, optional): Target chat filename for action item extraction.file_name_a(str, optional): First chat filename for comparison.file_name_b(str, optional): Second chat filename for comparison.brief_title(str, default: "Project Brief"): Title header for compiled briefs.rebuild(bool, default: False): Re-scans all files to update the knowledge index.summary_only(bool, default: False): Returns topic file counts instead of full file lists in index lookup.client(str, default: "default"): Subfolder client identifier.
5. maintain_storage
Description: Performs server operations, storage cleanups, settings configuration, and capabilities lookup.
Parameters:
op_type(str): Maintenance operation name. Supported options:compress: Compresses historical archives older than a set age using Gzip.deduplicate: Content-hash based search and deletion of duplicate logs.configure: Updates auto-save message limits, paths, and transcripts.capabilities: Returns server meta-capabilities and client configurations.
settings(dict, optional): Settings payload dict (for configure).days_old(int ≥ 1, optional): Cutoff threshold age in days for compression (default 30).dry_run(bool, default: True): Lists duplicates without performing deletions.client(str, default: "default"): Subfolder client identifier.
6. manage_session_state
Description: Manages active session caching, folder monitoring, file merges, markdown exports, and file deletions.
Parameters:
action(str): Operation to perform. Supported options:save: Commits active messages list to storage.register_auto_save: Registers the session for auto-saving on connection termination.trigger_auto_save: Instantly flushes pending sessions to disk.watch_folder: Reports file changes since the last execution.merge: Appends new messages to an existing chat archive.export_markdown: Converts a JSON transcript to a Markdown document.delete: Permanently deletes an archive file (requires confirm=True).
conversation_name(str, optional): Active conversation name.messages(list of dicts, optional): Message list payload.force_save(bool, default: False): Saves the chat session even if below message limit thresholds.file_name(str, optional): Target file name.confirm(bool, default: False): Confirms deletion.new_messages(list of dicts, optional): Message list to merge.client(str, default: "default"): Subfolder client identifier.
7. save_handoff_receipt
Description: Saves a structured handoff receipt that documents the current run's state (obligations, work state, evidence, and the conditions that invalidate it) so the next agent can continue safely. Receipts form a chain through
supersedes, are indexed, and active receipts are bubbled to the top of search results.Parameters:
obligations(dict): Open promises and commitments left for the next agent.work_state(dict): Current state of the work, such as touched files and progress.evidence(dict): Supporting evidence, such as checks that ran or were skipped.invalidation(dict): Conditions that make the receipt stale (for example, monitored files) and thenext_safe_actionto take.status(str, default: "open"): Receipt status.supersedes(str, optional): ID of the earlier receipt this one replaces.closure(dict, optional): Closure details (closed_by,closed_at,closure_basis,closure_evidence) when closing a receipt.receipt_id(str, optional): Explicit receipt ID. If omitted, one is generated.
Returns: the saved file name and its
receipt_id, which a later receipt passes assupersedes.client(str, default: "default"): Subfolder client identifier.
8. get_handoff_status
Description: Returns the current workspace handoff state: the active chain of receipts, whether the workspace is blocked (for example, by files modified after the receipt was written), and the next safe action.
Parameters:
client(str, default: "default"): Subfolder client identifier.
Prompt: start_session
Title: Start a Chronicle Session
Description: Returns system instructions that tell the agent to register the conversation with
manage_session_state(action="register_auto_save") at the start of a chat, so the session is saved automatically.
Prompt: recall_past_work
Title: Recall Past Work
Arguments:
topic(str): what to look up, such as "the auth refactor".Description: Walks the agent through checking
get_handoff_status, searching withsearch_history, and reading the best hits withget_chat_logsusing small message ranges.
Resources
chronicle://capabilities(JSON): the same server capabilities report asmaintain_storage(op_type="capabilities").chronicle://chats(text): the first page of archived chat files, asget_chat_logslists them.
Installation and Configuration
Quick Setup (Recommended)
Install the package directly from PyPI and run the interactive setup wizard to configure your storage paths and editor integrations automatically:
pip install chronicle-mcp-server
chronicle setupSystem Prerequisites
Python 3.10 or higher.
Python package
mcp1.22 or later, below 2.0 (the Model Context Protocol SDK; installed automatically).Python
setuptools(for installation as a package).
Run the Server Directly
MCP clients start Chronicle over stdio. Any of these commands works as the server command in a client config:
uvx chronicle-mcp-server # no install needed
chronicle-mcp-server # after pip install chronicle-mcp-server
chronicle serve # same server, through the main CLI
chronicle --versionEnvironment variables (all optional):
Variable | Purpose |
| Archive folder (default |
| Extra transcript folder for |
| stderr log level (default |
| Set to |
Docker
The image runs the same stdio server, with the archive in a /data volume:
docker build -t chronicle-mcp .
docker run -i --rm -v "$HOME/.chronicle:/data" chronicle-mcpAlways pass -i, because MCP traffic goes over stdin and stdout. In a client config, use docker as the command and ["run", "-i", "--rm", "-v", "/path/to/archive:/data", "chronicle-mcp"] as the arguments. Inside a container Chronicle can only see the folders you mount, so importing editor transcripts also needs those folders mounted (and TRANSCRIPTS_DIR pointed at them).
MCP Bundle (Claude Desktop, Smithery)
mcpb/ holds an MCP Bundle manifest for one-click installs in clients that support .mcpb files and for the Smithery registry. The bundle is a thin wrapper: it runs the pinned PyPI release with uvx, so uv must be installed. Build it with:
npx @anthropic-ai/mcpb pack mcpb chronicle-mcp.mcpbCI validates the manifest and uploads the packed bundle as the chronicle-mcp-mcpb artifact on every run.
Manual Installation
Clone the repository:
git clone https://github.com/Leviathan0x0/Chronicle-MCP.git cd Chronicle-MCPSet up a Python virtual environment:
python3 -m venv venv source venv/bin/activateInstall dependencies and the package in editable mode:
pip install -e .
Automatic Session Saving in Cursor and VS Code
Since editors (like Cursor or VS Code) do not notify MCP servers when a chat window or tab is closed, Chronicle implements a multi-step solution to ensure your conversation history is saved automatically:
1. Process Exit Handler (Automatic Flush)
The Chronicle server includes an exit handler registered via Python's atexit module. When you close a chat tab or close the editor, the editor terminates the stdio connection, shutting down the Chronicle process. Upon receiving this shutdown trigger, the server automatically flushes the registered pending session to the local chats folder.
2. Workspace Rules Generation (Opt-in)
For this flush to succeed, the active chat session must be registered during the conversation. There are two ways to tell the agent to do that:
Use the
start_sessionprompt, or rely on the server instructions, which MCP clients pass to the model.Opt in to rule files by setting
CHRONICLE_AUTO_CONFIGURE_RULES=1in the server environment. On startup Chronicle then creates or appends the rule in the active workspace's rule files (such as.cursorrules,.clinerules,.windsurfrulesand.clauderules). This is off by default, so the server never writes into your projects unless you ask it to.
The rule states:
At the beginning of the chat session, you must call the "manage_session_state" tool with action="register_auto_save" to register this conversation. Provide a descriptive title based on the user's initial prompt. As the conversation progresses, periodically update the registration payload to keep it current.This ensures that the chat history is registered dynamically, and Chronicle will write the complete history to your storage folder as soon as the editor terminates the connection.
Running Verification and Tests
Chronicle contains unit and integration tests to verify platform path resolution, parsing logic, and tool compatibility:
1. Run Unit Tests
To execute the suite of unit tests verifying core business logic:
python3 -m unittest discover -p "test_*.py"2. Run Integration Tests
To exercise all 8 tools end to end (point CHRONICLE_BASE_DIR at a scratch folder so your real archive is untouched):
CHRONICLE_BASE_DIR="$(mktemp -d)" python3 test_all_tools.py3. MCP Introspection and Live Smoke Test
test_mcp_introspection.py runs as part of the unit tests. It starts the server over stdio and fails if any tool, parameter, prompt or resource loses its description, title or annotations, if errors stop setting isError, or if version numbers drift apart. smoke_test_live.py runs read-only checks against your real archive, or against any server command:
python3 smoke_test_live.py
python3 smoke_test_live.py --command docker run -i --rm -v "$HOME/.chronicle:/data" chronicle-mcpAll of these run in CI on Python 3.10 to 3.13, plus a run against the minimum supported mcp release (1.22), a python -m build and twine check packaging job, and a Docker job. The Docker job builds the image and checks initialize and tools/list over stdio.
Market Comparison Matrix
Features | Chronicle MCP | Mem0 | Raw RAG / Naive VecDB |
Cloud Dependency | Local first (Zero Cloud dependencies) | Cloud-reliant | Cloud or complex local setup |
Token Savings | Up to 40% reduction (Smart code folding and pruning) | None (transfers full history) | None |
Setup Complexity | 1-click CLI installer ( | Requires API keys and database configs | High (VecDB setups and loaders) |
Auto-Save Support | Native via workspace rules and exit hooks | Requires manual application integration | None |
Local Resources | Minimal CPU and RAM (lightweight local BM25 index) | Heavy | High (vector indexing overhead) |
Contributing
We welcome community contributions. To get started:
Fork the repository and create a new branch.
Write unit tests for new behavior inside
test_chat_connector.py.Verify all code changes by running the test suite locally:
python3 -m unittest discover -p "test_*.py" CHRONICLE_BASE_DIR="$(mktemp -d)" python3 test_all_tools.pyEnsure code formatting is clean and all imports are properly sorted.
Submit a pull request detailing your changes and test coverage.
Releasing
Bump the version in pyproject.toml, server.json, mcpb/manifest.json (version and the pinned mcp_config.args) and mcpb/server/main.py, add a CHANGELOG.md entry, then publish a GitHub release tagged v<version>. The publish workflow builds the package and uploads it to PyPI through trusted publishing.
Public Roadmap
Planned future features and enhancements for Chronicle:
Local Embeddings: Add optional local vector retrieval using lightweight ONNX models.
Database Auditing: Automatic cache cleanups and data integrity audits for historical logs.
Dynamic Tailoring: Specific prompt formats optimized for different LLM host architectures (Claude, GPT, Gemini).
Extended IDE Support: Out-of-the-box config injection scripts for additional emerging developer environments.
Frequently Asked Questions (FAQ)
General & Setup Inquiries
Q: What is the benefit of the new Interactive Setup Wizard?
A: It completely automates the configuration process. In less than 10 seconds, it configures your storage directory, partitions raw monolithic conversation logs, checks system environments, validates custom paths, and injects configurations into all target applications.
Q: Why does the setup wizard use a purple theme?
A: Chronicle is designed to feel premium and state of the art. The setup wizard uses a vibrant, highly readable purple/magenta theme (
\033[1;35m) with custom cursor pointers (❯) and status checks ([✓]) for an optimized terminal experience.
Q: What happens if a custom app directory is not found on my system?
A: The interactive selector prevents invalid configurations. If you type a custom name under "Other" whose configuration directory cannot be resolved, an alert appears inline at the bottom:
⚠ App/IDE "<name>" was not found on your system.. You can easily backspace and edit the input without losing other selections.
Q: How does the Automatic Session Saving work?
A: Chronicle generates workspace rule files (e.g.
.cursorrules,.clinerules) instructing your AI agent to register the session at startup. On tab or editor shutdown, the server's process exit hooks trigger an automatic flush to write the transcripts to your storage folder.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Available Tools
8 toolscompile_project_insightsCompile Project InsightsAIdempotent
Derive structured insight from archived chats: action items, a topic index, a two-chat comparison, or a Markdown project brief. Use it when you need a digest rather than raw text; to find chats use search_history and to read them use get_chat_logs. insight_type 'action_items': TODOs, checkboxes and 'next' tasks from file_name (or the first of target_chats), returned as a list of strings. 'knowledge_index': chats grouped by topic, returned as {topic: [files], built_at}, or file counts when summary_only=true (use that on large archives); rebuild=true rescans every file. 'compare_chats': shared and unique topics of file_name_a and file_name_b (or the first two target_chats) as Markdown. 'project_brief': merges summaries and action items of target_chats (or file_name) into exports/<brief_title>.md and returns its path. Side effects: 'project_brief' writes or overwrites an export file; 'knowledge_index' rewrites the cached index file. Chat files are never modified.
| Name | Required | Description | Default |
|---|---|---|---|
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| rebuild | No | For 'knowledge_index': rescan all chats instead of returning the cached index. | |
| file_name | No | Single chat file for 'action_items' (or a one-chat 'project_brief'), such as 'my-chat.json'. | |
| brief_title | No | Heading and export file name for 'project_brief' (an existing brief with this title is overwritten). | Project Brief |
| file_name_a | No | First chat file for 'compare_chats'. | |
| file_name_b | No | Second chat file for 'compare_chats'. | |
| insight_type | Yes | Which insight to produce (see the tool description). | |
| summary_only | No | For 'knowledge_index': return file counts per topic instead of full file lists. | |
| target_chats | No | Chat file names: all of them for 'project_brief', the first two for 'compare_chats', the first for 'action_items'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare write-capable, idempotent, non-destructive, closed-world, and the description builds on that by naming exactly what gets written: 'project_brief' writes/overwrites exports/<brief_title>.md and 'knowledge_index' rewrites the cached index file. It also reassures that 'Chat files are never modified', which is context the flags alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose and alternative routing, then lays out each insight_type in a compact clause. Dense but every sentence carries mode-specific information; minor redundancy between the description and 100%-covered schema descriptions keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, four-mode tool with a sibling cluster, the description covers purpose, mode selection, side effects, and parameter routing. An output schema exists, and the description still summarizes return shapes ({topic: [files], built_at}, path of written brief) so the agent is not left guessing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, yet the description adds genuine cross-parameter meaning: which parameter each insight_type consumes (file_name or first of target_chats for action_items, file_name_a/b or first two target_chats for compare_chats), and when rebuild/summary_only matter. It stops short of documenting client-namespace or brief_title overwrite nuance, keeping it a 4 rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Derive structured insight from archived chats') and enumerates the four concrete outputs: action items, topic index, two-chat comparison, and Markdown brief. It also names the sibling tools (search_history, get_chat_logs) that do the adjacent jobs, so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('when you need a digest rather than raw text') plus explicit routing to alternatives for finding and reading chats. Per-mode guidance is also given, e.g. summary_only=true 'on large archives' and rebuild=true rescans every file, so the agent knows the conditions that select each path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chat_logsRead Chat LogsARead-onlyIdempotent
List archived chats, or read one chat as a message range, a short summary, or metadata. Use it after search_history to open a hit, or with no chat_id to browse the archive page by page. To search by topic use search_history instead. Without chat_id: returns a page header '[Page N of M (Total chats: T)]' followed by file names. With chat_id: view_type 'content' returns messages start_msg..end_msg as plain text with a '... of N total' header, truncating each message to max_msg_len characters and collapsing code blocks to one-line summaries unless summarize_code=false; 'summary' returns the opener and closer; 'metadata' returns {file_name, title, message_count, file_size_bytes, last_modified, saved_at, client}. Older chats are shown pruned to save tokens. Keep ranges small (the default is 20 messages): max_msg_len=0 with a wide range can return a whole transcript. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based) when listing chats without chat_id. | |
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| chat_id | No | Chat file or chunk id to read, such as 'my-chat.json' or 'my-chat__part_2.json'. Omit to list chats. | |
| end_msg | No | Last message to return (inclusive) for view_type='content'. | |
| per_page | No | Chats per page when listing without chat_id. | |
| start_msg | No | First message to return (1-based) for view_type='content'. | |
| view_type | No | What to return for chat_id: message text ('content'), file statistics ('metadata') or a short 'summary'. | content |
| max_msg_len | No | Per-message character cap for view_type='content'; 0 means no cap (can be very large). | |
| summarize_code | No | Replace fenced code blocks with a one-line language and line-count summary to save tokens. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/idempotent annotations by disclosing return shapes per view_type, message truncation, code-block collapsing, and that older chats are shown pruned to save tokens. The token-blowup warning is concrete. It stops short of stating whether list results paginate deterministically or what happens on an out-of-range page, so a 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence front-loads the two modes and the routing hint, which is exactly the right ordering. The second paragraph is one long semicolon-chained sentence covering every view_type, which is dense but nearly all of it is load-bearing; a short bulleted split would read better.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter dual-mode tool with an output schema, the description covers both modes, each view_type, defaults, and the token-risk caveat. Nothing an agent needs to make a correct first call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns an extra point by explaining parameter interactions the schema does not — e.g. max_msg_len=0 combined with a wide range returns a whole transcript, and 'keep ranges small (the default is 20 messages)'. It also ties start/end_msg and view_type to the active chat_id path.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names specific verbs and resources: list archived chats, or read one chat as a message range, summary, or metadata. It also explicitly separates itself from search_history ('To search by topic use search_history instead'), so an agent can route without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use scenarios: after search_history to open a hit, or with no chat_id to browse page by page. It also names the exclusion (topic search belongs to search_history), leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_handoff_statusGet Handoff StatusARead-onlyIdempotent
Check whether this workspace has unfinished work handed off by an earlier agent. Call it at the start of a session on a project, before editing; to record a handoff use save_handoff_receipt. Returns {blocked, blocked_by_receipt, active_chain (newest first), newest_receipt_id, next_safe_action}; with no receipts it returns {blocked: false, reason, active_chain: []}. When blocked is true, follow next_safe_action (stale receipts tell you to re-verify first). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| reason | No | |
| blocked | No | |
| active_chain | No | |
| next_safe_action | No | |
| newest_receipt_id | No | |
| blocked_by_receipt | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds important behavioral context: what the return shape contains, how the no-receipts case behaves, and what to do when blocked is true, including stale receipts requiring re-verification.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: purpose first, usage timing second, return behavior third, and blocked handling last. Every sentence contributes useful information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and annotations cover safety and idempotency, the description provides enough additional context for an agent to call the tool correctly: when to call it, what the output represents, and how to react to a blocked status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single optional client parameter is already documented in the schema as the archive namespace with built-in values. The description adds no parameter-specific meaning beyond what the schema provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: checking whether the workspace has unfinished work handed off by an earlier agent. It clearly distinguishes itself from save_handoff_receipt, which is named as the write-side alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to call it at the start of a session on a project and before editing, and directs recording a handoff to save_handoff_receipt. Both when-to-use and the alternative are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
maintain_storageMaintain StorageADestructiveIdempotent
Housekeeping for the archive: compress old chats, find or remove duplicates, change settings, or report server capabilities. Use it for storage and configuration only, not for reading or searching chats. op_type 'compress': gzips chats older than days_old (default from settings, 30) in place and returns {compressed, skipped_recent, days_threshold}; compressed chats stay readable and searchable. 'deduplicate': finds chats with identical content; with dry_run=true (default) it only lists them, with dry_run=false it permanently deletes the duplicates, returning {dry_run, duplicates, unique_count}. 'configure': updates settings (see 'settings') and returns which keys changed. 'capabilities': read-only summary of tools, prompts, version and client paths. Destructive only for deduplicate with dry_run=false; ask the user before doing that.
| Name | Required | Description | Default |
|---|---|---|---|
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| dry_run | No | For 'deduplicate': true lists duplicates only; false deletes them permanently. | |
| op_type | Yes | Maintenance operation (see the tool description). | |
| days_old | No | For 'compress': minimum age in days; omit to use compression_days_threshold (30 by default). | |
| settings | No | For 'configure' only. Allowed keys: auto_save_message_threshold (int, messages before manage_session_state save persists), compression_days_threshold (int), summary_pruning_days_threshold (int), client_paths (object: client name to a relative folder), transcripts_dirs (object: client name to a folder), cursor_transcripts_dir (string). Unknown keys are ignored. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that compress is in-place and leaves chats readable/searchable, that deduplicate defaults to dry_run=true but permanently deletes when false, and that capabilities is read-only. The explicit "ask the user before" guidance adds a safety signal the destructiveHint annotation cannot express. Minor gap: no mention of cost, scale, or failure behavior for large archives.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a one-line purpose and scope, then organized per op_type with quoted labels, which makes it scannable. It is dense as a single paragraph and returns shapes could be trimmed since an output schema exists, but essentially no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter, multi-mode mutation tool, the description covers every mode, its defaults, its destructive potential, and its scoping against siblings. Since an output schema exists, it does not need to restate return values, and nothing an agent needs to invoke it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: which parameters apply to which op_type (days_old to compress, dry_run to deduplicate, settings to configure) and that days_old falls back to a configured threshold. It stops short of adding detail not already in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource framing ("Housekeeping for the archive") and enumerates the four concrete operations (compress, deduplicate, configure, capabilities). It also explicitly scopes itself against siblings with "not for reading or searching chats," so an agent can separate it from search_history and get_chat_logs without reading either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the when (storage and configuration tasks) and the when-not (reading or searching chats), and adds a prerequisite-style instruction: "Destructive only for deduplicate with dry_run=false; ask the user before doing that." The per-op sentences further disambiguate which op_type to pick for which intent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_session_stateManage Session StateADestructive
Save, auto-save, merge, export or delete archived conversations, and watch the archive for changes. Use it to persist the current conversation; to import outside history use sync_workspace_data. action 'register_auto_save': remember conversation_name and messages so they are written when the client disconnects (call it early and re-call it to refresh). 'trigger_auto_save': write the registered session now. 'save': write messages to <conversation_name>.json, overwriting a chat with that name; below the auto_save_message_threshold (default 20) it is skipped unless force_save=true. 'merge': append new_messages to file_name, skipping duplicates. 'export_markdown': write exports/.md. 'delete': permanently delete file_name; refused unless confirm=true, so ask the user first. 'watch_folder': report {new_files, modified_files, total_tracked} since the last call (only updates the watch checkpoint). Returns a confirmation string, or the report object for 'watch_folder'.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Operation to perform (see the tool description). | |
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| confirm | No | Must be true for 'delete' to proceed; deletion is permanent. | |
| messages | No | Chat messages as objects with 'role' ('user', 'assistant' or 'system') and 'content' (text). 'text' is accepted in place of 'content'; extra keys such as 'timestamp' are kept. | |
| file_name | No | Existing chat file for 'merge', 'export_markdown' and 'delete', such as 'my-chat.json'. | |
| force_save | No | For 'save': write even when the message count is below the auto-save threshold. | |
| new_messages | No | Messages to append for 'merge' (same shape as 'messages'); falls back to 'messages'. | |
| conversation_name | No | Conversation title for 'save' and 'register_auto_save' (also the file name); used as file_name for other actions when file_name is omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and non-idempotent, and the description adds concrete consequences beyond them: delete is permanent and refused without confirm=true, save overwrites an existing chat of that name, saves below the default-20 threshold are silently skipped unless force_save, merge deduplicates, and watch_folder only advances the checkpoint. It also discloses the return shape for each path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the overall scope and the sibling routing in the first two sentences, then switches to a compact per-action list with the action name as the anchor. Dense but zero filler; every clause carries a distinct behavioral fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, seven-action mutation tool this covers what an agent needs: per-action effects, the destructive guardrail, threshold behavior, and return values (a confirmation string or the watch_folder report object). The output schema exists but the description still names the return shape, which is more than required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by binding parameters to actions — force_save only matters for 'save', confirm only for 'delete', new_messages for 'merge', and conversation_name doubling as file_name when that is omitted. It does not cover the 'client' namespace parameter, which is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific set of verbs and the resource they act on ('Save, auto-save, merge, export or delete archived conversations... watch the archive for changes'), then enumerates all seven actions with what each writes. It explicitly carves out the boundary against the sibling sync_workspace_data for outside history, so an agent can choose between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-action when-to-use guidance ('call it early and re-call it to refresh', 'trigger_auto_save: write the registered session now') and names the alternative tool plus the condition that selects it ('to import outside history use sync_workspace_data'). It also states a procedural precondition for the destructive path: ask the user before delete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_handoff_receiptSave Handoff ReceiptA
Record what this agent run did and what the next agent must do, as a handoff receipt for the current workspace. Use it before stopping or handing work to another agent or model; read the current state with get_handoff_status. A receipt with status 'open' (the default) marks the workspace as blocked until a later receipt supersedes it with status 'closed' and a closure (closed_by, closed_at, closure_basis). It becomes stale automatically when any file listed in invalidation.stale_if changes after it was saved. Receipts are stored as new JSON files in the archive (never overwritten), indexed, and ranked first in search_history. Returns the saved file name and its receipt_id (pass that as 'supersedes' later).
| Name | Required | Description | Default |
|---|---|---|---|
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| status | No | 'open' (work outstanding, blocks the workspace) or 'closed' (finished; needs 'closure'). | open |
| closure | No | Required to close: {'closed_by': str, 'closed_at': ISO-8601 str, 'closure_basis': str, 'closure_evidence': str}. | |
| evidence | Yes | Proof: {'checks_run': [{'command': str, 'exit_code': int, 'stdout_summary': str}], 'missing_evidence': [str] (checks skipped or not yet run)}. | |
| receipt_id | No | Explicit receipt id. Defaults to '<workspace-hash>_<unix-time>'. | |
| supersedes | No | receipt_id of the earlier receipt this one replaces, forming a chain. | |
| work_state | Yes | What was done: {'touched_surfaces': [{'file_path': str, 'summary': str, 'why': str}], 'dependencies': [str]}. | |
| obligations | Yes | What was promised: {'promise': str (the goal), 'scope': [str] (areas or files in scope)}. | |
| invalidation | Yes | When to distrust this receipt and what to do next: {'stale_if': [{'file_path': str} or {'glob_pattern': str}], 'next_safe_action': str (a direct instruction for the next agent)}. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnlyHint=false, destructiveHint=false, idempotentHint=false) but say nothing about lifecycle semantics, and the description fills that gap in detail: an 'open' receipt blocks the workspace until a 'closed' receipt with a closure supersedes it, staleness is automatic via invalidation.stale_if, and receipts are written as new JSON files that are never overwritten. That last point independently corroborates the non-idempotent, non-destructive annotation profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, then usage, then lifecycle behavior, then return values -- a sensible ordering with no filler sentences. The second paragraph is dense with chained conditions and runs long, though every clause conveys a distinct behavioral fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, four-required, nested-object mutation with a large blast radius, the description supplies the state machine (open/closed/supersedes/stale) an agent must understand to call it correctly. It also covers the chaining contract, which is the one thing the schema and output schema cannot convey on their own.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the per-field documentation is already carried by the schema and baseline 3 applies. The description still adds cross-parameter semantics the schema cannot express: the default 'open' status is tied to the workspace-blocking behavior and the closure requirement, and the returned receipt_id is explicitly named as the value to pass into 'supersedes' later.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: record what this run did and what the next agent must do, as a handoff receipt scoped to the current workspace. That is clearly distinguishable from the read-side sibling get_handoff_status, which it names explicitly in the next sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger ('before stopping or handing work to another agent or model') and routes the agent to get_handoff_status when the intent is inspection rather than recording. It does not state any case where the tool should not be used (e.g. trivial runs with nothing to hand off), so it stops short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_historySearch Chat HistoryARead-onlyIdempotent
Search the local chat archive and return matching transcript chunks. Use this first to recall past work on a topic; then read a hit with get_chat_logs. For extracted action items, comparisons or briefs use compile_project_insights instead. Methods: 'semantic' (default) ranks chunks with Okapi BM25 plus recency decay and returns [{file, score}]; 'keyword' returns chunk ids containing every keyword; 'date_range' returns [{file_name, last_modified}] for chats saved between start_date and end_date; 'related' returns [{file, score}] for chats similar to file_name. Chunk ids look like 'name__part_2.json' and can be passed to get_chat_logs as chat_id. Active handoff receipts are ranked first. Read-only for chat data; it refreshes the local search index cache. An empty archive returns a single placeholder entry such as 'No stored chats found.'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results for 'keyword' and 'date_range' searches. | |
| query | No | Free-text query for 'semantic' search; for 'keyword' it is split on spaces when 'keywords' is omitted. | |
| top_k | No | Maximum results for 'semantic' and 'related' searches. | |
| client | No | Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'. | default |
| method | No | Search strategy (see the tool description). | semantic |
| end_date | No | Inclusive end date (YYYY-MM-DD, UTC) for method='date_range'. Required with start_date. | |
| keywords | No | Exact terms for method='keyword'; all must appear. Overrides 'query' for that method. | |
| file_name | No | Reference chat file for method='related' (for example 'my-chat.json'). Falls back to 'query'. | |
| start_date | No | Inclusive start date (YYYY-MM-DD, UTC) for method='date_range'. Required with end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), and the description adds non-obvious traits beyond them: active handoff receipts are ranked first, the search index cache is refreshed as a side effect, and an empty archive returns a placeholder entry rather than nothing. These are real behaviors an agent could not predict from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and sibling routing before the method catalogue, and each sentence carries information. It is dense and long — the method list plus return shapes plus cache note plus empty-archive case is a lot for one description — but little is genuinely wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter multi-method search tool, the description supplies method selection, return shape per method, id handoff to get_chat_logs, ranking behavior, and the empty-result edge case. An output schema exists, but the extra return detail supports correct method choice rather than duplicating it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns a point by explaining cross-parameter behavior the schema does not — that chunk ids like 'name__part_2.json' can be passed to get_chat_logs as chat_id, and by mapping each method to its distinct return shape. It does not discuss limit vs top_k, leaving that to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('search the local chat archive and return matching transcript chunks') and immediately distinguishes itself from get_chat_logs (read a hit) and compile_project_insights (derived outputs). The four search methods further pin down the resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use this first to recall past work on a topic; then read a hit with get_chat_logs' gives an explicit ordering, and 'For extracted action items, comparisons or briefs use compile_project_insights instead' names the alternative and the condition selecting it. Method-level guidance is also spelled out per case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_workspace_dataImport ChatsA
Import conversations into the archive from pasted content, a local file, or an editor's transcript folder, normalizing ChatGPT, Claude, Cline/Continue JSON, JSONL and Markdown formats. Use it to bring outside history in; to save the current conversation use manage_session_state(action='save'). source_type 'raw_content': payload is the chat JSON (string or object); 'local_path': payload is a file path inside the archive, the current directory, the temp directory or a configured transcripts folder (other paths are refused); 'agent_transcripts': scans the transcripts folder for 'client' ('cursor', 'continue', 'cline', 'copilot', or source_dir) and imports up to 'limit' newest files, skipping ones already imported; 'cursor_agent_transcripts' is a deprecated alias for Cursor. Writes new JSON files into the archive and updates the search index; never deletes. Imports with an existing title overwrite that chat. Returns a confirmation string for single imports, or {imported: [{file, status, dest}], errors, total_scanned} for folder syncs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum newest transcript files to scan for folder syncs. | |
| title | No | Archive name for 'raw_content' or 'local_path' imports. Defaults to a timestamped or source-derived name. | |
| client | No | Archive namespace to import into; for 'agent_transcripts' it also picks the source editor ('cursor', 'continue', 'cline', 'copilot'). Omit for 'default'. | default |
| payload | No | Chat JSON for 'raw_content', a file path for 'local_path', or a folder path for 'agent_transcripts' (same as source_dir). | |
| source_dir | No | Override folder to scan for 'agent_transcripts'; must be inside an allowed root. | |
| source_type | Yes | Where to import from (see the tool description). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=false, but the description says imports with an existing title overwrite that chat; overwriting existing content is a destructive update and conflicts with that annotation. The description otherwise discloses writes, index updates, path refusals, and skip behavior, but the contradiction dominates this dimension.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and the key alternative, then moves through source modes, behavior, and return values. It is dense but organized, and every section appears to earn its place for a six-parameter import tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, six parameters, and existing output schema, the description covers the important source-mode distinctions, overwrite caveat, indexing behavior, path constraints, skip/limit behavior, and return shapes. An agent has enough context to invoke it correctly apart from the annotation conflict.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful conditional semantics for source_type, payload, client, source_dir, and limit. Some details such as title and limit defaults remain in the schema, so it is not fully exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: imports external conversation history into the archive from raw content, local paths, or editor transcript folders, with format normalization. It also explicitly distinguishes this from saving the current conversation via manage_session_state(action='save').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use guidance: bring outside history in, not save the current conversation. It further details each source_type, allowed path locations, folder scan behavior, and a deprecated alias, leaving little ambiguity about tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v1.6.2- Changed
compile_project_insights10 fields changed- added
Input schema / properties / brief_title / descriptionAdded value: +"Heading and export file name for 'project_brief' (an existing brief with this title is overwritten)." - added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - added
Input schema / properties / file_name / descriptionAdded value: +"Single chat file for 'action_items' (or a one-chat 'project_brief'), such as 'my-chat.json'." - added
Input schema / properties / file_name_a / descriptionAdded value: +"First chat file for 'compare_chats'." - added
Input schema / properties / file_name_b / descriptionAdded value: +"Second chat file for 'compare_chats'." - added
Input schema / properties / insight_type / descriptionAdded value: +"Which insight to produce (see the tool description)." - added
Input schema / properties / insight_type / enumAdded value: +[ + "action_items", + "knowledge_index", + "compare_chats", + "project_brief" +] - added
Input schema / properties / rebuild / descriptionAdded value: +"For 'knowledge_index': rescan all chats instead of returning the cached index." - added
Input schema / properties / summary_only / descriptionAdded value: +"For 'knowledge_index': return file counts per topic instead of full file lists." - added
Input schema / properties / target_chats / descriptionAdded value: +"Chat file names: all of them for 'project_brief', the first two for 'compare_chats', the first for 'action_items'."
- Changed
get_chat_logs15 fields changed- added
Input schema / properties / chat_id / descriptionAdded value: +"Chat file or chunk id to read, such as 'my-chat.json' or 'my-chat__part_2.json'. Omit to list chats." - added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - added
Input schema / properties / end_msg / descriptionAdded value: +"Last message to return (inclusive) for view_type='content'." - added
Input schema / properties / end_msg / minimumAdded value: +1 - added
Input schema / properties / max_msg_len / descriptionAdded value: +"Per-message character cap for view_type='content'; 0 means no cap (can be very large)." - added
Input schema / properties / max_msg_len / minimumAdded value: +0 - added
Input schema / properties / page / descriptionAdded value: +"Page number (1-based) when listing chats without chat_id." - added
Input schema / properties / page / minimumAdded value: +1 - added
Input schema / properties / per_page / descriptionAdded value: +"Chats per page when listing without chat_id." - added
Input schema / properties / per_page / minimumAdded value: +1 - added
Input schema / properties / start_msg / descriptionAdded value: +"First message to return (1-based) for view_type='content'." - added
Input schema / properties / start_msg / minimumAdded value: +1 - added
Input schema / properties / summarize_code / descriptionAdded value: +"Replace fenced code blocks with a one-line language and line-count summary to save tokens." - added
Input schema / properties / view_type / descriptionAdded value: +"What to return for chat_id: message text ('content'), file statistics ('metadata') or a short 'summary'." - added
Input schema / properties / view_type / enumAdded value: +[ + "content", + "metadata", + "summary" +]
- Changed
get_handoff_status2 fields changed- added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "active_chain": { + "default": null, + "items": { + "type": "string" + }, + "title": "Active Chain", + "type": "array" + }, + "blocked": { + "default": null, + "title": "Blocked", + "type": "boolean" + }, + "blocked_by_receipt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Blocked By Receipt" + }, + "newest_receipt_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Newest Receipt Id" + }, + "next_safe_action": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Safe Action" + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reason" + } + }, + "title": "HandoffStatus", + "type": "object" +}
- Changed
maintain_storage7 fields changed- added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - changed
Input schema / properties / days_old / anyOfPrevious value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -]New value: +[ + { + "minimum": 1, + "type": "integer" + }, + { + "type": "null" + } +] - added
Input schema / properties / days_old / descriptionAdded value: +"For 'compress': minimum age in days; omit to use compression_days_threshold (30 by default)." - added
Input schema / properties / dry_run / descriptionAdded value: +"For 'deduplicate': true lists duplicates only; false deletes them permanently." - added
Input schema / properties / op_type / descriptionAdded value: +"Maintenance operation (see the tool description)." - added
Input schema / properties / op_type / enumAdded value: +[ + "compress", + "deduplicate", + "configure", + "capabilities" +] - added
Input schema / properties / settings / descriptionAdded value: +"For 'configure' only. Allowed keys: auto_save_message_threshold (int, messages before manage_session_state save persists), compression_days_threshold (int), summary_pruning_days_threshold (int), client_paths (object: client name to a relative folder), transcripts_dirs (object: client name to a folder), cursor_transcripts_dir (string). Unknown keys are ignored."
- Changed
manage_session_state9 fields changed- added
Input schema / properties / action / descriptionAdded value: +"Operation to perform (see the tool description)." - added
Input schema / properties / action / enumAdded value: +[ + "save", + "register_auto_save", + "trigger_auto_save", + "watch_folder", + "merge", + "export_markdown", + "delete" +] - added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - added
Input schema / properties / confirm / descriptionAdded value: +"Must be true for 'delete' to proceed; deletion is permanent." - added
Input schema / properties / conversation_name / descriptionAdded value: +"Conversation title for 'save' and 'register_auto_save' (also the file name); used as file_name for other actions when file_name is omitted." - added
Input schema / properties / file_name / descriptionAdded value: +"Existing chat file for 'merge', 'export_markdown' and 'delete', such as 'my-chat.json'." - added
Input schema / properties / force_save / descriptionAdded value: +"For 'save': write even when the message count is below the auto-save threshold." - added
Input schema / properties / messages / descriptionAdded value: +"Chat messages as objects with 'role' ('user', 'assistant' or 'system') and 'content' (text). 'text' is accepted in place of 'content'; extra keys such as 'timestamp' are kept." - added
Input schema / properties / new_messages / descriptionAdded value: +"Messages to append for 'merge' (same shape as 'messages'); falls back to 'messages'."
- Changed
save_handoff_receipt9 fields changed- added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - added
Input schema / properties / closure / descriptionAdded value: +"Required to close: {'closed_by': str, 'closed_at': ISO-8601 str, 'closure_basis': str, 'closure_evidence': str}." - added
Input schema / properties / evidence / descriptionAdded value: +"Proof: {'checks_run': [{'command': str, 'exit_code': int, 'stdout_summary': str}], 'missing_evidence': [str] (checks skipped or not yet run)}." - added
Input schema / properties / invalidation / descriptionAdded value: +"When to distrust this receipt and what to do next: {'stale_if': [{'file_path': str} or {'glob_pattern': str}], 'next_safe_action': str (a direct instruction for the next agent)}." - added
Input schema / properties / obligations / descriptionAdded value: +"What was promised: {'promise': str (the goal), 'scope': [str] (areas or files in scope)}." - added
Input schema / properties / receipt_id / descriptionAdded value: +"Explicit receipt id. Defaults to '<workspace-hash>_<unix-time>'." - added
Input schema / properties / status / descriptionAdded value: +"'open' (work outstanding, blocks the workspace) or 'closed' (finished; needs 'closure')." - added
Input schema / properties / supersedes / descriptionAdded value: +"receipt_id of the earlier receipt this one replaces, forming a chain." - added
Input schema / properties / work_state / descriptionAdded value: +"What was done: {'touched_surfaces': [{'file_path': str, 'summary': str, 'why': str}], 'dependencies': [str]}."
- Changed
search_history12 fields changed- added
Input schema / properties / client / descriptionAdded value: +"Archive namespace (a subfolder of the chats directory). Built-in: 'default', 'cursor', 'chatgpt', 'claude'; any other name creates its own subfolder. Omit to use 'default'." - added
Input schema / properties / end_date / descriptionAdded value: +"Inclusive end date (YYYY-MM-DD, UTC) for method='date_range'. Required with start_date." - added
Input schema / properties / file_name / descriptionAdded value: +"Reference chat file for method='related' (for example 'my-chat.json'). Falls back to 'query'." - added
Input schema / properties / keywords / descriptionAdded value: +"Exact terms for method='keyword'; all must appear. Overrides 'query' for that method." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum results for 'keyword' and 'date_range' searches." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / method / descriptionAdded value: +"Search strategy (see the tool description)." - added
Input schema / properties / method / enumAdded value: +[ + "semantic", + "keyword", + "date_range", + "related" +] - added
Input schema / properties / query / descriptionAdded value: +"Free-text query for 'semantic' search; for 'keyword' it is split on spaces when 'keywords' is omitted." - added
Input schema / properties / start_date / descriptionAdded value: +"Inclusive start date (YYYY-MM-DD, UTC) for method='date_range'. Required with end_date." - added
Input schema / properties / top_k / descriptionAdded value: +"Maximum results for 'semantic' and 'related' searches." - added
Input schema / properties / top_k / minimumAdded value: +1
- Changed
sync_workspace_data8 fields changed- added
Input schema / properties / client / descriptionAdded value: +"Archive namespace to import into; for 'agent_transcripts' it also picks the source editor ('cursor', 'continue', 'cline', 'copilot'). Omit for 'default'." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum newest transcript files to scan for folder syncs." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / payload / descriptionAdded value: +"Chat JSON for 'raw_content', a file path for 'local_path', or a folder path for 'agent_transcripts' (same as source_dir)." - added
Input schema / properties / source_dir / descriptionAdded value: +"Override folder to scan for 'agent_transcripts'; must be inside an allowed root." - added
Input schema / properties / source_type / descriptionAdded value: +"Where to import from (see the tool description)." - added
Input schema / properties / source_type / enumAdded value: +[ + "agent_transcripts", + "cursor_agent_transcripts", + "local_path", + "raw_content" +] - added
Input schema / properties / title / descriptionAdded value: +"Archive name for 'raw_content' or 'local_path' imports. Defaults to a timestamped or source-derived name."
8 tool updates
v1.5.4- First observed
compile_project_insights - First observed
get_chat_logs - First observed
get_handoff_status - First observed
maintain_storage - First observed
manage_session_state - First observed
save_handoff_receipt - First observed
search_history - First observed
sync_workspace_data
TDQS
Scored across 8 tools
Each tool has a distinct role, and the descriptions actively cross-reference each other (search_history vs get_chat_logs, sync_workspace_data vs manage_session_state). Minor overlap remains between manage_session_state's export/save actions and compile_project_insights' project_brief export, and between sync_workspace_data's import and manage_session_state's save, but the descriptions steer agents correctly.
All eight tools use consistent snake_case verb_noun naming (search_history, get_chat_logs, save_handoff_receipt, get_handoff_status, etc.). The two handoff tools form a clean save/get pair, and no camelCase or vague verbs appear.
Eight tools is well-scoped for an archive memory server: search, read, import, digest, housekeeping, session persistence, and a two-tool handoff lifecycle. Each tool covers a meaningful capability with no filler.
Chat lifecycle is well covered: create/import (sync_workspace_data), read (get_chat_logs), update (merge), delete, export, plus compression, dedupe, settings, and handoff open/close with staleness. Minor gaps: no direct tool to read a handoff receipt's full body (must go through search/get_chat_logs) and no way to update chat metadata or titles.
Maintenance
Related MCP Connectors
Private persistent memory for Claude, ChatGPT & Gemini via MCP - semantic search, zero-code setup.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
One memory, every AI: Claude, ChatGPT, Perplexity, Gemini, Cursor, OpenClaw, Hermes, any MCP client.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server and background daemon that captures Discord and Telegram conversations locally to provide persistent memory for Claude Code sessions. It enables hybrid search and automatic context injection of chat history to maintain continuity across development sessions.1 npm22MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server that indexes and searches your Claude Code conversation history with both keyword and semantic search, fully private and running locally.MIT
- AlicenseAqualityBmaintenanceA local-first, privacy-first MCP server that passively indexes personal digital activity (screenshots, clipboard, notes, downloads, links) into a local database, enabling LLMs like Claude to access your context without cloud storage.41MIT
- AlicenseNot gradedqualityDmaintenanceCapture, index, and search your Claude Code conversation history. Provides an MCP server for Claude Code to query its own past conversations.1 npm1MIT