MCP Server Overview
fcheap includes a built-in MCP (Model Context Protocol) server that exposes stash operations to AI assistants like Claude across all three MCP surfaces: tools (actions), resources (readable stash data by URI), and prompts (one-shot agent workflows).
How It Works
The MCP server runs over stdio transport. When an AI assistant needs to save, restore, analyze, or diff files, it calls fcheap's MCP tools. The server creates a stash manager, performs the operation, and returns results as JSON. Agents can also read stash metadata as resources (without spending a tool call) and launch multi-step investigations from prompts.
Setup
fcheap is a standard stdio MCP server, so it works in any MCP-compatible client. The invocation is always the same — command fcheap, args mcp serve — only the config format differs. Below are the common clients.
Claude Code
One-liner (user scope, available in every project):
claude mcp add -s user fcheap -- fcheap mcp serveOr add it to your MCP config by hand:
{
"mcpServers": {
"fcheap": {
"command": "fcheap",
"args": ["mcp", "serve"]
}
}
}Codex CLI
In ~/.codex/config.toml:
[mcp_servers.fcheap]
command = "fcheap"
args = ["mcp", "serve"]OpenCode
In ~/.config/opencode/opencode.json, under mcp:
{
"mcp": {
"fcheap": {
"type": "local",
"command": ["fcheap", "mcp", "serve"],
"enabled": true
}
}
}Any other stdio MCP client
Register a server named fcheap that runs fcheap mcp serve over stdio. Clients that read a .mcp.json (mcpServers map) use the same shape as the Claude Code JSON above. On first connect the server advertises all three surfaces — 14 tools, the fcheap://stashes resource plus the fcheap://stash/{id} resource template, and 2 prompts.
Tools
fcheap_save
Save a file or directory to the stash vault.
Input:
path(string, required) -- absolute path to savename(string, optional) -- display nametags(string[], optional) -- categorization tagstool(string, optional) -- source tool (e.g., "vidtrace")source(string, optional) -- original artifact this stash derives from (provenance)ttl(string, optional) -- retention duration or date; empty means no expiryindex(bool, optional) -- index immediately after saving
Output: { manifest, secrets_warning?, secrets? } -- the stash manifest, plus a secrets warning and findings (file/rule/line) when the save-time scan flags likely credentials. With index: true, the result also contains indexed or index_error; an indexing policy block never rolls back a successful save.
The path must be outside the stash vault and must not contain it. Canonical-path checks also reject symlink-based overlap. Stash IDs are opaque single path elements; all ID-taking tools reject separators and traversal values.
fcheap_list
List stashes, optionally filtered by tag, tool, and age. Newest first.
Input:
tag(string, optional) -- filter by tag (single; merged withtags)tags(string[], optional) -- filter by tags, AND across entries (a stash must contain every tag). Repeatable on the CLI:--tag a --tag b.tool(string, optional) -- filter by tool (e.g. vidtrace)since(string, optional) -- only stashes newer than24h,7d,2w, or2026-06-01limit(int, optional) -- maximum number of stashes
Output: Array of stash summaries (id, name, tool, tags, sizes, created, bundle type, plus compression / secrets_found / video / custom where present). custom carries the full manifest.Custom map (e.g. source base-sha, branch, embedding_profile), so a caller can rebuild a pointer file from list alone.
fcheap_info
Get detailed information about a stash.
Input:
stash_id(string, required) -- the stash ID
Output: Full manifest with file tree
fcheap_restore
Restore a stash to a target directory.
Input:
stash_id(string, required) -- the stash IDtarget(string, optional) -- target directory (default: a fresh, unique temp directory, reported in the result)allow_mismatch(bool, optional) -- accept an unverified restore (defaultfalse)
Output: { stash_id, target, file_count, verified, mismatches, status }, where status is restored, restored_unverified, or restored_with_mismatches. When verified is false, the tool result has isError: true unless allow_mismatch is true. The structured result remains available either way. Restore targets that are inside the stash vault or contain it, including through symlinks, are rejected. An existing target is modified in place: same-named files are replaced and unrelated files remain. Omit target for a fresh temp directory when replacement is not intended.
fcheap_drop
Permanently delete a stash.
Input:
stash_id(string, required) -- the stash IDforce(bool, required) -- must be true to confirm
Output: { stash_id, status, failed }. status is dropped or dropped_with_failures; a derived search-index cleanup failure remains in failed and marks the tool result as an error even though stash deletion succeeded.
fcheap_search
Search across all indexed stashes.
Input:
query(string, required) -- search querylimit(int, optional) -- maximum number of results (default 20)mode(string, optional) --keyword,semantic, orhybrid(default:hybridif an embedder is configured, elsekeyword)
Output: Search results with scores and snippets, each naming the matching file
Semantic/hybrid mode sends query text to the configured HTTP embedder. OpenAI is remote; Ollama defaults to localhost but may use a custom remote URL. Query text is not covered by the save-time secret guard. In a mixed vault, semantic mode also merges BM25 results from stashes that have no vectors.
fcheap_analyze
Index a stash for search and optionally search within it.
Input:
stash_id(string, required) -- the stash IDquery(string, optional) -- search within the stash
Output: Index status, bundle type, and optional search results
With OpenAI or a non-loopback Ollama endpoint, indexing a stash flagged by the save-time secret scanner is blocked unless allow_remote_secrets: true is explicitly configured. Loopback Ollama remains local and exempt. An optional query is sent to the configured embedder and is not scanned by that guard. See config.
fcheap_diff
Compare a stash against a target directory.
Input:
stash_id(string, required) -- the stash IDtarget_dir(string, required) -- directory to compare against
Output: Diff result with file-level changes
fcheap_connect
Connect a stash to a codebase: run semantic code search (vecgrep) over the codebase using the stashed artifact's text to surface the file:line candidates most likely responsible for the bug. See connect.
Input:
stash_id(string, required) -- the stash whose content drives the searchcodebase_dir(string, required) -- absolute path to the codebasequery(string, optional) -- override the auto-extracted querylimit(int, optional) -- max code matches (default 10)index(bool, optional) -- build the vecgrep index for the codebase firstmode(string, optional) -- vecgrep search mode:semantic,keyword, orhybrid(default hybrid)
Output: Ranked code matches with file:line, score, and snippet
fcheap_vacuum
Remove orphaned metadata- and search-index entries for stashes whose directory no longer exists, then compact the database. See vacuum.
Input: none
Output: { on_disk, orphaned_rows, orphans }
fcheap_ttl
Set or clear a stash expiry.
Input:
stash_id(string, required) -- the stash IDttl(string, required) -- duration/date, or an empty string to clear expiry
Output: { stash_id, expires_at }
fcheap_sweep
Plan or apply deletion of expired stashes.
Input:
apply(bool, optional) -- delete the filtered plan (defaultfalse)keep_tag(string, optional) -- exempt this tag (defaultkeep)include_tag(string, optional) -- include only stashes with this tag
include_tag is applied while building the plan, before mutation. The output separates expired (planned IDs), dropped (successful deletions), and failed (drop/index failures), along with applied, skipped, and reclaimed. A non-empty failed array marks the tool result as an error.
fcheap_cleanup
Analyze cleanup candidates in scoring mode or category-based smart mode.
Input:
apply,keep_tag-- control mutation and protectiontool,tag,drop_only,expired-- scoring-mode filterssmart,categories,stale_days-- smart-mode controls
Both modes are dry-runs unless apply is true. Apply auto-deletes only expired TTLs or codemap/vecgrep caches; missing-source and evidence recommendations remain review-only. Smart output separates the pre-apply analysis from dropped, reclaimed, skipped, and failed. A non-empty failed array marks the tool result as an error. See cleanup.
fcheap_docs
Access the read-only fcheap documentation embedded in every installed server.
Input:
action(string, required) --list,show, orsitepage(string, optional) -- canonical embedded page path foraction=show, e.g.cli/save; absolute and traversal paths are rejected
Output: List of pages, page content, or site URL. The site result notes that local VitePress serving requires a file.cheap source checkout plus Node.js and npm; embedded list and show do not.
Resources
Resources expose stash data as readable URIs, so an agent can pull stash metadata straight into context without spending a tool call. Both return application/json.
fcheap://stashes
The full stash index — the same summaries as fcheap_list (id, name, tool, tags, file count, size, created_at, bundle type, plus compression / secrets_found / video / custom flags where present), newest first.
fcheap://stash/{id}
A resource template: read a single stash's full manifest by ID — provenance, the file list with hashes, tags, compression, detected secrets, and bundle metadata. Reading an unknown ID returns a resource-not-found error.
Prompts
Prompts are reusable, parameterized workflows a user can launch with one command; each expands into a guided message that drives the tools and resources above.
investigate_stash
Plan an end-to-end investigation of a stash. Arguments: stash_id (required), codebase_dir (optional). Walks the agent through reading the manifest, indexing and searching the stash, optionally fcheap_connect-ing it to a codebase to surface file:line candidates, and summarizing findings — the flagship vidtrace-evidence → code workflow.
find_across_stashes
Search every indexed stash for a query and synthesize where the answer lives. Arguments: query (required), mode (optional: keyword/semantic/hybrid).
Architecture
The MCP server is built with the official modelcontextprotocol/go-sdk. Tools use typed input structs with jsonschema tags for automatic schema generation. The DestructiveHint, OpenWorldHint, and IdempotentHint annotations help AI assistants understand the safety properties of each tool. Resources and prompts are registered alongside the tools (see internal/mcp/resources.go), so a single fcheap mcp serve advertises all three capabilities.