mcpgawk 0.1.1__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/.github/workflows/ci.yml +15 -0
- mcpgawk-0.1.3/.github/workflows/mcpgawk-gate-selftest.yml +20 -0
- mcpgawk-0.1.3/.github/workflows/publish-openvsx.yml +38 -0
- mcpgawk-0.1.3/.github/workflows/publish-pypi.yml +51 -0
- mcpgawk-0.1.3/.gitignore +39 -0
- mcpgawk-0.1.3/CHANGELOG.md +54 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/PKG-INFO +68 -18
- mcpgawk-0.1.3/README.md +151 -0
- mcpgawk-0.1.3/action.yml +62 -0
- mcpgawk-0.1.3/assets/brand/social-preview.png +0 -0
- {mcpgawk-0.1.1/docs → mcpgawk-0.1.3}/assets/brand/social-preview.svg +2 -2
- mcpgawk-0.1.3/docs/.gitignore +1 -0
- mcpgawk-0.1.3/docs/CNAME +1 -0
- mcpgawk-0.1.3/docs/api/lead.js +69 -0
- mcpgawk-0.1.3/docs/assets/brand/social-preview.png +0 -0
- mcpgawk-0.1.3/docs/assets/logos/alibaba.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/anthropic.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/baidu.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/cerebras.svg +4 -0
- mcpgawk-0.1.3/docs/assets/logos/cloudflare.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/cohere.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/copilot.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/cursor.svg +12 -0
- mcpgawk-0.1.3/docs/assets/logos/deepseek.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/discord.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/docker.svg +3 -0
- mcpgawk-0.1.3/docs/assets/logos/figma.svg +14 -0
- mcpgawk-0.1.3/docs/assets/logos/framer.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/gemini.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/github.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/gitlab.svg +6 -0
- mcpgawk-0.1.3/docs/assets/logos/gojek.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/google.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/grab.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/grok.svg +4 -0
- mcpgawk-0.1.3/docs/assets/logos/huawei.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/huggingface.svg +67 -0
- mcpgawk-0.1.3/docs/assets/logos/inflection.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/infosys.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/kakaotalk.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/kimi.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/klarna.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/langchain.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/line.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/linear.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/mercadolibre.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/meta.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/microsoft.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/midjourney.svg +6 -0
- mcpgawk-0.1.3/docs/assets/logos/mistral.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/naver.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/netlify.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/notion.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/nubank.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/nvidia.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/ollama.svg +7 -0
- mcpgawk-0.1.3/docs/assets/logos/openai.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/paytm.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/perplexity.svg +24 -0
- mcpgawk-0.1.3/docs/assets/logos/postgresql.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/python.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/qwen.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/rakuten.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/replicate.svg +12 -0
- mcpgawk-0.1.3/docs/assets/logos/replit.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/revolut.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/runway.svg +14 -0
- mcpgawk-0.1.3/docs/assets/logos/sap.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/sentry.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/shopee.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/slack.svg +24 -0
- mcpgawk-0.1.3/docs/assets/logos/sony.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/spotify.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/stability.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/stripe.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/suno.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/supabase.svg +15 -0
- mcpgawk-0.1.3/docs/assets/logos/swiggy.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/tiktok.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/togetherai.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/vercel.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/wechat.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/weibo.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/wise.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/xai.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/xiaomi.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/zoho.svg +1 -0
- mcpgawk-0.1.3/docs/assets/logos/zomato.svg +1 -0
- mcpgawk-0.1.3/docs/index.html +610 -0
- mcpgawk-0.1.3/docs/logofield.js +134 -0
- mcpgawk-0.1.3/docs/report.html +90 -0
- mcpgawk-0.1.3/editors/vscode/.vscodeignore +5 -0
- mcpgawk-0.1.3/editors/vscode/CHANGELOG.md +12 -0
- mcpgawk-0.1.3/editors/vscode/LICENSE +201 -0
- mcpgawk-0.1.3/editors/vscode/README.md +22 -0
- mcpgawk-0.1.3/editors/vscode/extension.js +177 -0
- mcpgawk-0.1.3/editors/vscode/media/icon.png +0 -0
- mcpgawk-0.1.3/editors/vscode/package.json +39 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/pyproject.toml +2 -2
- mcpgawk-0.1.3/scripts/ci_gate.py +105 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/cli.py +37 -13
- mcpgawk-0.1.3/src/mcpgawk/grade.py +75 -0
- mcpgawk-0.1.3/src/mcpgawk/label.py +158 -0
- mcpgawk-0.1.3/src/mcpgawk/oauth_scopes.py +45 -0
- mcpgawk-0.1.3/src/mcpgawk/supplychain.py +100 -0
- mcpgawk-0.1.3/supabase/leads.sql +34 -0
- mcpgawk-0.1.3/supabase/lockdown.sql +12 -0
- mcpgawk-0.1.3/tests/test_cli_integration.py +66 -0
- mcpgawk-0.1.3/tests/test_grade.py +47 -0
- mcpgawk-0.1.3/tests/test_label_axes.py +107 -0
- mcpgawk-0.1.3/tests/test_oauth_scopes.py +61 -0
- mcpgawk-0.1.3/tests/test_supplychain.py +87 -0
- mcpgawk-0.1.1/.gitignore +0 -11
- mcpgawk-0.1.1/CHANGELOG.md +0 -21
- mcpgawk-0.1.1/README.md +0 -101
- mcpgawk-0.1.1/assets/brand/social-preview.png +0 -0
- mcpgawk-0.1.1/docs/CNAME +0 -1
- mcpgawk-0.1.1/docs/assets/brand/social-preview.png +0 -0
- mcpgawk-0.1.1/docs/index.html +0 -178
- mcpgawk-0.1.1/src/mcpgawk/label.py +0 -89
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/BRAND.md +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/CONTRIBUTING.md +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/LICENSE +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/NOTICE +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/SECURITY.md +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/THREAT-MODEL.md +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/demo.gif +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/favicon.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/identity-board.html +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/nativerse-mark.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/wordmark-dark.png +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/wordmark-dark.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/wordmark-light.png +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/assets/brand/wordmark-light.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/docs/assets/brand/favicon.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/docs/assets/brand/nativerse-mark.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3/docs}/assets/brand/social-preview.svg +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/docs/styles.css +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/examples/mcp.json +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/__init__.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/__main__.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/drift.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/history.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/measure.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/probe.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/servercard.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/src/mcpgawk/signals.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/tests/test_drift.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/tests/test_measure.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/tests/test_no_egress.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/tests/test_servercard.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/tests/test_signals.py +0 -0
- {mcpgawk-0.1.1 → mcpgawk-0.1.3}/uv.lock +0 -0
|
@@ -36,3 +36,18 @@ jobs:
|
|
|
36
36
|
python -m venv /tmp/smoke
|
|
37
37
|
/tmp/smoke/bin/pip install dist/*.whl
|
|
38
38
|
/tmp/smoke/bin/mcpgawk --help
|
|
39
|
+
|
|
40
|
+
version-consistency:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- name: CLI (pyproject.toml) and VS Code extension (package.json) versions must match
|
|
45
|
+
run: |
|
|
46
|
+
PY_VERSION=$(grep -m1 '^version = ' pyproject.toml | sed -E 's/version = "(.*)"/\1/')
|
|
47
|
+
EXT_VERSION=$(node -p "require('./editors/vscode/package.json').version")
|
|
48
|
+
echo "pyproject.toml: $PY_VERSION"
|
|
49
|
+
echo "editors/vscode/package.json: $EXT_VERSION"
|
|
50
|
+
if [ "$PY_VERSION" != "$EXT_VERSION" ]; then
|
|
51
|
+
echo "::error::Version mismatch — CLI is $PY_VERSION but the VS Code extension is $EXT_VERSION. Bump editors/vscode/package.json (and its CHANGELOG.md) alongside every pyproject.toml release."
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: MCP hygiene gate (self-test)
|
|
2
|
+
|
|
3
|
+
# Dogfoods the mcpgawk Action against a real open server, so the marketplace
|
|
4
|
+
# listing has a live, passing example.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
gate:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- name: MCP hygiene gate
|
|
16
|
+
uses: ./
|
|
17
|
+
with:
|
|
18
|
+
stdio: 'npx -y @modelcontextprotocol/server-filesystem /tmp'
|
|
19
|
+
max-tokens: 5000
|
|
20
|
+
fail-on-flagged: true
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Publish VS Code extension (Open VSX)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "editors/vscode/package.json"
|
|
8
|
+
workflow_dispatch: {}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
defaults:
|
|
14
|
+
run:
|
|
15
|
+
working-directory: editors/vscode
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: "20"
|
|
22
|
+
|
|
23
|
+
- name: Fail loudly if the Open VSX token isn't configured
|
|
24
|
+
run: |
|
|
25
|
+
if [ -z "${{ secrets.OVSX_PAT }}" ]; then
|
|
26
|
+
echo "::error::OVSX_PAT secret is not set — add it under repo Settings > Secrets before this can publish."
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
- run: npm install -g @vscode/vsce ovsx
|
|
31
|
+
|
|
32
|
+
- name: Package
|
|
33
|
+
run: vsce package --no-dependencies
|
|
34
|
+
|
|
35
|
+
- name: Publish to Open VSX
|
|
36
|
+
env:
|
|
37
|
+
OVSX_PAT: ${{ secrets.OVSX_PAT }}
|
|
38
|
+
run: ovsx publish *.vsix -p "$OVSX_PAT"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "pyproject.toml"
|
|
8
|
+
workflow_dispatch: {}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
|
|
20
|
+
- name: Fail loudly if the PyPI token isn't configured
|
|
21
|
+
run: |
|
|
22
|
+
if [ -z "${{ secrets.PYPI_API_TOKEN }}" ]; then
|
|
23
|
+
echo "::error::PYPI_API_TOKEN secret is not set — add it under repo Settings > Secrets before this can publish."
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
- name: Skip if this version is already published (re-running main shouldn't re-publish)
|
|
28
|
+
run: |
|
|
29
|
+
LOCAL=$(grep -m1 '^version = ' pyproject.toml | sed -E 's/version = "(.*)"/\1/')
|
|
30
|
+
LIVE=$(python -c "import json,urllib.request; print(json.load(urllib.request.urlopen('https://pypi.org/pypi/mcpgawk/json'))['info']['version'])" 2>/dev/null || echo "none")
|
|
31
|
+
echo "local=$LOCAL live=$LIVE"
|
|
32
|
+
echo "LOCAL_VERSION=$LOCAL" >> "$GITHUB_ENV"
|
|
33
|
+
if [ "$LOCAL" = "$LIVE" ]; then
|
|
34
|
+
echo "Already published — skipping."
|
|
35
|
+
echo "SKIP=1" >> "$GITHUB_ENV"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
- run: python -m pip install --upgrade pip build
|
|
39
|
+
if: env.SKIP != '1'
|
|
40
|
+
|
|
41
|
+
- run: python -m build
|
|
42
|
+
if: env.SKIP != '1'
|
|
43
|
+
|
|
44
|
+
- name: Publish to PyPI
|
|
45
|
+
if: env.SKIP != '1'
|
|
46
|
+
env:
|
|
47
|
+
TWINE_USERNAME: __token__
|
|
48
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
49
|
+
run: |
|
|
50
|
+
python -m pip install twine
|
|
51
|
+
twine upload dist/*
|
mcpgawk-0.1.3/.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
venv/
|
|
5
|
+
*.egg-info/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
|
|
10
|
+
# dev-only QA harness
|
|
11
|
+
assets/brand/_qa.html
|
|
12
|
+
editors/vscode/*.vsix
|
|
13
|
+
editors/vscode/node_modules/
|
|
14
|
+
.vercel
|
|
15
|
+
|
|
16
|
+
# ===== NEVER PUBLISH — private strategy, paid product, business/internal =====
|
|
17
|
+
# Belt-and-braces guard: even if one of these is accidentally copied into this
|
|
18
|
+
# public checkout, git will not track it. Primary protection is that these live
|
|
19
|
+
# only in the private repo (~/devtools/mcpgawk, which has NO remote).
|
|
20
|
+
HANDOFF.md
|
|
21
|
+
# private strategy / research / business docs
|
|
22
|
+
docs/spec/
|
|
23
|
+
docs/PLATFORM-AND-FACTORY.md
|
|
24
|
+
docs/foundational-decisions.md
|
|
25
|
+
docs/track-v-verdict-strategy.md
|
|
26
|
+
docs/platform-system-design.md
|
|
27
|
+
docs/architecture-convergence.md
|
|
28
|
+
docs/functional-spec.md
|
|
29
|
+
docs/research-*.md
|
|
30
|
+
docs/strategy-*.md
|
|
31
|
+
docs/*-audit*.md
|
|
32
|
+
docs/adversarial-review-prompt.md
|
|
33
|
+
docs/vendor-outreach-*.md
|
|
34
|
+
# the PAID platform code (verify / monitor / enforce / forge) — never in the free repo
|
|
35
|
+
src/gawk_platform/
|
|
36
|
+
tests/test_platform_smoke.py
|
|
37
|
+
tests/test_forge_smoke.py
|
|
38
|
+
# third-party study clones (Apache-2.0) — never vendored/published
|
|
39
|
+
reference/
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to mcpgawk. Format: [Keep a Changelog](https://keepachangelog.com/); versioning: [SemVer](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## [0.1.3] — 2026-07-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Report now covers 5 axes: cost (+ top-3 heaviest tools), trust surface (% write, % exfil-capable,
|
|
9
|
+
destructive-declared count), annotation completeness (score — was computed but never surfaced),
|
|
10
|
+
coverage (prompts/resources, previously `--json`-only), and bounded signals (unchanged).
|
|
11
|
+
- `--verbose` — full per-tool table in CLI text output (previously only the write/exfil-flagged subset
|
|
12
|
+
was shown; the full list existed only via `--json`).
|
|
13
|
+
- `--supply-chain` (opt-in) — checks the launched package against the public npm registry / PyPI JSON
|
|
14
|
+
API for deprecation (npm) / yanked (PyPI, PEP 592) status. Makes a real network call — only the package
|
|
15
|
+
name and version are sent, never the tool inventory. Off by default.
|
|
16
|
+
- `--oauth-scopes` (opt-in) — locally decodes a supplied `Authorization: Bearer <jwt>` header's `scope`/
|
|
17
|
+
`scp` claim. No network call; the signature is not verified (reading a declared claim, not
|
|
18
|
+
authenticating). Opaque (non-JWT) tokens are reported as not locally inspectable, never guessed at.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- `x-mcpgawk` label schema gains `top_heavy_tools`, `trust_surface`, `annotation_completeness`, and
|
|
22
|
+
(only when the corresponding flag is passed) `supply_chain`/`oauth_scopes`. All additive — no existing
|
|
23
|
+
key renamed or removed.
|
|
24
|
+
|
|
25
|
+
## [0.1.2] — 2026-07-08
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Plain, reader-first README and package description.
|
|
29
|
+
- README images use absolute URLs so they render on PyPI (relative paths only work on GitHub).
|
|
30
|
+
|
|
31
|
+
## [0.1.1] — 2026-07-08
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- A tool declaring `destructiveHint: true` is now counted as write/mutating even when its name isn't a
|
|
35
|
+
write-verb (e.g. a `pause_job` tool). Previously the verb heuristic could leave a declared-destructive
|
|
36
|
+
tool unflagged.
|
|
37
|
+
|
|
38
|
+
## [0.1.0] — 2026-07-08
|
|
39
|
+
|
|
40
|
+
Initial release. Local-first MCP measurement.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- `mcpgawk scan` over stdio, streamable-HTTP, and SSE via the official `mcp` SDK (protocol-version negotiated).
|
|
44
|
+
- Cost **index** (named tokenizer) + **EXACT** capability facts (write / exfil-capable / annotations) + **integrity pin**.
|
|
45
|
+
- **Bounded** heuristic signals (0-FP on the tested corpus, never verdicts): injection-shaped descriptions
|
|
46
|
+
(tools and prompts), cross-server name shadowing, Server-Card under-declaration.
|
|
47
|
+
- `--track` rug-pull / drift monitor with a local history store.
|
|
48
|
+
- Server Card reader (`/.well-known/mcp/server-card.json`) — reads the card when present, checks
|
|
49
|
+
declared-vs-measured, falls back to live-connect. Fetched with no auth and no redirect-following.
|
|
50
|
+
- Label output as a Server-Card extension (`x-mcpgawk`); `--json` for machine consumption.
|
|
51
|
+
|
|
52
|
+
### Security
|
|
53
|
+
- Measurement layers import no network library — cannot egress by construction (enforced by test).
|
|
54
|
+
- Per-server timeout so a hung server degrades to one error row.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcpgawk
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: A local-first CLI that measures what an MCP server costs and what it can do. Nothing leaves your machine.
|
|
5
5
|
Project-URL: Homepage, https://mcp.gawk.dev
|
|
6
6
|
Project-URL: Documentation, https://mcp.gawk.dev
|
|
7
7
|
Project-URL: Repository, https://github.com/gawk-dev/mcpgawk
|
|
@@ -29,11 +29,11 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
|
|
30
30
|
<p align="center">
|
|
31
31
|
<picture>
|
|
32
|
-
<source media="(prefers-color-scheme: dark)" srcset="assets/brand/wordmark-dark.png">
|
|
33
|
-
<img alt="mcpgawk by nativerse" src="assets/brand/wordmark-light.png" width="320">
|
|
32
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/wordmark-dark.png">
|
|
33
|
+
<img alt="mcpgawk by nativerse" src="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/wordmark-light.png" width="320">
|
|
34
34
|
</picture>
|
|
35
35
|
</p>
|
|
36
|
-
<p align="center"><em>
|
|
36
|
+
<p align="center"><em>Make MCP lean and honest.</em></p>
|
|
37
37
|
|
|
38
38
|
# mcpgawk
|
|
39
39
|
|
|
@@ -41,22 +41,22 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
[](https://pypi.org/project/mcpgawk/)
|
|
42
42
|
[](LICENSE)
|
|
43
43
|
[](https://github.com/gawk-dev/mcpgawk/actions/workflows/ci.yml)
|
|
44
|
+
[](https://open-vsx.org/extension/gawk-dev/mcpgawk)
|
|
45
|
+
[](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate)
|
|
44
46
|
[](#guarantees)
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expose — **without the server's inventory ever leaving your machine.**
|
|
48
|
+
A local-first command that measures what a [Model Context Protocol](https://modelcontextprotocol.io)
|
|
49
|
+
server costs and what it can do. It runs on your machine and uploads nothing.
|
|
49
50
|
|
|
50
51
|
<p align="center">
|
|
51
|
-
<img src="assets/brand/demo.gif" alt="mcpgawk scanning an MCP server — tools, token cost, and capability flags, locally" width="760">
|
|
52
|
+
<img src="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/demo.gif" alt="mcpgawk scanning an MCP server — tools, token cost, and capability flags, locally" width="760">
|
|
52
53
|
</p>
|
|
53
54
|
<p align="center"><sub>Real output. Reproducible on your machine — no account, nothing uploaded.</sub></p>
|
|
54
55
|
|
|
55
56
|
## Why
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
surface**. mcpgawk measures both, **locally**, and never phones home about what it saw.
|
|
58
|
+
Connect an MCP server and it loads all its tools into your AI's context. Every request. Used or not.
|
|
59
|
+
You pay for those tokens, and you haven't checked what the tools can do. mcpgawk shows you both, locally.
|
|
60
60
|
|
|
61
61
|
## How it's different
|
|
62
62
|
|
|
@@ -68,18 +68,39 @@ surface**. mcpgawk measures both, **locally**, and never phones home about what
|
|
|
68
68
|
## Features
|
|
69
69
|
|
|
70
70
|
- 🔌 **Any transport** — stdio, streamable-HTTP, SSE, and OAuth remotes (via the `mcp-remote` bridge).
|
|
71
|
-
- 💸 **Token cost index** — exactly what each tool adds to your context at connect.
|
|
72
|
-
- 🧾 **Capability facts** — write / exfil-capable / declared annotations, straight from the schema
|
|
71
|
+
- 💸 **Token cost index** — exactly what each tool adds to your context at connect, plus the 3 heaviest tools.
|
|
72
|
+
- 🧾 **Capability facts** — write / exfil-capable / declared annotations, straight from the schema, plus a
|
|
73
|
+
trust-surface summary (% write, % exfil-capable, destructive-declared count) and an annotation-completeness
|
|
74
|
+
score.
|
|
73
75
|
- 📌 **Integrity pin + drift** — catch a server that silently rewrites its tools (`--track`).
|
|
74
76
|
- 🚩 **Bounded signals** — injection-shaped descriptions, cross-server shadowing, under-declaring Server Cards — pointers for a human, never verdicts.
|
|
75
77
|
- 🔒 **Zero egress, by construction** — the measurement layers import no network library. Enforced by a test.
|
|
78
|
+
Two checks are opt-in and make an explicit exception (see [Guarantees](#guarantees)): `--supply-chain` and
|
|
79
|
+
`--oauth-scopes`.
|
|
76
80
|
|
|
77
|
-
##
|
|
81
|
+
## Get it — three ways
|
|
78
82
|
|
|
83
|
+
**CLI** (any terminal):
|
|
79
84
|
```bash
|
|
80
85
|
pip install mcpgawk # or: uv tool install mcpgawk
|
|
86
|
+
mcpgawk scan mcp.json
|
|
81
87
|
```
|
|
82
88
|
|
|
89
|
+
**Editor** (VS Code / Cursor): install **mcpgawk** from the marketplace ([Open VSX](https://open-vsx.org/extension/gawk-dev/mcpgawk)). It scans your workspace `mcp.json` and shows cost + capability flags inline.
|
|
90
|
+
|
|
91
|
+
**CI** (GitHub Action): gate every PR on token budget / drift ([Marketplace](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate)):
|
|
92
|
+
```yaml
|
|
93
|
+
- uses: gawk-dev/mcpgawk@v1
|
|
94
|
+
with: { config: mcp.json, max-tokens: 8000, fail-on-flagged: true }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## When to run it
|
|
98
|
+
|
|
99
|
+
- **Before you add a server** — see what it costs and what it can do, before you trust it.
|
|
100
|
+
- **When your agent feels slow or picks the wrong tool** — it's often MCP bloat (too many / too-heavy tools).
|
|
101
|
+
- **On every PR** — the CI gate catches drift and creeping token cost.
|
|
102
|
+
- **If you *publish* an MCP server** — see what it costs your users and how it reads to a client, and fix it (usually one line per tool). Lean + well-annotated is a differentiator.
|
|
103
|
+
|
|
83
104
|
## Use
|
|
84
105
|
|
|
85
106
|
```bash
|
|
@@ -89,28 +110,42 @@ mcpgawk scan --http https://host/mcp --header "Authorization: Bearer $TOKEN"
|
|
|
89
110
|
mcpgawk scan --sse https://host/sse
|
|
90
111
|
mcpgawk scan mcp.json --track # record + detect rug-pulls over time
|
|
91
112
|
mcpgawk scan mcp.json --json # machine-readable labels
|
|
113
|
+
mcpgawk scan mcp.json --verbose # full per-tool table, not just flagged tools
|
|
114
|
+
mcpgawk scan mcp.json --supply-chain # opt-in: npm/PyPI deprecation check (network)
|
|
115
|
+
mcpgawk scan mcp.json --oauth-scopes # opt-in: decode a supplied Bearer JWT's scope
|
|
92
116
|
```
|
|
93
117
|
|
|
94
118
|
## What it reports
|
|
95
119
|
|
|
96
120
|
- **Cost index** — tokens each tool adds at connect (named tokenizer; a comparable index, not an
|
|
97
|
-
absolute Claude count).
|
|
98
|
-
- **
|
|
121
|
+
absolute Claude count), plus the 3 heaviest tools.
|
|
122
|
+
- **Trust surface** — capability facts (write/mutating, exfil-capable, declared annotations) rolled up
|
|
123
|
+
into % write, % exfil-capable, and a destructive-declared count.
|
|
124
|
+
- **Annotation completeness** — a transparent composite (annotated ÷ total tools declaring read/write
|
|
125
|
+
intent), not a risk score.
|
|
126
|
+
- **Coverage** — tools, prompts, and resources counted (`--verbose` for the full per-tool table).
|
|
99
127
|
- **Integrity pin** — a hash that changes if the server silently rewrites its tools; `--track`
|
|
100
128
|
turns it into rug-pull detection over time.
|
|
101
129
|
- **Bounded signals** — precise, low-false-positive pointers *for a human to review*, never verdicts:
|
|
102
130
|
injection-shaped descriptions (tools **and** prompts), cross-server name shadowing, and public
|
|
103
131
|
Server Cards that under-declare what the server actually exposes.
|
|
132
|
+
- **Supply-chain** (opt-in, `--supply-chain`) — checks the launched package against the public npm/PyPI
|
|
133
|
+
registry for deprecation/yank status.
|
|
134
|
+
- **OAuth scopes** (opt-in, `--oauth-scopes`) — locally decodes a supplied Bearer JWT's `scope` claim.
|
|
104
135
|
|
|
105
136
|
## Guarantees
|
|
106
137
|
|
|
107
138
|
- **No inventory egress.** The only network is the protocol client talking to the server you point
|
|
108
139
|
it at. The measurement layers import no network library — they *cannot* egress by construction
|
|
109
140
|
(enforced by a test). Public Server Card discovery is fetched with no auth and no redirect-following.
|
|
141
|
+
Two flags are the explicit, opt-in exception: `--supply-chain` sends the launched package's name
|
|
142
|
+
(and pinned version, if any) — never your tool inventory — to the public npm registry or PyPI JSON
|
|
143
|
+
API. `--oauth-scopes` makes no network call at all; it locally decodes a Bearer JWT you already
|
|
144
|
+
supplied. Neither runs unless you pass the flag.
|
|
110
145
|
- **Facts ≠ heuristics.** Exact capability facts and the token index never mix with the bounded
|
|
111
146
|
heuristic signals — separate in code, separate in output.
|
|
112
147
|
- **Reproducible.** One command, identical numbers.
|
|
113
|
-
- **
|
|
148
|
+
- **Tracks the protocol.** Built on the official `mcp` SDK, which negotiates the protocol version.
|
|
114
149
|
|
|
115
150
|
## Develop
|
|
116
151
|
|
|
@@ -118,6 +153,21 @@ mcpgawk scan mcp.json --json # machine-read
|
|
|
118
153
|
uv run --extra dev --with mcp --with tiktoken --with httpx python -m pytest -q
|
|
119
154
|
```
|
|
120
155
|
|
|
156
|
+
## CI gate — GitHub Action
|
|
157
|
+
|
|
158
|
+
Scan your MCP servers on every pull request and fail the build if one gets too heavy or trips a signal.
|
|
159
|
+
It runs entirely in your runner — nothing is uploaded — and posts a per-server cost/flag table to the job summary.
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
- uses: gawk-dev/mcpgawk@v1
|
|
163
|
+
with:
|
|
164
|
+
config: mcp.json # or: stdio / http / sse — a single server
|
|
165
|
+
max-tokens: 8000 # fail if any server loads more than this at connect
|
|
166
|
+
fail-on-flagged: true # fail if any bounded signal fires
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Available on the [GitHub Marketplace](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate).
|
|
170
|
+
|
|
121
171
|
## Contributing
|
|
122
172
|
|
|
123
173
|
Issues and PRs welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first, and see the design
|
mcpgawk-0.1.3/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/wordmark-dark.png">
|
|
4
|
+
<img alt="mcpgawk by nativerse" src="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/wordmark-light.png" width="320">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
<p align="center"><em>Make MCP lean and honest.</em></p>
|
|
8
|
+
|
|
9
|
+
# mcpgawk
|
|
10
|
+
|
|
11
|
+
[](https://pypi.org/project/mcpgawk/)
|
|
12
|
+
[](https://pypi.org/project/mcpgawk/)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
[](https://github.com/gawk-dev/mcpgawk/actions/workflows/ci.yml)
|
|
15
|
+
[](https://open-vsx.org/extension/gawk-dev/mcpgawk)
|
|
16
|
+
[](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate)
|
|
17
|
+
[](#guarantees)
|
|
18
|
+
|
|
19
|
+
A local-first command that measures what a [Model Context Protocol](https://modelcontextprotocol.io)
|
|
20
|
+
server costs and what it can do. It runs on your machine and uploads nothing.
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<img src="https://raw.githubusercontent.com/gawk-dev/mcpgawk/main/assets/brand/demo.gif" alt="mcpgawk scanning an MCP server — tools, token cost, and capability flags, locally" width="760">
|
|
24
|
+
</p>
|
|
25
|
+
<p align="center"><sub>Real output. Reproducible on your machine — no account, nothing uploaded.</sub></p>
|
|
26
|
+
|
|
27
|
+
## Why
|
|
28
|
+
|
|
29
|
+
Connect an MCP server and it loads all its tools into your AI's context. Every request. Used or not.
|
|
30
|
+
You pay for those tokens, and you haven't checked what the tools can do. mcpgawk shows you both, locally.
|
|
31
|
+
|
|
32
|
+
## How it's different
|
|
33
|
+
|
|
34
|
+
- **vs. cloud scanners** (e.g. Snyk/Invariant `mcp-scan`) — they upload your inventory to a server and
|
|
35
|
+
gate the verdict. mcpgawk runs entirely on your machine; nothing is uploaded, ever.
|
|
36
|
+
- **vs. lazy-load gateways** — they cut tokens but tell you nothing about the *risk* surface.
|
|
37
|
+
- **mcpgawk does both** — cost **and** trust — locally, reproducibly, in one command.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- 🔌 **Any transport** — stdio, streamable-HTTP, SSE, and OAuth remotes (via the `mcp-remote` bridge).
|
|
42
|
+
- 💸 **Token cost index** — exactly what each tool adds to your context at connect, plus the 3 heaviest tools.
|
|
43
|
+
- 🧾 **Capability facts** — write / exfil-capable / declared annotations, straight from the schema, plus a
|
|
44
|
+
trust-surface summary (% write, % exfil-capable, destructive-declared count) and an annotation-completeness
|
|
45
|
+
score.
|
|
46
|
+
- 📌 **Integrity pin + drift** — catch a server that silently rewrites its tools (`--track`).
|
|
47
|
+
- 🚩 **Bounded signals** — injection-shaped descriptions, cross-server shadowing, under-declaring Server Cards — pointers for a human, never verdicts.
|
|
48
|
+
- 🔒 **Zero egress, by construction** — the measurement layers import no network library. Enforced by a test.
|
|
49
|
+
Two checks are opt-in and make an explicit exception (see [Guarantees](#guarantees)): `--supply-chain` and
|
|
50
|
+
`--oauth-scopes`.
|
|
51
|
+
|
|
52
|
+
## Get it — three ways
|
|
53
|
+
|
|
54
|
+
**CLI** (any terminal):
|
|
55
|
+
```bash
|
|
56
|
+
pip install mcpgawk # or: uv tool install mcpgawk
|
|
57
|
+
mcpgawk scan mcp.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Editor** (VS Code / Cursor): install **mcpgawk** from the marketplace ([Open VSX](https://open-vsx.org/extension/gawk-dev/mcpgawk)). It scans your workspace `mcp.json` and shows cost + capability flags inline.
|
|
61
|
+
|
|
62
|
+
**CI** (GitHub Action): gate every PR on token budget / drift ([Marketplace](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate)):
|
|
63
|
+
```yaml
|
|
64
|
+
- uses: gawk-dev/mcpgawk@v1
|
|
65
|
+
with: { config: mcp.json, max-tokens: 8000, fail-on-flagged: true }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## When to run it
|
|
69
|
+
|
|
70
|
+
- **Before you add a server** — see what it costs and what it can do, before you trust it.
|
|
71
|
+
- **When your agent feels slow or picks the wrong tool** — it's often MCP bloat (too many / too-heavy tools).
|
|
72
|
+
- **On every PR** — the CI gate catches drift and creeping token cost.
|
|
73
|
+
- **If you *publish* an MCP server** — see what it costs your users and how it reads to a client, and fix it (usually one line per tool). Lean + well-annotated is a differentiator.
|
|
74
|
+
|
|
75
|
+
## Use
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
mcpgawk scan mcp.json # a whole config
|
|
79
|
+
mcpgawk scan --stdio "npx -y @modelcontextprotocol/server-filesystem /tmp"
|
|
80
|
+
mcpgawk scan --http https://host/mcp --header "Authorization: Bearer $TOKEN"
|
|
81
|
+
mcpgawk scan --sse https://host/sse
|
|
82
|
+
mcpgawk scan mcp.json --track # record + detect rug-pulls over time
|
|
83
|
+
mcpgawk scan mcp.json --json # machine-readable labels
|
|
84
|
+
mcpgawk scan mcp.json --verbose # full per-tool table, not just flagged tools
|
|
85
|
+
mcpgawk scan mcp.json --supply-chain # opt-in: npm/PyPI deprecation check (network)
|
|
86
|
+
mcpgawk scan mcp.json --oauth-scopes # opt-in: decode a supplied Bearer JWT's scope
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## What it reports
|
|
90
|
+
|
|
91
|
+
- **Cost index** — tokens each tool adds at connect (named tokenizer; a comparable index, not an
|
|
92
|
+
absolute Claude count), plus the 3 heaviest tools.
|
|
93
|
+
- **Trust surface** — capability facts (write/mutating, exfil-capable, declared annotations) rolled up
|
|
94
|
+
into % write, % exfil-capable, and a destructive-declared count.
|
|
95
|
+
- **Annotation completeness** — a transparent composite (annotated ÷ total tools declaring read/write
|
|
96
|
+
intent), not a risk score.
|
|
97
|
+
- **Coverage** — tools, prompts, and resources counted (`--verbose` for the full per-tool table).
|
|
98
|
+
- **Integrity pin** — a hash that changes if the server silently rewrites its tools; `--track`
|
|
99
|
+
turns it into rug-pull detection over time.
|
|
100
|
+
- **Bounded signals** — precise, low-false-positive pointers *for a human to review*, never verdicts:
|
|
101
|
+
injection-shaped descriptions (tools **and** prompts), cross-server name shadowing, and public
|
|
102
|
+
Server Cards that under-declare what the server actually exposes.
|
|
103
|
+
- **Supply-chain** (opt-in, `--supply-chain`) — checks the launched package against the public npm/PyPI
|
|
104
|
+
registry for deprecation/yank status.
|
|
105
|
+
- **OAuth scopes** (opt-in, `--oauth-scopes`) — locally decodes a supplied Bearer JWT's `scope` claim.
|
|
106
|
+
|
|
107
|
+
## Guarantees
|
|
108
|
+
|
|
109
|
+
- **No inventory egress.** The only network is the protocol client talking to the server you point
|
|
110
|
+
it at. The measurement layers import no network library — they *cannot* egress by construction
|
|
111
|
+
(enforced by a test). Public Server Card discovery is fetched with no auth and no redirect-following.
|
|
112
|
+
Two flags are the explicit, opt-in exception: `--supply-chain` sends the launched package's name
|
|
113
|
+
(and pinned version, if any) — never your tool inventory — to the public npm registry or PyPI JSON
|
|
114
|
+
API. `--oauth-scopes` makes no network call at all; it locally decodes a Bearer JWT you already
|
|
115
|
+
supplied. Neither runs unless you pass the flag.
|
|
116
|
+
- **Facts ≠ heuristics.** Exact capability facts and the token index never mix with the bounded
|
|
117
|
+
heuristic signals — separate in code, separate in output.
|
|
118
|
+
- **Reproducible.** One command, identical numbers.
|
|
119
|
+
- **Tracks the protocol.** Built on the official `mcp` SDK, which negotiates the protocol version.
|
|
120
|
+
|
|
121
|
+
## Develop
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
uv run --extra dev --with mcp --with tiktoken --with httpx python -m pytest -q
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## CI gate — GitHub Action
|
|
128
|
+
|
|
129
|
+
Scan your MCP servers on every pull request and fail the build if one gets too heavy or trips a signal.
|
|
130
|
+
It runs entirely in your runner — nothing is uploaded — and posts a per-server cost/flag table to the job summary.
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
- uses: gawk-dev/mcpgawk@v1
|
|
134
|
+
with:
|
|
135
|
+
config: mcp.json # or: stdio / http / sse — a single server
|
|
136
|
+
max-tokens: 8000 # fail if any server loads more than this at connect
|
|
137
|
+
fail-on-flagged: true # fail if any bounded signal fires
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Available on the [GitHub Marketplace](https://github.com/marketplace/actions/mcpgawk-mcp-hygiene-gate).
|
|
141
|
+
|
|
142
|
+
## Contributing
|
|
143
|
+
|
|
144
|
+
Issues and PRs welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first, and see the design
|
|
145
|
+
boundaries in [THREAT-MODEL.md](THREAT-MODEL.md). Security reports go through [SECURITY.md](SECURITY.md)
|
|
146
|
+
(privately, not a public issue).
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
**Apache-2.0** — see [LICENSE](LICENSE). Part of the **nativerse** · gawk.dev family. The value is in the
|
|
151
|
+
repo, not a cloud.
|
mcpgawk-0.1.3/action.yml
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: 'mcpgawk MCP hygiene gate'
|
|
2
|
+
description: 'Scan your MCP servers in CI and fail the build if one is too heavy or trips a signal. Local, nothing uploaded.'
|
|
3
|
+
author: 'nativerse'
|
|
4
|
+
branding:
|
|
5
|
+
icon: 'shield'
|
|
6
|
+
color: 'blue'
|
|
7
|
+
|
|
8
|
+
inputs:
|
|
9
|
+
config:
|
|
10
|
+
description: 'Path to an mcp.json config to scan.'
|
|
11
|
+
required: false
|
|
12
|
+
default: 'mcp.json'
|
|
13
|
+
stdio:
|
|
14
|
+
description: 'A single stdio server command to scan instead of a config (e.g. "npx -y @modelcontextprotocol/server-filesystem /tmp").'
|
|
15
|
+
required: false
|
|
16
|
+
default: ''
|
|
17
|
+
http:
|
|
18
|
+
description: 'A single streamable-HTTP MCP server URL to scan.'
|
|
19
|
+
required: false
|
|
20
|
+
default: ''
|
|
21
|
+
sse:
|
|
22
|
+
description: 'A single SSE MCP server URL to scan.'
|
|
23
|
+
required: false
|
|
24
|
+
default: ''
|
|
25
|
+
max-tokens:
|
|
26
|
+
description: 'Fail the build if any server loads more than this many tokens at connect. 0 = no budget.'
|
|
27
|
+
required: false
|
|
28
|
+
default: '0'
|
|
29
|
+
fail-on-flagged:
|
|
30
|
+
description: 'Fail the build if any server trips a bounded signal (injection-shaped / shadowing / undeclared).'
|
|
31
|
+
required: false
|
|
32
|
+
default: 'false'
|
|
33
|
+
version:
|
|
34
|
+
description: 'mcpgawk version to install from PyPI ("latest" or e.g. "0.1.2").'
|
|
35
|
+
required: false
|
|
36
|
+
default: 'latest'
|
|
37
|
+
|
|
38
|
+
runs:
|
|
39
|
+
using: 'composite'
|
|
40
|
+
steps:
|
|
41
|
+
- name: Set up Python
|
|
42
|
+
uses: actions/setup-python@v5
|
|
43
|
+
with:
|
|
44
|
+
python-version: '3.12'
|
|
45
|
+
- name: Install mcpgawk
|
|
46
|
+
shell: bash
|
|
47
|
+
run: |
|
|
48
|
+
if [ "${{ inputs.version }}" = "latest" ]; then
|
|
49
|
+
pip install --quiet --disable-pip-version-check mcpgawk
|
|
50
|
+
else
|
|
51
|
+
pip install --quiet --disable-pip-version-check "mcpgawk==${{ inputs.version }}"
|
|
52
|
+
fi
|
|
53
|
+
- name: Scan and gate
|
|
54
|
+
shell: bash
|
|
55
|
+
env:
|
|
56
|
+
MCPGAWK_CONFIG: ${{ inputs.config }}
|
|
57
|
+
MCPGAWK_STDIO: ${{ inputs.stdio }}
|
|
58
|
+
MCPGAWK_HTTP: ${{ inputs.http }}
|
|
59
|
+
MCPGAWK_SSE: ${{ inputs.sse }}
|
|
60
|
+
MCPGAWK_MAX_TOKENS: ${{ inputs.max-tokens }}
|
|
61
|
+
MCPGAWK_FAIL_ON_FLAGGED: ${{ inputs.fail-on-flagged }}
|
|
62
|
+
run: python "${{ github.action_path }}/scripts/ci_gate.py"
|
|
Binary file
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<text x="256" y="196" dominant-baseline="central" font-family="Sentient, Georgia, serif" font-weight="500" font-size="104" letter-spacing="-3" fill="#16160F">mcpgawk</text>
|
|
9
9
|
<text x="258" y="270" font-family="Supreme, -apple-system, sans-serif" font-size="30" letter-spacing="0.5" fill="#6B6B5E">by <tspan fill="#2A33C2" font-weight="500">nativerse</tspan></text>
|
|
10
10
|
<line x1="96" y1="352" x2="1184" y2="352" stroke="#E7E6E0" stroke-width="1.5"/>
|
|
11
|
-
<text x="96" y="438" font-family="Sentient, Georgia, serif" font-size="42" fill="#3A3A30">
|
|
11
|
+
<text x="96" y="438" font-family="Sentient, Georgia, serif" font-size="42" fill="#3A3A30">Make it lean. Make it honest.</text>
|
|
12
12
|
<text x="96" y="524" font-family="Tabular, ui-monospace, Menlo, monospace" font-size="25" fill="#717166"><tspan fill="#2A9d6b">●</tspan> cli-stdio 14 tools 2061 tok@connect 4 flagged</text>
|
|
13
13
|
<circle cx="102" cy="576" r="6" fill="#2A9d6b"/>
|
|
14
|
-
<text x="120" y="576" dominant-baseline="central" font-family="Tabular, ui-monospace, Menlo, monospace" font-size="24" letter-spacing="1" fill="#6B6B5E">local ·
|
|
14
|
+
<text x="120" y="576" dominant-baseline="central" font-family="Tabular, ui-monospace, Menlo, monospace" font-size="24" letter-spacing="1" fill="#6B6B5E">local · nothing leaves your machine</text>
|
|
15
15
|
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.vercel
|
mcpgawk-0.1.3/docs/CNAME
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mcp.gawk.dev
|