Skip to content

phate45/context-wrapper

Repository files navigation

context-wrapper

Pre-warm wrapper for the context-mode MCP server. Indexes configured markdown files into the FTS5 search database before the server starts, so search() returns results immediately — no manual indexing step required.

Requirements

  • Node.js (v22+) — runtime (context-mode depends on better-sqlite3, a native addon not yet supported by bun's runtime)
  • A package manager: bun (preferred), pnpm, or npm

Setup

cd context-wrapper/
node setup.js    # or: bun run setup.js

This installs dependencies and prints the claude mcp add command to wire up the wrapper. Run that command to register it with Claude Code.

If you already have a context-mode entry in your .mcp.json, replace it — this wrapper supersedes the direct bundle invocation.

Project Configuration

Create .claude/context-mode.json in any project that should have pre-warmed content:

Each source needs a label and a file selection strategy. Three strategies are available:

Strategy 1: Glob (flat or recursive)

Match files by pattern in a directory.

{
  "label": "work-logs",
  "path": "/absolute/path/to/logs",
  "glob": "*.md",
  "stripFrontmatter": true,
  "prefixDates": true
}

Add "recursive": true to scan subdirectories:

{
  "label": "docs",
  "path": "/absolute/path/to/docs",
  "glob": "*.md",
  "recursive": true,
  "stripFrontmatter": true
}

Strategy 2: Exec

Run a command that outputs a JSON array of file paths. Relative paths resolve from path (or CWD if omitted).

{
  "label": "curated",
  "path": "/project/root",
  "exec": "./list-indexable-files.sh",
  "stripFrontmatter": true
}

The command must print valid JSON to stdout, e.g.:

["docs/guide.md", "docs/api/reference.md", "CHANGELOG.md"]

Timeout: 10 seconds.

Strategy 3: Explicit Paths

Hardcode a list of file paths. Relative paths resolve from path (or CWD if omitted).

{
  "label": "key-docs",
  "paths": [
    "/absolute/path/to/architecture.md",
    "/absolute/path/to/decisions.md"
  ],
  "stripFrontmatter": true
}

Source Fields Reference

Field Description
label (required) Source tag for scoped search (source: "work-logs")
path Base directory. Required for glob, optional for exec/paths (used as CWD / base for relative paths)
glob File pattern to match (e.g. *.md). Requires path.
recursive Walk subdirectories when using glob. Default: false
exec Shell command that outputs a JSON array of file paths
paths Explicit array of file paths
stripFrontmatter Remove YAML --- frontmatter blocks from start of files. Default: false
prefixDates For date-named files (2026-02-28.md): prefix ## headings with [YYYY-MM-DD]. Default: false

Searching Pre-Warmed Content

Pre-warmed content is searchable through the standard context-mode tools:

search(queries: ["tmux configuration"])
search(queries: ["authentication"], source: "work-logs")
search(queries: ["FTS5 schema"], source: "research-notes")

The source parameter matches against labels. A source labeled "work-logs" creates entries like "work-logs: 2026-02-28.md", so source: "work-logs" matches all files in that source.

Runtime Folder Indexing

In addition to pre-warm (which runs at startup), the wrapper exposes an index_folder tool for on-demand indexing of entire directories. Each file becomes a separate searchable source with dedup-by-label — re-indexing the same folder replaces previous content.

index_folder(path: "/path/to/docs")
index_folder(path: "/path/to/docs", glob: "*.txt", source: "my-docs")
Parameter Required Default Description
path Directory to index
glob *.md Filename pattern to match
recursive true Walk subdirectories
source dir basename Label prefix — each file gets "{source}: {relative/path}"
stripFrontmatter true Strip YAML frontmatter before indexing

Files are preprocessed (frontmatter stripping, blank line collapsing), then forwarded individually to the upstream indexer. The response reports total files and chunks indexed.

How It Works

The wrapper runs three phases on startup:

  1. Discover — Walks up from CWD looking for .claude/context-mode.json
  2. Pre-warm — Creates a SQLite FTS5 database at /tmp/context-mode-{PID}.db, populates it with preprocessed and chunked content from the configured sources
  3. Launch — Dynamic-imports the context-mode server bundle, which finds the pre-warmed database and serves it

If no config file is found, the wrapper skips pre-warming and starts the server normally — identical behavior to running context-mode directly.

Preprocessing Details

Frontmatter Stripping

Removes YAML frontmatter at the start of a file (between opening --- and closing ---). Does not affect horizontal rules mid-document.

Date Prefixing

For files named YYYY-MM-DD.md (work logs):

  • Bare date headings (## 2026-02-28) are removed
  • Topic headings become ## [2026-02-28] Database Migration
  • This makes search results self-documenting — you can see when something happened without checking the source filename

Search Reminder Control

The upstream context-mode server progressively throttles search() calls and appends warning messages after the third call in a 60-second window. If these warnings create unwanted cognitive overhead, you can control them:

{
  "sources": [ ... ],
  "searchReminder": false
}
Value Effect
(absent) Warnings pass through unchanged (default)
false Strip all throttle warnings and block messages
"custom text" Replace warnings with your own text

Note: This only controls the message — the upstream throttling behavior (reduced results per query after 3 calls, hard block after 8) still applies.

Subagent Hook (Optional)

The wrapper includes subagent-hook.mjs — a PreToolUse hook that teaches subagents to use context-mode tools instead of flooding the parent's context with raw output.

What it does:

  • Injects routing instructions into every subagent prompt, directing them to use batch_execute, search, execute_file, etc.
  • Tells subagents to keep responses under 500 words and index detailed findings into the shared knowledge base (the parent can search() for them afterward)
  • Upgrades Bash subagents to general-purpose so they gain MCP tool access

To enable it, add a hook entry to .claude/settings.json or .claude/settings.local.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Agent",
        "hooks": [
          {
            "type": "command",
            "command": "node /absolute/path/to/context-wrapper/subagent-hook.mjs"
          }
        ]
      }
    ]
  }
}

Replace the path with the absolute path to your context-wrapper/ directory.

Note: This hook nudges subagents toward context-mode tools but does not block standard tools. Subagents can still use Bash, Read, etc. when appropriate.

Custom Subagent Profiles

By default, all subagents get a 500-word response cap and dead-drop instructions, except Plan agents (full output) and a few skip types. You can override this per agent type in your .claude/context-mode.json:

{
  "sources": [ ... ],
  "subagentProfiles": {
    "review": { "ending": "plan" },
    "my-fetcher": { "skip": true },
    "custom-role": { "block": "<custom>Full replacement injection text</custom>" }
  }
}

Each profile key matches against subagent_type. Three modes (mutually exclusive):

Field Effect
skip: true No routing injected — agent runs unmodified
ending: "plan" or "concise" Uses the standard tool routing block with the named output constraints
block: "..." Full custom text, replaces the entire routing injection

Custom profiles take priority over all hardcoded defaults. You can override the built-in Plan, Bash, or skip-type behavior by defining a profile with that name.

Portability

Copy this folder to another machine, run node setup.js, add the MCP server. The wrapper brings its own context-mode and better-sqlite3 as dependencies — only Node.js and a package manager (bun, pnpm, or npm) are required.

About

My wrapper over mksglu/context-mode

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors