Note: The project remains in maintenance mode: no active feature development, but maintenance patches like this one are still published.
- Added
src/utils/models.ts, a single registry that defines the supported providers, their default model and the suggested model IDs. The LLM dispatcher and thevibe_checktool schema now read from it instead of repeating hard-coded strings, and the docs are written against it. DEFAULT_MODELis now scoped toDEFAULT_LLM_PROVIDER. Previously a call that overrode only the provider (modelOverride: { provider: 'anthropic' }) still sent the configuredDEFAULT_MODEL— typically a Gemini model ID — to that provider and got a 404. It now falls through to the target provider's registry default.- Gemini: default is now
gemini-3.6-flash(wasgemini-2.5-pro), served natively from Google AI Studio. The retry model isgemini-3.5-flash-lite(wasgemini-2.5-flash).gemini-3.5-flashand the 2.5 models remain selectable. - Anthropic: default is now
claude-sonnet-5(wasclaude-3-5-sonnet-20241022).claude-opus-5,claude-fable-5andclaude-haiku-4-5-20251001are listed as supported. - OpenAI: default is now
gpt-5.6-terra(waso4-mini), withgpt-5.6-solandgpt-5.6-lunalisted as supported. - OpenRouter still requires an explicit fully-qualified slug; the registry carries examples only.
- Migrated from the retired
@google/generative-aipackage (deprecated Nov 2025, unmaintained) to the unified@google/genaiSDK. The dispatcher now callsai.models.generateContent({ model, contents })and readsresponse.text. - The Gemini fallback no longer retries when the failing model is the fallback — that case previously issued a duplicate doomed request.
- A blocked or empty Gemini response is now treated as a failure.
@google/genaiexposestextas a getter that returnsundefined— rather than throwing, as the retired package did — when a candidate is safety-blocked, has no parts, or is thought-only. Left as-is that returned an empty string, so neither the model retry nor the static-question fallback fired and the agent received a blank vibe check.
- CORS no longer defaults to
*. UnsetCORS_ORIGINnow means "loopback origins only, any port", which is what local MCP clients use. A comma-separated allowlist or*restores broader access. Credentialed CORS is never enabled. - DNS-rebinding protection. The
Hostheader is validated againstlocalhost/127.0.0.1/::1by default;MCP_ALLOWED_HOSTSaccepts a list or*. Rebinding makes an attacker's page same-origin, so CORS alone does not stop it. - Explicit, validated body cap. JSON bodies are limited to 100kb, configurable via
MCP_MAX_BODY_SIZE. Unparseable values fall back to the default instead of being passed to body-parser, which silently disables enforcement for limits it cannot parse (GHSA onbody-parser). - The
Hostcheck runs ahead of the CORS middleware, so a disallowed host cannot get a preflight answered —corsterminates allowed-origin preflights itself without calling the next handler. MCP_ALLOWED_HOSTSentries are normalised the same way incomingHostheaders are, so an entry written with a port (mcp.internal:8080— the literal value an operator reads off a request) matches instead of rejecting every request.Hostvalues are also shape-checked, solocalhost:80@evil.exampleno longer reduces tolocalhost.- Body-parser rejections and unknown routes now return JSON-RPC errors rather than Express's HTML pages, with the correct codes (
-32700for malformed JSON,-32600for oversized bodies,-32601for unknown routes). The underlying error message and stack are logged server-side; the client only sees the sanitised message.X-Powered-Byis disabled. MCP_MAX_BODY_SIZEaccepts thetb/pbunits thebytesparser understands, and rejects0, which would have 413'd every request.scripts/security-check.cjsno longer flags method calls such asregex.exec(...)as process execution; realchild_processuse is still caught (verified with a probe file).- Adopts the intent of community PR #99 with a working implementation:
cors({ origin: 'http://localhost:*' })as proposed is not a pattern thecorspackage expands, so it would have matched only that literal string, andexpress.json({ limit: '100kb' })restates body-parser's existing default. npm auditis clean (0 advisories, was 10 including 6 high): axios 1.13.5 → 1.18.1, MCP SDK 1.26 → 1.29 (pulls hono 4.12.32, form-data 4.0.6, fast-uri 3.1.4), vitest/coverage-v8 3.2.6 → 4.1.10 (clears the brace-expansion, minimatch, glob, test-exclude, postcss and esbuild advisories in the test toolchain).- Added an
overridesentry pinning@hono/node-serverto^2.0.11. The MCP SDK declares^1.19.9, a range that cannot reach the version fixing GHSA-frvp-7c67-39w9; the override is covered by the HTTP integration tests and should be removed once the SDK widens its range. SECURITY.mdrefreshed: the tool inventory said "two safe tools" when there are five, and the new HTTP controls are documented.
- Dropped the unused
body-parserdirect dependency (Express 5 bundles its own), bumped the OpenAI SDK to 6.x, and corrected@types/expressto v5 to match the installed Express. smithery.yaml: declared Node>=20to matchpackage.json(was>=18), passedMCP_ALLOWED_HOSTSso hosted deployments keep working under the new default, and added the missinganthropictag.scripts/docker-setup.shnow emitsMCP_ALLOWED_HOSTSin the generateddocker-compose.yml. The compose service publishes no ports, so it is reached by service name — which the new loopback-only default would otherwise reject. Documented in docker-automation.md.- README: fixed the quickstart's HTTP endpoints, which pointed at
/healthand/rpcinstead of the real/healthzand/mcp. - New tests:
tests/http-security.test.tsplus HTTP integration coverage for host rejection, allowlisted hosts, oversized bodies and header hygiene.
- If you run the HTTP transport on a non-loopback hostname (Docker, reverse proxy, hosted), set
MCP_ALLOWED_HOSTSto that hostname or*, otherwise requests are rejected with HTTP 403. - If a browser client on a non-loopback origin calls the server, set
CORS_ORIGINto that origin. - No changes to the stdio transport, the tool contracts, or the response formats.
Note: The project remains in maintenance mode: no active feature development, but maintenance patches like this one are still published.
- Publish the v2.8.0 fixes to npm: v2.8.0 was tagged in
package.jsononly — nov2.8.0git tag was pushed, so the npm publish workflow never ran and the registry stayed at 2.7.6. v2.8.1 ships everything from v2.8.0 plus the items below. - Add
.github/workflows/create-release.yml— GitHub Releases are now created automatically (with auto-generated notes) when av*tag is pushed.
smithery.yamlpointed npm installs at the wrong package scope (@mseep/vibe-check-mcp); corrected to@pv-bhat/vibe-check-mcp.server.jsonnow declares the real provider environment variables (GEMINI_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY,ANTHROPIC_API_KEY, all optional/secret) instead of aYOUR_API_KEYplaceholder.scripts/sync-version.mjsnow also syncsserver.json,CITATION.cff, andsmithery.yaml(previously stranded at 2.5.1, 2.7.3, and 2.5.0 respectively), and no longer rewrites the most recentCHANGELOG.mdrelease heading (which could mislabel an older release) — it warns when the new version's entry is missing instead.
- vitest / @vitest/coverage-v8 3.2.4 → 3.2.6 (devDependencies) — clears GHSA-5xrq-8626-4rwp (arbitrary file read/execute via the Vitest UI server). Production dependency tree was already clean;
npm auditis now fully clean again.
Note: This is the final maintenance release. The project is no longer actively maintained but remains available for use under the MIT license. Community forks and contributions are welcome.
- Fix
check_constitutionreturning invalid MCP content type (type: "json"→type: "text") — closes #84 - Fix HTTP Accept header normalization to work with MCP SDK >=1.26 (Hono adapter reads
rawHeaders) - Remove unused
samplingcapability (no longer in SDK types)
- axios 1.12.2 → 1.13.5 — fixes DoS via
__proto__key in mergeConfig - @modelcontextprotocol/sdk 1.16.0 → 1.26.0 — fixes cross-client response data leakage (GHSA-345p-7cg4-v4c7)
- diff 5.2.0 → 8.0.3 — fixes DoS and ReDOS vulnerabilities in
parsePatch - express 5.1.0 → 5.2.1 — fixes CVE-2024-51999
- brace-expansion, minimatch, picomatch, qs, rollup, yaml — all patched via audit fix
- Resolved all 14 npm audit vulnerabilities → 0 vulnerabilities
- Remove
@types/diffdev dependency (TypeScript definitions now bundled in diff 8.x) - Update
httpTransportWrapperto target inner_webStandardTransportfor SDK 1.26 compatibility - Update JSON-RPC compat tests for new SDK transport architecture
- Transport: migrate STDIO → Streamable HTTP (
POST /mcp,GET /mcp→ 405). - Constitution tools:
update_constitution,reset_constitution,check_constitution(session-scoped, in-memory, logged). - CPI surfaced: banner + concise metrics; links to ResearchGate, CPI GitHub, and Zenodo (MURST).
- CPI architecture enables adaptive interrupts to mitigate Reasoning Lock-In
- History continuity across sessions
- Multi-provider support for Gemini, OpenAI and OpenRouter
- Optional vibe_learn logging for privacy-conscious deployments
- Repository restructured with Vitest unit tests and CI workflow
- Initial feedback loop and Docker setup