carelessdept/ci-guard-mcp

GitHub ↗ · How this check works

Per-setup public labels: Linux / Haiku: Works · Linux / Luna: Works

Static status badge · SVG · read-only JSON. Embed with ![Coldpass status](https://coldpass.dev/badge/carelessdept--ci-guard-mcp.svg).

mcp-server

Works

README claims checked out on 2 recorded setups. Combinations not listed here were not tested.

Answers apply to each recorded setup, revision and operation. Earlier observations remain in Run details.

Tested on Linux
PlatformHaikuLuna
Linuxyesyes

Linux / Haiku 5.5: yes · Oct 23, 2026 · 11f7635d3c67 · claude-code / 2.1.300 (Claude Code)
Recorded operation: node <guest-path> --mcp --root /tmp/ciguard-fixture · local stdio MCP start + initialize + tools/list

Linux / Luna: yes · Oct 23, 2026 · 11f7635d3c67 · codex / codex-cli 0.163.0
Recorded operation: node dist/cli.js scan. --format json

Does what it says
1 of 1 claims checked out
  • The scan returns deterministic findings and summary counts as JSON.: Real input produced the expected result: "error": 0

    Source: Audits are deterministic, read-only, and run without sending source code to a service.

    Input: node dist/cli.js scan . --format json

    Expected: JSON scan report with summary and filesScanned

    Command: node dist/cli.js scan . --format json

    Observed: "error": 0, "warn": 0, "info": 0 }, "filesScanned": 50 }

MCP
Documented only
Local or hosted
local
Local: runs on your machine
Needs keys or browser
None seen
Maintained
Maintained
actively maintained: last commit 1 days ago; 10 commits and 0 merged PRs in 90 days; 0 open issues, 0 open PRs; latest release 2026-10-22

Last commit Oct 22, 2026

Setup time
10 min 57 s
10 min 57 s to a working result
Issue
none found in recorded check
Examples
1 of 1 ran as expected
  • Build and scan the source checkout: command completed successfully

    Source: README.md / Run locally / Or from a local source checkout

    Input: npm ci --ignore-scripts; npm run build; node dist/cli.js scan .

    Expected: Successful build and scan report

    Command: node dist/cli.js scan .

    Observed: 50 files scanned · 0 errors · 0 warnings · 0 informational

Evidence
README behavior checked
Agent interfaces
CLI, MCP (documented only)
CLI, MCP (documented only)

Observed interfaces were exercised by the checker. Documentation alone does not confirm compatibility.

Tested with
Codex / Luna
  • Linux: Codex / Luna · agent codex-cli 0.163.0 · Checked operation passed · Oct 23, 2026 on 11f7635d3c67

Each entry describes its recorded operation and source revision. Other agent clients were not tested.

Safety
No unexpected network or file activity found in these checks

No problems traced to this repository code in these checks; a short run cannot prove safety.

Full event, path and process lists for each observed setup:

Run details

Haiku 5.5

Native agent · Checked operation passed

Checked operation node <guest-path> --mcp --root /tmp/ciguard-fixture · local stdio MCP start + initialize + tools/list

Agent-reported scope: Install and run ci-guard-mcp from the pinned checkout: build, CLI scan, MCP scan_repo tool call, and the documented npm run check suite

MCP server returned: ci-guard-mcp · version 0.2.0.

MCP tools returned: scan_repo, check_env_drift, audit_github_workflows, check_secret_leaks. Tool listing does not establish authenticated tool-call success.

Run details
run
carelessdept--ci-guard-mcp-claude-haiku-5-5-1792797963689250861
date
Oct 23, 2026
time to working
340.8s
product hosting / execution
Local stdio MCP server in the guest
recorded operation scope
product operation
model
claude-haiku-5-5
agent / version
claude-code / 2.1.300 (Claude Code)
platform
linux
reported cost
$0.015150
Recorded source
https://github.com/carelessdept/ci-guard-mcp
Backend
hyperv
Tool transport
mcp-assigned-vm
Requested source pin (not an observed revision)
{"commit": "11f7635d3c67081aeebcd0ffe133db043ea03b7b", "url": "https://github.com/carelessdept/ci-guard-mcp"}
Test version
readme-bdc1b9b3c0d2673aef87e076d14084a8123ddcf09d520c1ee2e364a37c3f4bb9
revision
11f7635d3c67081aeebcd0ffe133db043ea03b7b
Whose fault: not assigned · resolved

Safety: No problems traced to this repository code in these checks.

No problems traced to this repository code in these checks.

OSV scanned supported lockfiles; unpinned dependencies and unsupported formats are outside this check.

A short run cannot establish that code is safe.

Connections show IP addresses; proxies can hide the final hostname.

Tracing covers dispatched commands and their children, not the whole OS; guest root can interfere with tracing.

Full safety evidence →

Answers recorded for this run
  • Exit code 1 when findings are at or above the threshold: Real input produced the expected result: "ruleId": "workflow/script-injection"

    Source: Exit codes: **0** below threshold, **1** findings at or above threshold

    Input: /tmp/ciguard-fixture (workflow with script injection)

    Expected: exit 1 and the workflow/script-injection finding

    Command: node <guest-path> scan /tmp/ciguard-fixture --format json

    Observed: "ruleId": "workflow/script-injection", "severity": "error", "file": ".github/workflows/ci.yml", "line": 10, "message": "Untrusted GitHub context is interpolated directly into a shell script.", "suggestion": "Pass event fields through step env and use quoted shell variables." } ], "summary": { "error": 1, "warn": 1, "info": 0 }, "filesScanned": 1 }

  • MCP tool results include structuredContent with the same report: Real input produced the expected result: workflow/unpinned-action

    Source: Responses contain text JSON plus `structuredContent` with the same report.

    Input: {"tool": "scan_repo", "arguments": {"path": "."}}

    Expected: report containing the workflow/unpinned-action finding

    Command: node <guest-path> --mcp --root /tmp/ciguard-fixture tools/call {"tool": "scan_repo", "arguments": {"path": "."}}

    Observed: workflow/unpinned-action\",\"severity\":\"warn\",\"file\":\".github/workflows/ci.yml\",\"line\":9,\"message\":\"External action or reusable workflow is not pinned to an immutable digest.\",\"suggestion\":\"Pin actions to a full 40-character commit SHA and containers to a sha256 digest.\"},{\"ruleId\":\"workflow/script-injection\",\"severity\":\"error\",\"file\":\".github/workflows/ci.yml\",\"line\":10,\"message\":\"Untrusted GitHub context is interpolated directly into a shell script.\",\"suggestion\":\"Pass event fields through step env and use quoted shell variables.\"}],\"summary\":{\"error

Examples

  • Repository development check runs typecheck, tests and build: command completed successfully

    Source: README.md Development and release

    Input: npm run check

    Expected: all 54 tests pass

    Command: npm run check

    Observed: ks ok 53 - v0.2.0: detects direct secret interpolation and toJSON(secrets) log exfiltration in run blocks --- duration_ms: 0.770257 type: 'test' ... # Subtest: v0.2.0: audits GitLab CI (.gitlab-ci.yml) for script injection, pwn requests, and unpinned includes/images ok 54 - v0.2.0: audits GitLab CI (.gitlab-ci.yml) for script injection, pwn requests, and unpinned includes/images --- duration_ms: 2.086947 type: 'test' ... 1..54 # tests 54 # suites 0 # pass 54 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 17322.349656 > [email protected] build > tsc -p tsconfig.json

  • Scan the checkout with a warn threshold: command completed successfully

    Source: README.md Development and release

    Input: node dist/cli.js scan . --fail-on warn

    Expected: 0 errors, exit 0

    Command: node dist/cli.js scan . --fail-on warn

    Observed: 50 files scanned · 0 errors · 0 warnings · 0 informational

Local or hosted: local

What the agent did

Install and run ci-guard-mcp from the pinned checkout: build, CLI scan, MCP scan_repo tool call, and the documented npm run check suite

cd <guest-path> && pwd && ls -la && git status 2>&1 | head -3; id -u; python3 --version; cat README.md 2>/dev/null | head -200
ls /inputs 2>&1; ls <guest-path> 2>&1; cat /etc/os-release | head -2
cd <guest-path> && (git init -q 2>&1; git remote add origin https://github.com/carelessdept/ci-guard-mcp 2>&1; timeout 120 git fetch --depth 1 origin 11f7635d3c67081aeebcd0ffe133db043ea03b7b 2>&1 | tail -3; git reset --mixed FETCH_HEAD 2>&1 | tail -2; git log --oneline -1 2>&1); which node npm; node -v 2>&1; npm -v 2>&1; cat package.json | head -40
(curl -fsSL https://deb.nodesource.com/setup_22.x -o /tmp/ns.sh && sudo -n bash /tmp/ns.sh && sudo -n apt-get install -y nodejs) 2>&1 | tail -5; node -v; npm -v
cd <guest-path> && npm ci --ignore-scripts 2>&1 | tail -5 && npm run build 2>&1 | tail -5 && ls dist | head; node dist/cli.js scan . --format json --no-git > /tmp/scan-out.json 2>/tmp/scan-err.txt; echo rc=$?; head -c 600 /tmp/scan-out.json; cat /tmp/scan-err.txt | head -5
mkdir -p /tmp/mcpclient && cat > /tmp/mcpclient/c.mjs <<'EOF'
import { spawn } from 'node:child_process';
const [,, tool, argsJson] = process.argv;
const p = spawn('node', ['<guest-path>','--mcp','--root','<guest-path>'], {stdio:['pipe','pipe','inherit']});
let buf=''; const waiters={};
p.stdout.on('data',d=>{buf+=d; let i; while((i=buf.indexOf('\n'))>=0){const l=buf.slice(0,i); buf=buf.slice(i+1); if(l.trim()){const m=JSON.parse(l); if(m.id!==undefined && waiters[m.id]) waiters[m.id](m);}}});
const send=(o)=>p.stdin.write(JSON.stringify(o)+'\n');
const req=(id,method,params)=>new Promise(r=>{waiters[id]=r; send({jsonrpc:'2.0',id,method,params});});
(async()=>{
  const init=await req(1,'initialize',{protocolVersion:'2025-11-25',capabilities:{},clientInfo:{name:'probe',version:'0'}});
  console.log('INIT', JSON.stringify(init.result.serverInfo));
  send({jsonrpc:'2.0',method:'notifications/initialized'});
  if(!tool){const l=await req(2,'tools/list',{}); console.log(l.result.tools.map(t=>t.name).join(', '));}
  else {const r=await req(3,'tools/call',{name:tool,arguments:JSON.parse(argsJson||'{}')}); console.log(JSON.stringify(r.result??r.error).slice(0,1500));}
  p.stdin.end(); p.kill();
})();
EOF
cd /tmp/mcpclient && timeout 60 node c.mjs && timeout 60 node c.mjs scan_repo '{"path":"."}' ; timeout 60 node c.mjs check_secret_leaks '{"path":"."}'
mkdir -p /tmp/ciguard-fixture/.github/workflows && cat > /tmp/ciguard-fixture/.github/workflows/ci.yml <<'EOF'
name: ci
on: [push]
permissions:
  contents: read
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "${{ github.event.issue.title }}"
EOF
cd <guest-path> && node dist/cli.js scan /tmp/ciguard-fixture --format json; echo rc=$?; grep -rn "setInterval\|cron\|schedule\|--once\|--now\|webhook" src README.md | head; timeout 600 npm run check 2>&1 | tail -15; echo check_rc=$?
cd <guest-path> && ls -la .coldpass; cat .gitignore; node dist/cli.js scan . --fail-on warn; echo rc=$?; node dist/cli.js scan /tmp/ciguard-fixture --format json | grep -c ruleId; grep -o "Exit codes: \*\*0\*\* below threshold, \*\*1\*\* findings at or above threshold" README.md; grep -o "Responses contain text JSON plus \`structuredContent\` with the same report." README.md; grep -o "^| \`scan_repo\` | All four auditors | \`path?: string\`, \`includeIgnored?: boolean\` |" README.md
cd <guest-path> && cat > probe.json <<'EOF'
{"kind":"mcp","argv":["node","<guest-path>","--mcp","--root","/tmp/ciguard-fixture"],"cwd":"<guest-path>","tool":"scan_repo","arguments":{"path":"."},"expected_text":"\"ruleId\":\"workflow/unpinned-action\""}
EOF
cat > claims.json <<'EOF'
[
 {"kind":"claim","claim":"Exit code 1 when findings are at or above the threshold","source":"Exit codes: **0** below threshold, **1** findings at or above threshold","input":"/tmp/ciguard-fixture (workflow with script injection)","expected":"exit 1 and the workflow/script-injection finding","probe_kind":"cli","argv":["node","<guest-path>","scan","/tmp/ciguard-fixture","--format","json"],"expected_returncode":1,"expected_text":"\"ruleId\": \"workflow/script-injection\"","cwd":"<guest-path>"},
 {"kind":"claim","claim":"MCP tool results include structuredContent with the same report","source":"Responses contain text JSON plus `structuredContent` with the same report.","input":"scan_repo on /tmp/ciguard-fixture","expected":"report containing the workflow/unpinned-action finding","probe_kind":"mcp","argv":["node","<guest-path>","--mcp","--root","/tmp/ciguard-fixture"],"tool":"scan_repo","arguments":{"path":"."},"expected_text":"\"ruleId\":\"workflow/unpinned-action\"","cwd":"<guest-path>"}
]
EOF
cat > examples.json <<'EOF'
[
 {"kind":"example","claim":"Repository development check runs typecheck, tests and build","source":"README.md Development and release","input":"npm run check","expected":"all 54 tests pass","argv":["npm","run","check"],"cwd":"<guest-path>","env":{},"expected_text":"# fail 0"},
 {"kind":"example","claim":"Scan the checkout with a warn threshold","source":"README.md Development and release","input":"node dist/cli.js scan . --fail-on warn","expected":"0 errors, exit 0","argv":["node","dist/cli.js","scan",".","--fail-on","warn"],"cwd":"<guest-path>","env":{},"expected_text":"0 errors"}
]
EOF
cat > cycles.json <<'EOF'
{"detected":false,"reason":"Inspected README.md and src/ for cron, schedule, setInterval, loop, webhook, --once and --now entry points; none exist. ci-guard-mcp is a one-shot CLI (scan), a one-shot GitHub Action, and a stdio MCP server that answers requests on demand. No product cycle to trigger.","checks":[]}
EOF
mkdir -p <guest-path> && cat > report.json <<'EOF'
{"outcome":"working","fault_owner":null,"operation":"Install and run ci-guard-mcp from the pinned checkout: build, CLI scan, MCP scan_repo tool call, and the documented npm run check suite","operation_scope":"Linux Ubuntu 24.04 guest; Node 22 (README requires Node 20+); local source checkout only, no npm publication, no browser or credentials needed","steps":["git init; git remote add origin https://github.com/carelessdept/ci-guard-mcp; git fetch --depth 1 origin 11f7635d3c67081aeebcd0ffe133db043ea03b7b; git reset --mixed FETCH_HEAD","sudo NodeSource setup_22.x + apt-get install nodejs (Node v22.23.4, npm 10.9.9)","npm ci --ignore-scripts","npm run build","node dist/cli.js scan . --format json","node dist/cli.js scan . --fail-on warn","node dist/cli.js scan /tmp/ciguard-fixture --format json (exit 1, real findings)","node dist/cli.js --mcp --root /tmp/ciguard-fixture; tools/call scan_repo","npm run check (54 tests pass)"],"deviations":["Node.js was not installed in the guest; installed Node 22 from NodeSource via sudo apt-get (README requires Node 20+). No errors.","Workspace was not a git repo; applied the supplied git init/fetch/reset pin steps.","The supplied checker path /inputs/coldpass-preflight.py does not exist; used <guest-path> as the validator.","Used a scratch fixture at /tmp/ciguard-fixture with a deliberately flawed workflow to exercise findings, since the repo itself has zero findings.","No README 'npx' usage was run: the package is not published yet, so the local dist/cli.js path was used as the README documents for source checkouts."],"stuck_step":null,"main_blocker":null,"plain_failure":null,"suggested_fix":"None required for this run. Optional: publish the package so the npx examples in the README can be run as written."}
EOF
for f in probe claims examples cycles report; do python3 -m json.tool $f.json >/dev/null && echo "$f ok"; done; cd <guest-path> && <env-var>=<guest-path> python3 -I <guest-path> --validate --replay 2>&1 | tail -40
cd <guest-path> && sed -i 's/"expected_text":"\\"ruleId\\":\\"workflow\/unpinned-action\\""/"expected_text":"workflow\/unpinned-action"/' probe.json && sed -i 's/"expected_text":"\\"ruleId\\":\\"workflow\/unpinned-action\\""/"expected_text":"workflow\/unpinned-action"/' claims.json && grep -o '"expected_text":"[^"]*"' probe.json claims.json && python3 -m json.tool probe.json >/dev/null && python3 -m json.tool claims.json >/dev/null && cd <guest-path> && <env-var>=<guest-path> python3 -I <guest-path> --validate --replay 2>&1 | tail -c 1500
cd <guest-path> && <env-var>=<guest-path> python3 -I <guest-path> --validate --replay > /tmp/check-out.txt 2>&1; echo rc=$?; python3 -I -c "
import json,sys
d=json.loads(open('/tmp/check-out.txt').read().strip().splitlines()[-1])
print('valid:',d.get('valid')); print('problems:',d.get('problems'))
" ; grep -o '"working": [a-z]*' /tmp/check-out.txt | head; cat .coldpass/claims.json | python3 -m json.tool | grep expected_text
pgrep -fa "dist/cli.js" || echo "no servers running"; ls <guest-path>
Earlier attempts (1)

Luna

Native agent · Checked operation passed

Checked operation node dist/cli.js scan . --format json

Agent-reported scope: Build the TypeScript CLI and audit the repository as JSON

Run details
run
carelessdept--ci-guard-mcp-gpt-6-luna-1792805076633917582
date
Oct 23, 2026
time to working
657.2s
product hosting / execution
Local command in the guest
recorded operation scope
product operation
model
gpt-6-luna
agent / version
codex / codex-cli 0.163.0
platform
linux
reported cost
not reported (not assumed free)
Recorded source
https://github.com/carelessdept/ci-guard-mcp
Backend
hyperv
Tool transport
mcp-assigned-vm
Requested source pin (not an observed revision)
{"commit": "11f7635d3c67081aeebcd0ffe133db043ea03b7b", "url": "https://github.com/carelessdept/ci-guard-mcp"}
Test version
readme-f72312298d35d84837d4fc5f6f22b138d54d456600b5ed431e36e8f5db931dbf
revision
11f7635d3c67081aeebcd0ffe133db043ea03b7b
Whose fault: not assigned · resolved

Safety: No problems traced to this repository code in these checks.

No problems traced to this repository code in these checks.

OSV scanned supported lockfiles; unpinned dependencies and unsupported formats are outside this check.

A short run cannot establish that code is safe.

Connections show IP addresses; proxies can hide the final hostname.

Tracing covers dispatched commands and their children, not the whole OS; guest root can interfere with tracing.

Full safety evidence →

Answers recorded for this run
  • The scan returns deterministic findings and summary counts as JSON.: Real input produced the expected result: "error": 0

    Source: Audits are deterministic, read-only, and run without sending source code to a service.

    Input: node dist/cli.js scan . --format json

    Expected: JSON scan report with summary and filesScanned

    Command: node dist/cli.js scan . --format json

    Observed: "error": 0, "warn": 0, "info": 0 }, "filesScanned": 50 }

Examples

  • Build and scan the source checkout: command completed successfully

    Source: README.md / Run locally / Or from a local source checkout

    Input: npm ci --ignore-scripts; npm run build; node dist/cli.js scan .

    Expected: Successful build and scan report

    Command: node dist/cli.js scan .

    Observed: 50 files scanned · 0 errors · 0 warnings · 0 informational

Local or hosted: local

What the agent did

Build the TypeScript CLI and audit the repository as JSON

cd <guest-path> && vault-search 'ci-guard-mcp README setup operation' 2>&1; cat <host-path> 2>&1; rg --files -g 'README*' -g 'AGENTS.md' -g 'pyproject.toml' -g 'package.json' -g '*.yml' -g '*.yaml' -g 'Makefile' | head -80; pwd; id -u; python3 --version; cat README.md
cd <guest-path> && ls -la; cat package.json; node --version; npm --version; which sudo && sudo -n true; 
sudo -n apt-get update && sudo -n apt-get install -y nodejs npm
node --version; npm --version;
cd <guest-path> && cat .coldpass/* 2>/dev/null; sudo -n apt-get install -y curl ca-certificates; curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -n -E bash -; sudo -n apt-get install -y nodejs; node --version
cd <guest-path> && npm ci --ignore-scripts && npm run build && node dist/cli.js scan . --format json > <guest-path>; rc=$?; cat <guest-path>; echo scan_rc=$rc; cat src/cli.ts; find src -maxdepth 3 -type f
cd <guest-path> && sed -n '1,260p' src/mcp-server.ts; node -e 'const p=require("./package-lock.json"); console.log(p.packages["node_modules/typescript"]?.version)'
cd <guest-path> && mkdir -p .coldpass && node dist/cli.js --mcp --root <guest-path> <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"coldpass","version":"1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"scan_repo","arguments":{"path":".","noGit":true}}}
EOF
cd <guest-path> && cat > .coldpass/probe.json <<'EOF'
{"kind":"cli","argv":["node","dist/cli.js","scan",".","--format","json"],"cwd":"<guest-path>","expected_text":"\"filesScanned\": 44"}
EOF
cat > .coldpass/claims.json <<'EOF'
[{"kind":"claim","claim":"The scan returns deterministic findings and summary counts as JSON.","source":"Audits are deterministic, read-only, and run without sending source code to a service.","input":"node dist/cli.js scan . --format json","expected":"JSON scan report with summary and filesScanned","probe_kind":"cli","argv":["node","dist/cli.js","scan",".","--format","json"],"expected_text":"\"filesScanned\": 44","cwd":"<guest-path>"}]
EOF
cat > .coldpass/examples.json <<'EOF'
[{"kind":"example","claim":"Build and scan the source checkout","source":"README.md / Run locally / Or from a local source checkout","input":"npm ci --ignore-scripts; npm run build; node dist/cli.js scan .","expected":"Successful build and scan report","argv":["node","dist/cli.js","scan","."],"cwd":"<guest-path>","expected_text":"0 errors"}]
EOF
cat > .coldpass/cycles.json <<'EOF'
{"detected":false,"reason":"Inspected README product entry points: CLI scans and MCP tool calls run on demand; no scheduler, loop, webhook, or cycle trigger is documented." ,"checks":[]}
EOF
<env-var>=<guest-path> python3 -I <guest-path> --validate --replay
cd <guest-path> && python3 - <<'PY'
import json
for f in ['.coldpass/probe.json','.coldpass/claims.json']:
 d=json.load(open(f))
 if isinstance(d,list): d[0]['expected_text']='"error": 0'
 else: d['expected_text']='"error": 0'
 open(f,'w').write(json.dumps(d,indent=2)+'\n')
PY
cat > .coldpass/report.json <<'EOF'
{"outcome":"working","fault_owner":null,"operation":"Build the TypeScript CLI and audit the repository as JSON","operation_scope":"Node.js 20.20.2; source checkout, local read-only audit","steps":["Installed Node.js 20 with the NodeSource setup script and apt.","npm ci --ignore-scripts","npm run build","node dist/cli.js scan . --format json"],"deviations":["Initial Ubuntu nodejs package supplied Node 18.19.1, below the README minimum; replaced it with Node.js 20."],"stuck_step":null,"main_blocker":null,"plain_failure":null,"suggested_fix":null}
EOF
<env-var>=<guest-path> python3 -I <guest-path> --validate --replay