Skip to content

feat: on-demand context for Claude Code via MCP server (v0.5.0)#1

Merged
OceansCreative merged 9 commits into
mainfrom
feat/mcp-on-demand-context
Jun 1, 2026
Merged

feat: on-demand context for Claude Code via MCP server (v0.5.0)#1
OceansCreative merged 9 commits into
mainfrom
feat/mcp-on-demand-context

Conversation

@OceansCreative
Copy link
Copy Markdown
Owner

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.md fights 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 is npx + 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.
  • Extension — new mcp-store output mode writes each capture as <slug>.md into a linked directory; options UI to link/re-grant the directory + setup instructions; stable slug generation.
  • Reuses the existing high-fidelity claude.ai parser (thinking / tool_use / branches) and frontmatter format unchanged.
  • Version bumped to 0.5.0.

Verification

  • Extension: npm run build ✓ · npm test (79) ✓ · npm run lint
  • MCP server: npm run build ✓ · npm test (12) ✓ · driven over stdio with initialize → tools/list → tools/call ✓

🤖 Generated with Claude Code

OcenasCreative and others added 9 commits June 1, 2026 21:08
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>
@OceansCreative OceansCreative merged commit adc6aa9 into main Jun 1, 2026
1 check passed
@OceansCreative OceansCreative deleted the feat/mcp-on-demand-context branch June 1, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants