agent-mcp-guard 0.3.1 → 0.4.0
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.
- package/README.md +36 -5
- package/action.yml +60 -0
- package/docs/baseline.md +70 -0
- package/docs/business-playbook.md +13 -14
- package/docs/github-action.md +31 -3
- package/docs/launch-checklist.md +4 -1
- package/docs/marketplace-action-readme.md +32 -2
- package/docs/marketplace.md +6 -4
- package/docs/roadmap.md +4 -2
- package/examples/sample-report.md +15 -15
- package/package.json +2 -1
- package/scripts/action-comment.js +72 -0
- package/scripts/action-summary.js +7 -3
- package/scripts/prepare-marketplace-action.js +3 -1
- package/site/e2e/index.html +3 -2
- package/site/e2e/report.html +15 -4
- package/site/e2e/report.json +36 -11
- package/site/e2e/report.md +15 -15
- package/site/e2e/report.sarif +10 -10
- package/src/baseline.js +162 -0
- package/src/cli.js +35 -5
- package/src/fingerprint.js +33 -0
- package/src/report.js +100 -38
- package/src/scan.js +8 -24
package/README.md
CHANGED
|
@@ -10,11 +10,16 @@ Local-first security scanning for MCP and AI agent tool configs.
|
|
|
10
10
|
|
|
11
11
|
Website: [chaoyue0307.github.io/mcp-guard](https://chaoyue0307.github.io/mcp-guard/)
|
|
12
12
|
|
|
13
|
+
Marketplace: [mcp-guard MCP Security Scanner](https://github.com/marketplace/actions/mcp-guard-mcp-security-scanner)
|
|
14
|
+
|
|
15
|
+
Live demo PR: [mcp-guard-demo#1](https://github.com/ChaoYue0307/mcp-guard-demo/pull/1)
|
|
16
|
+
|
|
13
17
|
<p>
|
|
14
18
|
<a href="https://www.npmjs.com/package/agent-mcp-guard"><img alt="npm version" src="https://img.shields.io/npm/v/agent-mcp-guard?color=0f766e"></a>
|
|
19
|
+
<a href="https://github.com/marketplace/actions/mcp-guard-mcp-security-scanner"><img alt="GitHub Marketplace" src="https://img.shields.io/badge/Marketplace-mcp--guard-0f766e?logo=github"></a>
|
|
15
20
|
<a href="https://github.com/ChaoYue0307/mcp-guard/actions"><img alt="CI" src="https://github.com/ChaoYue0307/mcp-guard/actions/workflows/ci.yml/badge.svg"></a>
|
|
16
21
|
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-111827"></a>
|
|
17
|
-
<a href="https://github.com/ChaoYue0307/mcp-guard/releases/tag/v0.
|
|
22
|
+
<a href="https://github.com/ChaoYue0307/mcp-guard/releases/tag/v0.4.0"><img alt="Release" src="https://img.shields.io/github/v/release/ChaoYue0307/mcp-guard?color=7c2d12"></a>
|
|
18
23
|
</p>
|
|
19
24
|
|
|
20
25
|
## Install
|
|
@@ -54,15 +59,27 @@ Use in CI:
|
|
|
54
59
|
mcp-guard scan --config .mcp.json --fail-on high
|
|
55
60
|
```
|
|
56
61
|
|
|
62
|
+
Accept known findings and fail only on new risk:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
mcp-guard scan --config .mcp.json --write-baseline .mcp-guard-baseline.json
|
|
66
|
+
mcp-guard scan --config .mcp.json --baseline .mcp-guard-baseline.json --fail-on high
|
|
67
|
+
```
|
|
68
|
+
|
|
57
69
|
Use the GitHub Action:
|
|
58
70
|
|
|
59
71
|
```yaml
|
|
60
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
72
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
61
73
|
with:
|
|
74
|
+
config: .mcp.json
|
|
75
|
+
baseline: .mcp-guard-baseline.json
|
|
62
76
|
fail-on: high
|
|
77
|
+
comment-pr: "true"
|
|
63
78
|
upload-sarif: "true"
|
|
64
79
|
```
|
|
65
80
|
|
|
81
|
+
Inspect the live demo pull request: [ChaoYue0307/mcp-guard-demo#1](https://github.com/ChaoYue0307/mcp-guard-demo/pull/1). It intentionally introduces risky MCP config so the Action fails, uploads reports, and sends SARIF to GitHub code scanning.
|
|
82
|
+
|
|
66
83
|
## End-to-End Example
|
|
67
84
|
|
|
68
85
|
Use the transparent example to evaluate what the scanner actually does:
|
|
@@ -73,7 +90,9 @@ Use the transparent example to evaluate what the scanner actually does:
|
|
|
73
90
|
- generated JSON report: [site/e2e/report.json](site/e2e/report.json)
|
|
74
91
|
- generated SARIF report: [site/e2e/report.sarif](site/e2e/report.sarif)
|
|
75
92
|
|
|
76
|
-
The example scans 3 MCP servers and reports 9 findings with a risk score of 98. It is synthetic, but fully reproducible from committed files.
|
|
93
|
+
The example scans 3 MCP servers and reports 9 active findings with a risk score of 98. It is synthetic, but fully reproducible from committed files.
|
|
94
|
+
|
|
95
|
+
For the GitHub Action workflow, inspect the public demo repository: [ChaoYue0307/mcp-guard-demo](https://github.com/ChaoYue0307/mcp-guard-demo).
|
|
77
96
|
|
|
78
97
|
## What It Finds
|
|
79
98
|
|
|
@@ -87,13 +106,24 @@ The example scans 3 MCP servers and reports 9 findings with a risk score of 98.
|
|
|
87
106
|
| Remote MCP URLs | Data may leave the local trust boundary. |
|
|
88
107
|
| Dangerous command patterns | `rm -rf`, `sudo`, `chmod 777`, and curl-pipe-shell should block review. |
|
|
89
108
|
|
|
109
|
+
## Team Workflow
|
|
110
|
+
|
|
111
|
+
`mcp-guard` now supports a baseline/allowlist workflow for real teams:
|
|
112
|
+
|
|
113
|
+
1. Generate a baseline from already-known findings.
|
|
114
|
+
2. Commit the baseline file after review.
|
|
115
|
+
3. Run CI with `--baseline` so accepted findings are visible but do not fail the build.
|
|
116
|
+
4. Fail pull requests only when new high-risk MCP changes appear.
|
|
117
|
+
|
|
118
|
+
The GitHub Action can also post an optional pull request comment with the active finding summary.
|
|
119
|
+
|
|
90
120
|
## Example Output
|
|
91
121
|
|
|
92
122
|
```text
|
|
93
123
|
mcp-guard scan report
|
|
94
124
|
Scanned files: 1
|
|
95
125
|
MCP servers: 3
|
|
96
|
-
|
|
126
|
+
Active findings: 9
|
|
97
127
|
Risk score: 98
|
|
98
128
|
Critical: 2 High: 5 Medium: 2 Low: 0
|
|
99
129
|
|
|
@@ -137,13 +167,14 @@ MCP configs often contain sensitive local paths, internal hostnames, tokens, and
|
|
|
137
167
|
|
|
138
168
|
Want to try `mcp-guard` on a real AI agent or MCP setup?
|
|
139
169
|
|
|
140
|
-
The project is currently an automated local scanner. I am collecting early users, real-world config examples, CI setup feedback, and rule requests to improve coverage.
|
|
170
|
+
The project is currently an automated local scanner. I am collecting early users, real-world config examples, CI setup feedback, baseline workflow feedback, and rule requests to improve coverage.
|
|
141
171
|
|
|
142
172
|
Contact: [hechaoyue0307@gmail.com](mailto:hechaoyue0307@gmail.com)
|
|
143
173
|
|
|
144
174
|
## Documentation
|
|
145
175
|
|
|
146
176
|
- [Rule reference](docs/rules.md)
|
|
177
|
+
- [Baseline and allowlist](docs/baseline.md)
|
|
147
178
|
- [GitHub Action](docs/github-action.md)
|
|
148
179
|
- [Marketplace publishing plan](docs/marketplace.md)
|
|
149
180
|
- [Privacy and security](docs/privacy-and-security.md)
|
package/action.yml
CHANGED
|
@@ -15,6 +15,14 @@ inputs:
|
|
|
15
15
|
description: Fail the workflow when a finding is at least this severity. Use critical, high, medium, low, or none.
|
|
16
16
|
required: false
|
|
17
17
|
default: high
|
|
18
|
+
baseline:
|
|
19
|
+
description: Optional mcp-guard baseline/allowlist JSON path. Matching findings are accepted and do not fail the workflow.
|
|
20
|
+
required: false
|
|
21
|
+
default: ""
|
|
22
|
+
comment-pr:
|
|
23
|
+
description: "Post or update a pull request comment with the scan summary. Requires pull-requests: write permission."
|
|
24
|
+
required: false
|
|
25
|
+
default: "false"
|
|
18
26
|
output-dir:
|
|
19
27
|
description: Directory where reports will be written.
|
|
20
28
|
required: false
|
|
@@ -48,6 +56,9 @@ outputs:
|
|
|
48
56
|
exit-code:
|
|
49
57
|
description: mcp-guard threshold exit code.
|
|
50
58
|
value: ${{ steps.reports.outputs.exit-code }}
|
|
59
|
+
comment-report:
|
|
60
|
+
description: Path to the generated pull request comment body.
|
|
61
|
+
value: ${{ steps.reports.outputs.comment-report }}
|
|
51
62
|
|
|
52
63
|
runs:
|
|
53
64
|
using: composite
|
|
@@ -62,6 +73,7 @@ runs:
|
|
|
62
73
|
shell: bash
|
|
63
74
|
env:
|
|
64
75
|
MCP_GUARD_CONFIG: ${{ inputs.config }}
|
|
76
|
+
MCP_GUARD_BASELINE: ${{ inputs.baseline }}
|
|
65
77
|
MCP_GUARD_FAIL_ON: ${{ inputs.fail-on }}
|
|
66
78
|
MCP_GUARD_OUTPUT_DIR: ${{ inputs.output-dir }}
|
|
67
79
|
run: |
|
|
@@ -74,16 +86,26 @@ runs:
|
|
|
74
86
|
if [ -n "${MCP_GUARD_CONFIG}" ]; then
|
|
75
87
|
scan_args+=(--config "${MCP_GUARD_CONFIG}")
|
|
76
88
|
fi
|
|
89
|
+
if [ -n "${MCP_GUARD_BASELINE}" ]; then
|
|
90
|
+
scan_args+=(--baseline "${MCP_GUARD_BASELINE}")
|
|
91
|
+
fi
|
|
77
92
|
|
|
78
93
|
markdown_report="${MCP_GUARD_OUTPUT_DIR}/mcp-guard-report.md"
|
|
79
94
|
html_report="${MCP_GUARD_OUTPUT_DIR}/mcp-guard-report.html"
|
|
80
95
|
json_report="${MCP_GUARD_OUTPUT_DIR}/mcp-guard-report.json"
|
|
81
96
|
sarif_report="${MCP_GUARD_OUTPUT_DIR}/mcp-guard.sarif"
|
|
97
|
+
comment_report="${MCP_GUARD_OUTPUT_DIR}/mcp-guard-pr-comment.md"
|
|
82
98
|
|
|
83
99
|
node "${guard_bin}" scan "${scan_args[@]}" --format markdown --output "${markdown_report}" --fail-on none
|
|
84
100
|
node "${guard_bin}" scan "${scan_args[@]}" --format html --output "${html_report}" --fail-on none
|
|
85
101
|
node "${guard_bin}" scan "${scan_args[@]}" --format json --output "${json_report}" --fail-on none
|
|
86
102
|
node "${guard_bin}" scan "${scan_args[@]}" --format sarif --output "${sarif_report}" --fail-on none
|
|
103
|
+
node "${GITHUB_ACTION_PATH}/scripts/action-comment.js" \
|
|
104
|
+
"${json_report}" \
|
|
105
|
+
"${markdown_report}" \
|
|
106
|
+
"${html_report}" \
|
|
107
|
+
"${sarif_report}" \
|
|
108
|
+
"${MCP_GUARD_FAIL_ON}" > "${comment_report}"
|
|
87
109
|
|
|
88
110
|
set +e
|
|
89
111
|
node "${guard_bin}" scan "${scan_args[@]}" --fail-on "${MCP_GUARD_FAIL_ON}"
|
|
@@ -95,6 +117,7 @@ runs:
|
|
|
95
117
|
echo "html-report=${html_report}"
|
|
96
118
|
echo "json-report=${json_report}"
|
|
97
119
|
echo "sarif-report=${sarif_report}"
|
|
120
|
+
echo "comment-report=${comment_report}"
|
|
98
121
|
echo "exit-code=${status}"
|
|
99
122
|
} >> "${GITHUB_OUTPUT}"
|
|
100
123
|
|
|
@@ -111,6 +134,43 @@ runs:
|
|
|
111
134
|
"${{ steps.reports.outputs.sarif-report }}" \
|
|
112
135
|
"${MCP_GUARD_FAIL_ON}" >> "${GITHUB_STEP_SUMMARY}"
|
|
113
136
|
|
|
137
|
+
- name: Comment on pull request
|
|
138
|
+
if: ${{ always() && inputs.comment-pr == 'true' && github.event_name == 'pull_request' && steps.reports.outputs.comment-report != '' }}
|
|
139
|
+
uses: actions/github-script@v7
|
|
140
|
+
env:
|
|
141
|
+
MCP_GUARD_COMMENT_PATH: ${{ steps.reports.outputs.comment-report }}
|
|
142
|
+
with:
|
|
143
|
+
script: |
|
|
144
|
+
const fs = require('fs');
|
|
145
|
+
const marker = '<!-- mcp-guard-comment -->';
|
|
146
|
+
const body = fs.readFileSync(process.env.MCP_GUARD_COMMENT_PATH, 'utf8');
|
|
147
|
+
const issue_number = context.payload.pull_request.number;
|
|
148
|
+
const { owner, repo } = context.repo;
|
|
149
|
+
const comments = await github.rest.issues.listComments({
|
|
150
|
+
owner,
|
|
151
|
+
repo,
|
|
152
|
+
issue_number,
|
|
153
|
+
per_page: 100
|
|
154
|
+
});
|
|
155
|
+
const previous = comments.data.find((comment) =>
|
|
156
|
+
comment.user?.type === 'Bot' && comment.body?.includes(marker)
|
|
157
|
+
);
|
|
158
|
+
if (previous) {
|
|
159
|
+
await github.rest.issues.updateComment({
|
|
160
|
+
owner,
|
|
161
|
+
repo,
|
|
162
|
+
comment_id: previous.id,
|
|
163
|
+
body
|
|
164
|
+
});
|
|
165
|
+
} else {
|
|
166
|
+
await github.rest.issues.createComment({
|
|
167
|
+
owner,
|
|
168
|
+
repo,
|
|
169
|
+
issue_number,
|
|
170
|
+
body
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
114
174
|
- name: Upload report artifact
|
|
115
175
|
if: ${{ always() && inputs.upload-artifact == 'true' }}
|
|
116
176
|
uses: actions/upload-artifact@v4
|
package/docs/baseline.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Baseline and Allowlist
|
|
2
|
+
|
|
3
|
+
Use a baseline when a team already has known MCP findings but wants CI to block only new risk.
|
|
4
|
+
|
|
5
|
+
The baseline is local JSON. It stores stable finding fingerprints plus enough context for review. Matching findings are marked as accepted and are excluded from `--fail-on`.
|
|
6
|
+
|
|
7
|
+
## Create a Baseline
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mcp-guard scan \
|
|
11
|
+
--config .mcp.json \
|
|
12
|
+
--write-baseline .mcp-guard-baseline.json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Commit the baseline with the MCP config if the accepted findings are intentional.
|
|
16
|
+
|
|
17
|
+
## Enforce Only New Findings
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
mcp-guard scan \
|
|
21
|
+
--config .mcp.json \
|
|
22
|
+
--baseline .mcp-guard-baseline.json \
|
|
23
|
+
--fail-on high
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If the scan finds only baseline-accepted findings, the exit code is `0`. If a new high or critical finding appears, the exit code is `2`.
|
|
27
|
+
|
|
28
|
+
`--allowlist` and `--write-allowlist` are aliases for teams that prefer that wording.
|
|
29
|
+
|
|
30
|
+
## GitHub Action
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
34
|
+
with:
|
|
35
|
+
config: .mcp.json
|
|
36
|
+
baseline: .mcp-guard-baseline.json
|
|
37
|
+
fail-on: high
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The generated Markdown, HTML, JSON, and PR comment separate active findings from accepted baseline findings.
|
|
41
|
+
|
|
42
|
+
## Baseline Format
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"version": 1,
|
|
47
|
+
"generatedAt": "2026-05-10T00:00:00.000Z",
|
|
48
|
+
"toolVersion": "0.4.0",
|
|
49
|
+
"findings": [
|
|
50
|
+
{
|
|
51
|
+
"fingerprint": "mcpg_a009b2c2",
|
|
52
|
+
"id": "MCP010",
|
|
53
|
+
"severity": "critical",
|
|
54
|
+
"serverName": "shell-installer",
|
|
55
|
+
"configPath": ".mcp.json",
|
|
56
|
+
"title": "Shell command executes inline script",
|
|
57
|
+
"evidence": "command=bash args=-c curl https://example.com/install.sh | bash",
|
|
58
|
+
"acceptedAt": "2026-05-10T00:00:00.000Z",
|
|
59
|
+
"reason": "Accepted current MCP findings"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Review Guidance
|
|
66
|
+
|
|
67
|
+
- Treat the baseline like code. Review changes in pull requests.
|
|
68
|
+
- Keep the reason field specific when accepting high or critical findings.
|
|
69
|
+
- Regenerate the baseline only after reviewing why findings changed.
|
|
70
|
+
- Do not use a baseline to hide unknown third-party tools or broad filesystem access from reviewers.
|
|
@@ -4,31 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
`mcp-guard` is the local-first security scanner for teams adopting AI agents and MCP servers.
|
|
6
6
|
|
|
7
|
-
The business is not the open-source CLI alone. The CLI creates trust and distribution. Near-term validation comes from early users running the scanner on real setups. Revenue can
|
|
7
|
+
The business is not the open-source CLI alone. The CLI creates trust and distribution. Near-term validation comes from early users running the scanner on real setups. Revenue can start with setup help and team workflow integration before offering broader manual audits.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Near-Term Paid Offer
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
MCP Guard CI Setup Sprint.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
This is setup and product onboarding, not a manual security audit.
|
|
14
14
|
|
|
15
15
|
Deliverables:
|
|
16
16
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- optional PR with safer config changes.
|
|
17
|
+
- install the CLI and GitHub Action;
|
|
18
|
+
- generate Markdown, HTML, JSON, and SARIF reports;
|
|
19
|
+
- create an initial baseline for accepted known findings;
|
|
20
|
+
- enable PR comments and optional SARIF upload;
|
|
21
|
+
- document missing rule requests for future product work;
|
|
22
|
+
- provide a short setup handoff note.
|
|
24
23
|
|
|
25
24
|
## Pricing
|
|
26
25
|
|
|
27
26
|
| Customer | Price |
|
|
28
27
|
| --- | ---: |
|
|
29
|
-
| Solo founder / indie team | USD
|
|
30
|
-
| Small startup | USD
|
|
31
|
-
| Funded team / private deployment pilot | USD
|
|
28
|
+
| Solo founder / indie team | USD 199-500 |
|
|
29
|
+
| Small startup | USD 750-2,000 |
|
|
30
|
+
| Funded team / private deployment pilot | USD 2,000-5,000 |
|
|
32
31
|
|
|
33
32
|
## Outreach Copy
|
|
34
33
|
|
package/docs/github-action.md
CHANGED
|
@@ -4,6 +4,8 @@ Use the `mcp-guard` action to scan MCP and AI agent tool configuration in pull r
|
|
|
4
4
|
|
|
5
5
|
The action runs the CLI from the pinned GitHub Action tag, generates Markdown, HTML, JSON, and SARIF reports, writes a job summary, uploads reports as an artifact, and fails the job when findings meet your selected severity threshold.
|
|
6
6
|
|
|
7
|
+
It can also use a committed baseline to accept known findings and optionally post a pull request comment with only the active findings.
|
|
8
|
+
|
|
7
9
|
Marketplace/action repository: <https://github.com/ChaoYue0307/mcp-guard-action>
|
|
8
10
|
|
|
9
11
|
## Basic Workflow
|
|
@@ -18,15 +20,18 @@ on:
|
|
|
18
20
|
|
|
19
21
|
permissions:
|
|
20
22
|
contents: read
|
|
23
|
+
pull-requests: write
|
|
21
24
|
|
|
22
25
|
jobs:
|
|
23
26
|
scan:
|
|
24
27
|
runs-on: ubuntu-latest
|
|
25
28
|
steps:
|
|
26
29
|
- uses: actions/checkout@v4
|
|
27
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
30
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
28
31
|
with:
|
|
32
|
+
config: .mcp.json
|
|
29
33
|
fail-on: high
|
|
34
|
+
comment-pr: "true"
|
|
30
35
|
```
|
|
31
36
|
|
|
32
37
|
## Upload SARIF to GitHub Security
|
|
@@ -50,7 +55,7 @@ jobs:
|
|
|
50
55
|
runs-on: ubuntu-latest
|
|
51
56
|
steps:
|
|
52
57
|
- uses: actions/checkout@v4
|
|
53
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
58
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
54
59
|
with:
|
|
55
60
|
config: .mcp.json
|
|
56
61
|
fail-on: high
|
|
@@ -62,17 +67,39 @@ jobs:
|
|
|
62
67
|
Use `fail-on: none` when you want artifacts and summaries without blocking a pull request.
|
|
63
68
|
|
|
64
69
|
```yaml
|
|
65
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
70
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
66
71
|
with:
|
|
67
72
|
fail-on: none
|
|
68
73
|
```
|
|
69
74
|
|
|
75
|
+
## Baseline Mode
|
|
76
|
+
|
|
77
|
+
Use a baseline when you want to accept known findings and fail only on new risk.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
mcp-guard scan --config .mcp.json --write-baseline .mcp-guard-baseline.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Commit `.mcp-guard-baseline.json`, then reference it from the action:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
87
|
+
with:
|
|
88
|
+
config: .mcp.json
|
|
89
|
+
baseline: .mcp-guard-baseline.json
|
|
90
|
+
fail-on: high
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Reports will show active findings separately from findings accepted by the baseline.
|
|
94
|
+
|
|
70
95
|
## Inputs
|
|
71
96
|
|
|
72
97
|
| Input | Default | Description |
|
|
73
98
|
| --- | --- | --- |
|
|
74
99
|
| `config` | empty | Optional MCP config path. Empty scans default project and user config locations. |
|
|
75
100
|
| `fail-on` | `high` | Fails the job for `critical`, `high`, `medium`, or `low` findings. Use `none` for report-only mode. |
|
|
101
|
+
| `baseline` | empty | Optional baseline/allowlist JSON path. Matching findings are accepted and do not fail the workflow. |
|
|
102
|
+
| `comment-pr` | `false` | Posts or updates a pull request comment with the scan summary. Requires `pull-requests: write`. |
|
|
76
103
|
| `output-dir` | `mcp-guard-report` | Directory for generated reports. |
|
|
77
104
|
| `upload-artifact` | `true` | Uploads generated reports as a workflow artifact. |
|
|
78
105
|
| `upload-sarif` | `false` | Uploads SARIF to GitHub code scanning. Requires `security-events: write`. |
|
|
@@ -86,4 +113,5 @@ Use `fail-on: none` when you want artifacts and summaries without blocking a pul
|
|
|
86
113
|
| `html-report` | Path to the generated HTML report. |
|
|
87
114
|
| `json-report` | Path to the generated JSON report. |
|
|
88
115
|
| `sarif-report` | Path to the generated SARIF report. |
|
|
116
|
+
| `comment-report` | Path to the generated pull request comment body. |
|
|
89
117
|
| `exit-code` | `0` when below threshold, `2` when findings met the threshold. |
|
package/docs/launch-checklist.md
CHANGED
|
@@ -31,9 +31,12 @@ mcp-guard scan --config .mcp.json --fail-on high
|
|
|
31
31
|
## GitHub Action Setup
|
|
32
32
|
|
|
33
33
|
```yaml
|
|
34
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
34
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
35
35
|
with:
|
|
36
|
+
config: .mcp.json
|
|
37
|
+
baseline: .mcp-guard-baseline.json
|
|
36
38
|
fail-on: high
|
|
39
|
+
comment-pr: "true"
|
|
37
40
|
upload-sarif: "true"
|
|
38
41
|
```
|
|
39
42
|
|
|
@@ -16,15 +16,18 @@ on:
|
|
|
16
16
|
|
|
17
17
|
permissions:
|
|
18
18
|
contents: read
|
|
19
|
+
pull-requests: write
|
|
19
20
|
|
|
20
21
|
jobs:
|
|
21
22
|
scan:
|
|
22
23
|
runs-on: ubuntu-latest
|
|
23
24
|
steps:
|
|
24
25
|
- uses: actions/checkout@v4
|
|
25
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
26
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
26
27
|
with:
|
|
28
|
+
config: .mcp.json
|
|
27
29
|
fail-on: high
|
|
30
|
+
comment-pr: "true"
|
|
28
31
|
```
|
|
29
32
|
|
|
30
33
|
## Upload SARIF to GitHub Security
|
|
@@ -39,7 +42,7 @@ jobs:
|
|
|
39
42
|
runs-on: ubuntu-latest
|
|
40
43
|
steps:
|
|
41
44
|
- uses: actions/checkout@v4
|
|
42
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
45
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
43
46
|
with:
|
|
44
47
|
config: .mcp.json
|
|
45
48
|
fail-on: high
|
|
@@ -52,6 +55,8 @@ jobs:
|
|
|
52
55
|
| --- | --- | --- |
|
|
53
56
|
| `config` | empty | Optional MCP config path. Empty scans default project and user config locations. |
|
|
54
57
|
| `fail-on` | `high` | Fails the job for `critical`, `high`, `medium`, or `low` findings. Use `none` for report-only mode. |
|
|
58
|
+
| `baseline` | empty | Optional baseline/allowlist JSON path. Matching findings are accepted and do not fail the workflow. |
|
|
59
|
+
| `comment-pr` | `false` | Posts or updates a pull request comment with the scan summary. Requires `pull-requests: write`. |
|
|
55
60
|
| `output-dir` | `mcp-guard-report` | Directory for generated reports. |
|
|
56
61
|
| `upload-artifact` | `true` | Uploads generated reports as a workflow artifact. |
|
|
57
62
|
| `upload-sarif` | `false` | Uploads SARIF to GitHub code scanning. Requires `security-events: write`. |
|
|
@@ -65,6 +70,7 @@ jobs:
|
|
|
65
70
|
| `html-report` | Path to the generated HTML report. |
|
|
66
71
|
| `json-report` | Path to the generated JSON report. |
|
|
67
72
|
| `sarif-report` | Path to the generated SARIF report. |
|
|
73
|
+
| `comment-report` | Path to the generated pull request comment body. |
|
|
68
74
|
| `exit-code` | `0` when below threshold, `2` when findings met the threshold. |
|
|
69
75
|
|
|
70
76
|
## Reports
|
|
@@ -78,14 +84,38 @@ The action generates:
|
|
|
78
84
|
|
|
79
85
|
Secret-like values are redacted before reports are written.
|
|
80
86
|
|
|
87
|
+
## Baseline Mode
|
|
88
|
+
|
|
89
|
+
Generate and commit a baseline when existing MCP risk is known and accepted:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
mcp-guard scan --config .mcp.json --write-baseline .mcp-guard-baseline.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Then enforce only new findings:
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
99
|
+
with:
|
|
100
|
+
config: .mcp.json
|
|
101
|
+
baseline: .mcp-guard-baseline.json
|
|
102
|
+
fail-on: high
|
|
103
|
+
```
|
|
104
|
+
|
|
81
105
|
## Transparent Example
|
|
82
106
|
|
|
83
107
|
Inspect a committed input config, reproduction commands, and generated Markdown, HTML, JSON, and SARIF artifacts:
|
|
84
108
|
|
|
85
109
|
https://chaoyue0307.github.io/mcp-guard/e2e/
|
|
86
110
|
|
|
111
|
+
Inspect a live GitHub Action demo pull request that intentionally fails on risky MCP config:
|
|
112
|
+
|
|
113
|
+
https://github.com/ChaoYue0307/mcp-guard-demo/pull/1
|
|
114
|
+
|
|
87
115
|
## Links
|
|
88
116
|
|
|
89
117
|
- Product site: https://chaoyue0307.github.io/mcp-guard/
|
|
118
|
+
- Marketplace listing: https://github.com/marketplace/actions/mcp-guard-mcp-security-scanner
|
|
119
|
+
- Live demo repository: https://github.com/ChaoYue0307/mcp-guard-demo
|
|
90
120
|
- Main repository: https://github.com/ChaoYue0307/mcp-guard
|
|
91
121
|
- npm package: https://www.npmjs.com/package/agent-mcp-guard
|
package/docs/marketplace.md
CHANGED
|
@@ -82,17 +82,19 @@ Code quality
|
|
|
82
82
|
Release title:
|
|
83
83
|
|
|
84
84
|
```text
|
|
85
|
-
v0.
|
|
85
|
+
v0.4.0
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Release notes:
|
|
89
89
|
|
|
90
90
|
```text
|
|
91
|
-
|
|
91
|
+
Baseline and pull request comment release.
|
|
92
92
|
|
|
93
93
|
- Runs mcp-guard from the pinned action tag.
|
|
94
94
|
- Generates Markdown, HTML, JSON, and SARIF reports.
|
|
95
95
|
- Writes a GitHub Step Summary for pull request review.
|
|
96
|
+
- Supports baseline/allowlist files so known accepted findings do not fail CI.
|
|
97
|
+
- Can post or update a pull request comment with active findings.
|
|
96
98
|
- Can upload SARIF to GitHub code scanning with `upload-sarif: "true"`.
|
|
97
99
|
- Fails workflows by configurable severity threshold.
|
|
98
100
|
```
|
|
@@ -103,11 +105,11 @@ Completed:
|
|
|
103
105
|
|
|
104
106
|
- Public repository created: <https://github.com/ChaoYue0307/mcp-guard-action>
|
|
105
107
|
- `dist/mcp-guard-action/` exported, committed, and pushed.
|
|
106
|
-
- Release created: <https://github.com/ChaoYue0307/mcp-guard-action/releases/tag/v0.
|
|
108
|
+
- Release created: <https://github.com/ChaoYue0307/mcp-guard-action/releases/tag/v0.4.0>
|
|
107
109
|
- README, docs, and website examples now use:
|
|
108
110
|
|
|
109
111
|
```yaml
|
|
110
|
-
- uses: ChaoYue0307/mcp-guard-action@v0.
|
|
112
|
+
- uses: ChaoYue0307/mcp-guard-action@v0.4.0
|
|
111
113
|
```
|
|
112
114
|
|
|
113
115
|
Remaining Marketplace web step:
|
package/docs/roadmap.md
CHANGED
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
- Rules for shell wrappers, remote package runners, unpinned packages, broad filesystem access, secret-like env vars/headers, and remote MCP URLs.
|
|
10
10
|
- CI usage with `--fail-on`.
|
|
11
11
|
- GitHub Action wrapper that writes a job summary, uploads Markdown/HTML/JSON/SARIF artifacts, and can upload SARIF to GitHub code scanning.
|
|
12
|
+
- Baseline/allowlist mode for accepting known findings and failing only on new risks.
|
|
13
|
+
- Optional GitHub pull request comments from the Marketplace Action.
|
|
12
14
|
|
|
13
15
|
## Next
|
|
14
16
|
|
|
15
17
|
1. More MCP client discovery paths.
|
|
16
18
|
2. Rule packs mapped to MCP security best practices.
|
|
17
19
|
3. Policy file for approved commands, packages, directories, and remote URLs.
|
|
18
|
-
4.
|
|
19
|
-
5.
|
|
20
|
+
4. `mcp-guard audit` mode for review-ready reports.
|
|
21
|
+
5. Safer default remediation snippets for common MCP servers.
|
|
20
22
|
|
|
21
23
|
## Later
|
|
22
24
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# mcp-guard Scan Report
|
|
2
2
|
|
|
3
|
-
Generated: 2026-05-
|
|
3
|
+
Generated: 2026-05-10T12:58:03.265Z
|
|
4
4
|
|
|
5
5
|
## Summary
|
|
6
6
|
|
|
7
7
|
- Scanned files: 1
|
|
8
8
|
- MCP servers: 3
|
|
9
|
-
-
|
|
9
|
+
- Active findings: 9
|
|
10
10
|
- Risk score: 98
|
|
11
11
|
- Critical: 2
|
|
12
12
|
- High: 5
|
|
@@ -25,19 +25,19 @@ Generated: 2026-05-10T06:56:59.977Z
|
|
|
25
25
|
| shell-installer | bash | -c curl https://example.com/install.sh \| bash | - | - | - |
|
|
26
26
|
| remote-prod | - | - | - | https://mcp.example.com/sse | - |
|
|
27
27
|
|
|
28
|
-
## Findings
|
|
29
|
-
|
|
30
|
-
| Severity | Rule | Server | Finding | Evidence | Recommendation |
|
|
31
|
-
| --- | --- | --- | --- | --- | --- |
|
|
32
|
-
| critical | MCP010 | shell-installer | Shell command executes inline script | command=bash args=-c curl https://example.com/install.sh \| bash | Use a direct, pinned executable instead of a shell wrapper. If a shell is required, place the script in source control and review it. |
|
|
33
|
-
| critical | MCP050 | shell-installer | MCP server command includes a dangerous operation | curl pipe to shell | Remove the dangerous operation from MCP startup. Run destructive setup steps manually and review them separately. |
|
|
34
|
-
| high | MCP021 | filesystem-all-home | Remote MCP package is not version pinned | package=@modelcontextprotocol/server-filesystem | Pin the package to an exact version such as package@1.2.3 and review updates before changing it. |
|
|
35
|
-
| high | MCP030 | filesystem-all-home | Secret-like environment variable is exposed to MCP server | GITHUB_TOKEN=ghp...890 (32 chars) | Pass the least privileged token possible. Prefer scoped tokens, short-lived credentials, and a dedicated service account. |
|
|
36
|
-
| high | MCP040 | filesystem-all-home | MCP server has a broad working directory | cwd=/ | Run the server in a narrow project directory or sandbox with only the files it needs. |
|
|
37
|
-
| high | MCP041 | filesystem-all-home | MCP server argument grants broad filesystem access | arg=/ | Replace broad filesystem paths with a dedicated project folder or read-only sandbox path. |
|
|
38
|
-
| high | MCP061 | remote-prod | Secret-like header is configured for remote MCP server | Authorization=Bea...ken (27 chars) | Use scoped, short-lived credentials and avoid placing long-lived secrets directly in MCP config files. |
|
|
39
|
-
| medium | MCP020 | filesystem-all-home | MCP server is launched through a remote package runner | command=npx package=@modelcontextprotocol/server-filesystem | Pin the package version, review the package source, and prefer a local lockfile or vendored executable for sensitive tools. |
|
|
40
|
-
| medium | MCP060 | remote-prod | Remote MCP server URL is configured | url=https://mcp.example.com/sse | Verify the provider, use HTTPS, document the data sent to this server, and keep an allowlist of approved remote endpoints. |
|
|
28
|
+
## Active Findings
|
|
29
|
+
|
|
30
|
+
| Severity | Rule | Server | Finding | Evidence | Fingerprint | Recommendation |
|
|
31
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
32
|
+
| critical | MCP010 | shell-installer | Shell command executes inline script | command=bash args=-c curl https://example.com/install.sh \| bash | mcpg_a009b2c2 | Use a direct, pinned executable instead of a shell wrapper. If a shell is required, place the script in source control and review it. |
|
|
33
|
+
| critical | MCP050 | shell-installer | MCP server command includes a dangerous operation | curl pipe to shell | mcpg_6bd13204 | Remove the dangerous operation from MCP startup. Run destructive setup steps manually and review them separately. |
|
|
34
|
+
| high | MCP021 | filesystem-all-home | Remote MCP package is not version pinned | package=@modelcontextprotocol/server-filesystem | mcpg_d0af49fa | Pin the package to an exact version such as package@1.2.3 and review updates before changing it. |
|
|
35
|
+
| high | MCP030 | filesystem-all-home | Secret-like environment variable is exposed to MCP server | GITHUB_TOKEN=ghp...890 (32 chars) | mcpg_a5f382b0 | Pass the least privileged token possible. Prefer scoped tokens, short-lived credentials, and a dedicated service account. |
|
|
36
|
+
| high | MCP040 | filesystem-all-home | MCP server has a broad working directory | cwd=/ | mcpg_31aaa689 | Run the server in a narrow project directory or sandbox with only the files it needs. |
|
|
37
|
+
| high | MCP041 | filesystem-all-home | MCP server argument grants broad filesystem access | arg=/ | mcpg_dbc08d76 | Replace broad filesystem paths with a dedicated project folder or read-only sandbox path. |
|
|
38
|
+
| high | MCP061 | remote-prod | Secret-like header is configured for remote MCP server | Authorization=Bea...ken (27 chars) | mcpg_5abd4cbd | Use scoped, short-lived credentials and avoid placing long-lived secrets directly in MCP config files. |
|
|
39
|
+
| medium | MCP020 | filesystem-all-home | MCP server is launched through a remote package runner | command=npx package=@modelcontextprotocol/server-filesystem | mcpg_a3493a53 | Pin the package version, review the package source, and prefer a local lockfile or vendored executable for sensitive tools. |
|
|
40
|
+
| medium | MCP060 | remote-prod | Remote MCP server URL is configured | url=https://mcp.example.com/sse | mcpg_cf1296e4 | Verify the provider, use HTTPS, document the data sent to this server, and keep an allowlist of approved remote endpoints. |
|
|
41
41
|
|
|
42
42
|
## Notes
|
|
43
43
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-mcp-guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Open-source CLI scanner for risky MCP server and AI agent tool configuration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://chaoyue0307.github.io/mcp-guard/",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"README.md",
|
|
46
46
|
"action.yml",
|
|
47
47
|
"scripts/action-summary.js",
|
|
48
|
+
"scripts/action-comment.js",
|
|
48
49
|
"scripts/prepare-marketplace-action.js",
|
|
49
50
|
"LICENSE",
|
|
50
51
|
"SECURITY.md",
|