Skip to content

feat(mcp): MCP v2 — deep_dive tool, fit fix, schema honesty, GITHUB_TOKEN + timeout#35

Merged
New1Direction merged 4 commits into
mainfrom
feat/mcp-v2-core
Jun 17, 2026
Merged

feat(mcp): MCP v2 — deep_dive tool, fit fix, schema honesty, GITHUB_TOKEN + timeout#35
New1Direction merged 4 commits into
mainfrom
feat/mcp-v2-core

Conversation

@New1Direction

Copy link
Copy Markdown
Owner

Summary

Turns the MCP proof (#33) into something real: a third tool, two correctness fixes the survey caught, and the rate-limit + timeout hardening it needed. All extension modules are reused verbatim; only mcp/ changes plus a backward-compatible optional param on two shared fetch helpers.

What's in it

New tool — deep_dive({ repo }) — plain-English explanation of how a repo works, with gaps, assumptions, self-test questions, and per-claim confidence, plus the underlying atoms + lineage. Reuses deepdive.js verbatim (atoms → lineage → Feynman, three model calls — the heaviest tool).

Bug fix — scan_repo fit was always undefined. The schema declared fit required, but parseClaudeResponse never produces it (the extension derives it separately via verdict.js deriveFit). Now a pure buildScanResult calls deriveFit, the schema declares the real { level, label, why } object, and bottom_line is surfaced too.

Bug fix — blueprint_scene outputSchema lied. It advertised edges as { source, target, label } and flat nodes, but buildBlueprintScene returns engine-shaped edges { id, from, to, rel, note, userDrawn } and nodes with ref/layer/pinned. Any client trusting the declared schema would mis-parse. Schema now matches the real scene.

GITHUB_TOKEN pass-through — optional opts.githubToken threaded into fetchGitHub (fetcher.js) and fetchSource/ghJson (deepdive.js). No token → byte-for-byte the old anonymous path, so the extension is untouched. With one, GitHub's 60 req/hr → 5000/hr (blueprint/deep_dive make 10+ calls each and would otherwise 403 mid-scan).

Hard timeout on the Anthropic callAbortController + ANTHROPIC_TIMEOUT_MS (default 60s) so a stalled connection can't hang a tool call forever (mirrors the extension's per-provider timeout).

Reuse / invariants

  • Extension stays zero-dep; all deps remain isolated under mcp/.
  • Shared-module changes (fetcher.js, deepdive.js) are purely additive optional params — existing extension callers pass nothing and behave identically (confirmed: the extension's own 849 tests still pass).

Test plan

  • npx vitest run857 passed (was 849; +8 new offline MCP tests, no key/network)
    • ghOpts env plumbing; buildScanResult fit derivation (strong + risky); buildDeepDiveResult assembly
    • full runScanRepo / runDeepDive via mocked global.fetch — asserts the Authorization: Bearer header appears only when GITHUB_TOKEN is set, and deep_dive makes exactly three model calls
  • Runtime ESM import check — all three tools load; blueprint edge schema uses {from,to}
  • npx eslint . → 0 errors (25 warnings, baseline)
  • node --check on all touched files

Not in this PR (follow-ups)

  • npm / PyPI / GitLab inputs for scan_repo (the fetcher already supports them — only repo-input.js is GitHub-only)
  • Multi-provider (reuse the extension's providers.js registry)
  • A tools/list structural smoke test

⚠️ Not live-tested against a real key/network (no key in CI) — exercised entirely through mocks.

…call

GITHUB_TOKEN (mcp/github-auth.js → ghOpts) is threaded as an optional
opts.githubToken into fetcher.js (fetchGitHub) and deepdive.js
(fetchSource/ghJson). With no token the path is byte-for-byte the old
anonymous behavior, so the extension is untouched; with one, GitHub's
60 req/hr limit becomes 5000/hr — needed for blueprint_scene/deep_dive,
which make 10+ GitHub calls per run.

anthropic.js now wraps the fetch in an AbortController timeout
(ANTHROPIC_TIMEOUT_MS, default 60s) so a stalled connection can't hang
a tool call forever — mirroring the extension's per-provider timeout.
scan_repo declared `fit` as a required output but never produced it:
parseClaudeResponse has no fit field (the extension derives it separately
via verdict.js deriveFit), so the headline verdict was always undefined.
Now buildScanResult (pure, testable) calls deriveFit and the schema
declares fit as the real {level,label,why} object; bottom_line added too.

blueprint_scene's outputSchema advertised edges as {source,target,label}
and flat nodes, but buildBlueprintScene returns engine-shaped edges
{id,from,to,rel,note,userDrawn} and nodes carrying ref/layer/pinned. Any
client trusting the declared schema would mis-handle the payload. Schema
now matches the real scene.

Both runners thread ghOpts() for the GITHUB_TOKEN pass-through.
Third tool: plain-English explanation of how a repo works, with gaps,
assumptions, self-test questions, and per-claim confidence, plus the
underlying atoms + lineage. Reuses deepdive.js verbatim (same module the
extension's Deep Dive uses); three sequential model calls, so it is the
heaviest tool. Registered in the server's multi-tool dispatcher.
Adds 8 offline tests (no key, no network) covering the previously
untested runners: ghOpts env plumbing, buildScanResult fit derivation,
buildDeepDiveResult assembly, and full runScanRepo/runDeepDive via a
mocked global.fetch (asserting the GITHUB_TOKEN Authorization header and
deep_dive's three model calls). README documents the three tools, the
real output shapes, GITHUB_TOKEN, and the timeout knob.
@New1Direction New1Direction merged commit 9e417db into main Jun 17, 2026
1 check passed
@New1Direction New1Direction deleted the feat/mcp-v2-core branch June 17, 2026 00:28
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.

1 participant