feat(mcp): expose dvalin_scan so any agent can call the scanner - #161
Merged
Conversation
The MCP surface repeated the mistake the README made: all three tools were heavyweight. `dvalin_run_task` asks a calling agent to hand over an entire coding task, which needs DvalinCode's own provider configured and a lot of trust. Nothing let an agent do the cheap, obvious thing — check the code it just wrote. `dvalin_scan` is read-only and deterministic: no model, no credentials, no edits. That matters more for an agent than for a person, because it does not stack another layer of nondeterminism on top of the caller's own. It is listed first, and defaults to the `builtin` engine so the default call works on a machine with nothing installed. Findings are trimmed by default — the per-finding repair prompt and source snippet are ~1KB each, and an agent that wants context can read the file. `include_remediation_prompts` opts back in. Results are capped at 50 with the true total reported, so one scan cannot flood a caller's context. Verified end to end over real stdio MCP against a vulnerable fixture: ~170ms including process start, ~600 byte payload, correct file and line. 10 unit tests cover the default scanner set, trimming, the cap, unknown scanner rejection, the workspace guard, and timeout conversion. The existing test asserting "exactly the three task-level tools" is updated rather than loosened — it exists to pin the surface, so it now pins four and asserts each tool's readOnly annotation by name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the pieces that make the MCP server findable and usable: - A README section in both languages: if an agent writes the code, something other than that agent has to check it. - integrations/claude-code/ — an MCP setup snippet and a Claude Code skill. The skill falls back to `npx -y dvalincode` when no MCP server is configured, so it works with nothing installed. It also tells Claude what a scan does *not* prove, which matters more than the invocation: a clean scan is not a safety certificate, and suppressing a finding to make it pass is not a fix. - server.json — the MCP registry manifest, so the server can be listed rather than only documented. integrations/README.md separates the two unrelated things called "skills" in this project: DvalinCode's own JSON bundles under ~/.dvalincode/skills, and Anthropic's SKILL.md directories that Claude Code loads. Every flag documented here was checked against `mcp-serve --help` rather than written from memory. Co-Authored-By: Claude Opus 5 <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.
Summary
If an agent writes the code, something other than that agent has to check it. That is the same governance argument this project already makes, applied to who is actually writing code now — and the MCP server was not set up for it.
All three existing tools were heavyweight.
dvalin_run_taskasks a calling agent to hand over an entire coding task, which needs DvalinCode's own provider configured and a lot of trust. Nothing let an agent do the cheap, obvious thing: check what it just wrote.dvalin_scanis read-only and deterministic — no model, no credentials, no edits. That property matters more for an agent than for a person: it does not stack another layer of nondeterminism on top of the caller's own. It is listed first and defaults to thebuiltinengine, so the default call works on a machine with nothing installed.Designed for a caller with a context window
include_remediation_promptsopts back in.Testing
Verified end to end over real stdio MCP against a vulnerable fixture — full
initialize→tools/callhandshake with a separate client process, correct file and line reported.10 unit tests cover the default scanner set, trimming, the cap and
limit, unknown-scanner rejection, the workspace guard refusing a path outside--workspace, timeout conversion to milliseconds, and the missing-engine report.The existing "exactly the three task-level tools" test is updated, not loosened — it exists to pin the surface, so it now pins four and asserts each tool's
readOnlyHintby name.npm run checkgreen at 332 tests / 50 files. Repo self-scan clean.Also in this PR (second commit)
integrations/claude-code/— MCP setup snippet plus a Claude Code skill. The skill falls back tonpx -y dvalincodewhen no MCP server is configured, so it works with nothing installed. It also states what a scan does not prove, which matters more than the invocation: a clean scan is not a safety certificate, and suppressing a finding to make it pass is not a fix.server.json— the MCP registry manifest.integrations/README.mdseparates the two unrelated things called "skills" here: DvalinCode's JSON bundles, and Anthropic's SKILL.md directories.Every flag documented was checked against
mcp-serve --help, not written from memory.Security and AI Governance
docs/.docs/governance/AI-CHANGE-IMPACT-ASSESSMENT.md.Third box unticked, but this is the one where a reviewer should push back hardest if they disagree — it does add a new agent-facing tool:
dvalin_scanis strictly narrower than what the server already exposed. It runs no model, resolves no provider, and cannot write;dvalin_run_taskbeside it can do all three. It goes through the sameresolveAllowedWorkspaceguard, so--workspacestill bounds it.I did not fill out the assessment because the template covers agent permissions, prompts, provider handling, audit, and release security, and this touches none — but the call is yours.
Notes
Not done, needs your decision: submitting to the MCP registry and to
awesome-mcp-servers. Both mean opening a pull request on someone else's repository under your identity, so I preparedserver.jsonand stopped there. Say the word and I will draft both submissions..dvalincodeignoredid not grow. The self-scan flagged this PR's own test file, on a mocksnippetvalue. Unlike the three fixtures already excluded, that value is not load-bearing — the test only asserts the field is absent — so it became a neutral placeholder instead of a fifth exclusion. The exclusion list is supposed to stay surgical; this was a case where the vulnerable pattern was not actually the fixture.