feat: on-demand context for Claude Code via MCP server (v0.5.0)#1
Merged
Conversation
Adds an MCP delivery path as an alternative to appending to CLAUDE.md. Anthropic's own guidance is to keep CLAUDE.md small (bloated context files degrade instruction-following), so this lets captures live as individual files that the agent pulls in only when it asks. - mcp-server/: standalone npx-distributable stdio MCP server (SDK 1.29) with list_contexts / search_contexts / get_context / delete_context. Reads a plain directory of Markdown files — no native-messaging host, which is the most common failure mode of similar bridges. 12 tests. - extension: new "mcp-store" output mode writes each capture as a standalone <slug>.md file into a linked directory via the existing File System Access offscreen pipeline; options UI to link/re-grant the directory and setup instructions; stable slug generation. - Reuses the existing high-fidelity claude.ai parser (thinking / tool_use / branches) and frontmatter format unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Includes posting checklist: do not post the npx install line until the MCP server is published to npm, to avoid the broken-install failure mode that sank the closest competitor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntly The #1 silent failure for this feature is "I captured something but Claude Code can't see it", which almost always means the server's resolved directory differs from where the extension writes (typically a relative path resolving against an unexpected cwd). - ContextStore.status() diagnoses missing / not-a-directory / unreadable / ok(+file count); describeStatus() renders a one-line explanation with the resolved absolute path. - Server logs the resolved path and status on startup (stderr), with a hint when it's not ok. - list_contexts returns the same diagnostic to the agent when empty, so Claude Code can relay the actual fix instead of "nothing found". - README troubleshooting section. +3 tests (15 total in mcp-server). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Strengthens the highest-fidelity, Claude-specific capture path.
- Artifacts (code/documents Claude authors via the `artifacts` tool) now
render as clean fenced code blocks with title + language, instead of
collapsing to raw JSON — both inline in full captures and in the new
artifacts-only mode.
- New capture options (UserOptions + forwarded to the in-page parser):
- claudeAiArtifactsOnly: extract just the artifacts, drop the chat.
Deduped by artifact id so an edited artifact is captured at its final
version, not every intermediate edit.
- claudeAiMaxMessages: keep only the last N messages of a long thread.
- Options plumbed end to end: service worker loads + forwards a parser
subset via RuntimeMessage -> content script -> dispatcher -> parser.
- Options UI: "claude.ai conversations" controls.
- Tests: claude-ai parser 9 -> 21 (artifactFromInput, collectArtifacts,
artifacts-only, maxMessages, no-artifacts error).
- vitest: exclude mcp-server from the root run (it has its own).
- README: document the v0.5.0 capture options (EN + JA).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Makes the on-demand context store actually navigable as it grows. - filter.ts: shared filtering by source, tags (case-insensitive substring; AND by default, OR via tagMatch), and a captured-at date range (since/until; bare `until` date = end of day). Invalid date bounds are reported as warnings instead of failing the call. - list_contexts + search_contexts gain parser/tags/tagMatch/since/until. search applies the filter before ranking, so you can scope a keyword search to e.g. claude-ai TS artifacts from this month. - New stats_contexts tool: total count + size, breakdown by source, top tags, and captured-at date range — an at-a-glance store overview. - stats.ts: computeStats + formatBytes. - Tests: +14 (filter AND/OR, substring, date window, end-of-day, no-date exclusion, invalid-bound warning, stats aggregation). 29 total. - README: tool table, filtering docs, worked example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t:code) Completes the "one code = one file" path: a claude.ai capture's code/ document artifacts become individually addressable in the MCP store. Extension (mcp-store mode): - CapturedContext now carries `artifacts`; the claude.ai parser exposes them even for full-conversation captures. - artifact-file.ts: builds one standalone store file per artifact — frontmatter (parser: claude-ai-artifact, artifact_of, language, tags artifact + lang:<x>) + a single fenced code block. Filenames share the parent slug and disambiguate same-title artifacts. - service worker writes the main capture file plus one file per artifact. MCP server: - get_context gains format:"code" — returns raw code with frontmatter and fences stripped, ready to write to a file. extractCode() in store.ts. - Artifact files are first-class: filterable via tags/parser, fetchable as code. Tests: extension +6 (buildArtifactFiles), mcp +2 (extractCode). 80 + 31. README: artifact-as-files docs + worked example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When the active tab is a claude.ai chat, the popup shows an inline panel to toggle "artifacts only" and set "last N messages" without digging into the options page. Changes persist to the same chrome.storage options, so the next capture (button, shortcut, or context menu) picks them up — one source of truth, no divergence from the settings page. - popup detects claude.ai/chat/<uuid> via the active tab URL (same pattern as the parser's canHandleClaudeAi); panel is hidden elsewhere. - patchOption() persists each change immediately via saveOptions. - README: note the popup quick-toggle (EN + JA). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Directly answers the strongest signal in #13843's thread: users want a single source of truth, not export/import silos. Re-capturing the same conversation now UPDATES its store files instead of accumulating duplicate snapshots. - CapturedContext.dedupeKey: stable identity for a capture's subject. The claude.ai parser sets it to the conversation UUID (and uuid:artifacts for artifacts-only mode, so the two modes stay independent). - buildContextSlug: with a dedupeKey, the slug leads with a stable `ccc-<hash>` prefix (title appended only for readability). The prefix is invariant across re-captures even when Claude renames the conversation. - WRITE_MCP_FILESET offscreen op: removes the prior version by stable prefix (main + derived artifact files), then writes the new set atomically per file. Non-deduped captures (web pages) are unaffected. - slugFileNamesToRemove: pure, prefix-based selection of files to replace, with a boundary check so ccc-ab12 doesn't match ccc-ab123. Tests: +dedupe slug stability (incl. title-change), +prefix removal boundary cases. 90 extension tests, 31 mcp. README EN+JA. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…LF, extractCode, artifact order) Self-review of the PR surfaced a critical security bug and several correctness/data-loss issues; all fixed with regression tests. CRITICAL — path traversal (mcp-server): - readBySlug/deleteBySlug accepted slugs like "../../etc/passwd", allowing read and DELETE of files outside the contexts dir. Added isSafeSlugComponent() guard + resolveInside() containment check, and a refusal at the delete_context tool boundary. Verified the exploit is closed end-to-end. HIGH — hash truncation (extension): - shortHash did `.slice(0,6)` on a value that's 6–7 base36 chars, halving and skewing the dedupe space. Since the hash gates which files a re-capture deletes, a collision could delete an unrelated capture. Now returns the full 32-bit value. Artifact filenames use a collision- proof numeric counter instead of a (truncated) hash suffix. HIGH — CRLF frontmatter (mcp-server): - splitFrontmatter dropped all fields for Windows line endings; now normalizes CRLF/CR to LF first. MEDIUM — extractCode (mcp-server): - Only strips fences when the body is exactly one fenced block; otherwise returns the full body, so prose-around-fence or multi-fence content is never silently truncated. MEDIUM — collectArtifacts order (extension): - Preserves authoring order; an updated artifact keeps its original slot instead of all id'd artifacts jumping ahead of anonymous ones. Tests: extension 90 -> 91, mcp 31 -> 39 (traversal, CRLF, extractCode truncation, artifact ordering). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Closes the gap our research surfaced: people want their claude.ai conversations and web research available in Claude Code, but appending everything to
CLAUDE.mdfights Anthropic's own guidance to keep that file small (bloated context files degrade instruction-following).This PR adds an MCP delivery path: captures live as individual Markdown files, and a bundled MCP server hands them to Claude Code only when the agent asks (
list_contexts/search_contexts/get_context/delete_context).Why this beats existing bridges
The closest prior tool (
claude-context-bridge) relies on a native-messaging host, which is exactly where every public install attempt failed. This implementation deliberately uses no native host — the extension writes plain files via the File System Access API (reusing our existing, battle-tested offscreen pipeline), and the server just reads that directory. Install isnpx+ one line.Changes
mcp-server/— standalone, npx-distributable stdio MCP server (SDK 1.29.0). 12 tests; verified end-to-end over a real JSON-RPC handshake.mcp-storeoutput mode writes each capture as<slug>.mdinto a linked directory; options UI to link/re-grant the directory + setup instructions; stable slug generation.Verification
npm run build✓ ·npm test(79) ✓ ·npm run lint✓npm run build✓ ·npm test(12) ✓ · driven over stdio with initialize → tools/list → tools/call ✓🤖 Generated with Claude Code