-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathTaskfile.yml
More file actions
452 lines (409 loc) · 15.7 KB
/
Taskfile.yml
File metadata and controls
452 lines (409 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
version: '3'
tasks:
scan:
desc: "Run security scan on a specific MCP server"
summary: |
Run Cisco AI Defense mcp-scanner on a specific MCP server configuration.
Usage:
task scan -- npx/browserbase-mcp-server
task scan -- uvx/blender-mcp
task scan -- npx/sentry-mcp-server
The server path should be relative to the project root and contain a spec.yaml file.
Environment variables:
MCP_SCANNER_ENABLE_LLM=true - Enable LLM analyzer (requires API key)
MCP_SCANNER_LLM_API_KEY - API key for LLM service
requires:
vars: [CLI_ARGS]
vars:
SERVER_PATH: '{{.CLI_ARGS}}'
PROTOCOL:
sh: echo "{{.SERVER_PATH}}" | cut -d'/' -f1
SERVER_NAME:
sh: echo "{{.SERVER_PATH}}" | cut -d'/' -f2
cmds:
- |
if [ ! -f "{{.SERVER_PATH}}/spec.yaml" ]; then
echo "❌ Error: spec.yaml not found at {{.SERVER_PATH}}/spec.yaml"
exit 1
fi
- 'echo "🔍 Scanning MCP server: {{.SERVER_NAME}} ({{.PROTOCOL}})"'
- |
# Generate config (outputs JSON with command/args)
config_json=$(python3 scripts/mcp-scan/generate_mcp_config.py \
"{{.SERVER_PATH}}/spec.yaml" \
"{{.PROTOCOL}}" \
"{{.SERVER_NAME}}")
command=$(echo "$config_json" | jq -r '.command')
args=$(echo "$config_json" | jq -r '.args')
# Run scan using Cisco AI Defense mcp-scanner
# Note: stderr is redirected to a separate file to avoid corrupting JSON output
python3 scripts/mcp-scan/run_scan.py "$command" "$args" \
> "/tmp/mcp-scan-{{.SERVER_NAME}}.json" 2> "/tmp/mcp-scan-{{.SERVER_NAME}}.stderr" || true
# Show stderr if it exists (for debugging)
if [ -s "/tmp/mcp-scan-{{.SERVER_NAME}}.stderr" ]; then
echo "Scanner stderr:"
cat "/tmp/mcp-scan-{{.SERVER_NAME}}.stderr"
fi
- |
python3 scripts/mcp-scan/process_scan_results.py \
"/tmp/mcp-scan-{{.SERVER_NAME}}.json" \
"{{.SERVER_NAME}}" \
"{{.SERVER_PATH}}/spec.yaml"
- echo "✅ Scan completed for {{.SERVER_NAME}}"
- 'echo "📄 Raw results: /tmp/mcp-scan-{{.SERVER_NAME}}.json"'
scan-all:
desc: "Run security scan on all MCP servers"
summary: |
Run Cisco AI Defense mcp-scanner on all MCP server configurations found in the project.
This will scan all spec.yaml files found in:
- npx/*/spec.yaml
- uvx/*/spec.yaml
- go/*/spec.yaml
cmds:
- |
echo "🔍 Discovering all MCP server configurations..."
configs=$(find npx uvx go -name "spec.yaml" -type f 2>/dev/null | sort)
if [ -z "$configs" ]; then
echo "❌ No MCP server configurations found"
exit 1
fi
echo "📋 Found configurations:"
echo "$configs" | sed 's/^/ - /'
echo ""
total=$(echo "$configs" | wc -l)
current=0
for config in $configs; do
current=$((current + 1))
server_dir=$(dirname "$config")
echo "🔍 [$current/$total] Scanning: $server_dir"
task scan -- "$server_dir" || echo "⚠️ Scan failed for $server_dir"
echo ""
done
echo "✅ All scans completed!"
scan-setup:
desc: "Setup Cisco AI Defense mcp-scanner"
summary: |
Install and setup the Cisco AI Defense mcp-scanner tool.
This only needs to be run once or when the tool needs updating.
Set MCP_SCANNER_ENABLE_LLM=true for LLM analysis (requires API key).
cmds:
- echo "🔧 Setting up Cisco AI Defense mcp-scanner..."
- uv tool install cisco-ai-mcp-scanner
- echo "✅ mcp-scanner setup completed"
- echo "ℹ️ Set MCP_SCANNER_ENABLE_LLM=true for LLM analysis"
- mcp-scanner --help || true
scan-clean:
desc: "Clean up temporary scan files"
summary: |
Remove temporary files created during security scans.
cmds:
- echo "🧹 Cleaning up temporary scan files..."
- rm -f /tmp/*mcp-config.json /tmp/mcp-scan-*.json /tmp/mcp-scan-storage
- echo "✅ Cleanup completed"
scan-help:
desc: "Show help for security scanning tasks"
summary: |
Display detailed help and examples for using the security scanning tasks.
cmds:
- |
echo "🔒 MCP Security Scanning Tasks (Cisco AI Defense)"
echo "=================================================="
echo ""
echo "Available tasks:"
echo " scan - Run security scan on a specific server"
echo " scan-all - Run security scan on all servers"
echo " scan-setup - Setup mcp-scanner tool (run once)"
echo " scan-clean - Clean up temporary files"
echo " scan-help - Show this help"
echo ""
echo "Examples:"
echo " task scan -- npx/browserbase-mcp-server"
echo " task scan -- uvx/blender-mcp"
echo " task scan-all"
echo " task scan-setup"
echo ""
echo "Environment variables:"
echo " MCP_SCANNER_ENABLE_LLM=true - Enable LLM analyzer"
echo " MCP_SCANNER_LLM_API_KEY - API key for LLM service"
echo ""
echo "The scan results will show:"
echo " ✅ - No security issues found"
echo " ❌ - Security issues found (not allowlisted)"
echo " ⚠️ - Security issues found but allowlisted"
echo ""
echo "Issue codes use AITech taxonomy (e.g., AITech-8.2 for data exposure)"
echo "For detailed analysis, check the raw JSON output files in /tmp/"
build:
desc: "Generate Dockerfile from MCP server spec"
summary: |
Generate a Dockerfile from an MCP server specification.
Usage:
task build -- npx/context7
task build -- uvx/mcp-clickhouse
task build -- go/my-go-server
The server path should be relative to the project root and contain a spec.yaml file.
Output will be written to stdout by default.
requires:
vars: [CLI_ARGS]
vars:
SERVER_PATH: '{{.CLI_ARGS}}'
SPEC_FILE: '{{.SERVER_PATH}}/spec.yaml'
cmds:
- |
if [ ! -f "{{.SPEC_FILE}}" ]; then
echo "❌ Error: spec.yaml not found at {{.SPEC_FILE}}"
exit 1
fi
- echo "🏗️ Generating Dockerfile for {{.SERVER_PATH}}"
- build/dockhand build -c "{{.SPEC_FILE}}"
build-file:
desc: "Generate Dockerfile from MCP server spec and save to file"
summary: |
Generate a Dockerfile from an MCP server specification and save to a file.
Usage:
task build-file -- npx/context7 Dockerfile
task build-file -- uvx/mcp-clickhouse my-dockerfile
Arguments:
1. Server path (e.g., npx/context7)
2. Output file path (e.g., Dockerfile)
requires:
vars: [CLI_ARGS]
vars:
ARGS: '{{.CLI_ARGS}}'
SERVER_PATH:
sh: echo "{{.ARGS}}" | cut -d' ' -f1
OUTPUT_FILE:
sh: echo "{{.ARGS}}" | cut -d' ' -f2
SPEC_FILE: '{{.SERVER_PATH}}/spec.yaml'
cmds:
- |
if [ ! -f "{{.SPEC_FILE}}" ]; then
echo "❌ Error: spec.yaml not found at {{.SPEC_FILE}}"
exit 1
fi
- |
if [ -z "{{.OUTPUT_FILE}}" ]; then
echo "❌ Error: Output file not specified"
echo "Usage: task build-file -- <server-path> <output-file>"
exit 1
fi
- echo "🏗️ Generating Dockerfile for {{.SERVER_PATH}} → {{.OUTPUT_FILE}}"
- build/dockhand build -c "{{.SPEC_FILE}}" -o "{{.OUTPUT_FILE}}"
- echo "✅ Dockerfile saved to {{.OUTPUT_FILE}}"
build-tag:
desc: "Generate Dockerfile with custom tag"
summary: |
Generate a Dockerfile from an MCP server specification with a custom tag.
Usage:
task build-tag -- npx/context7 my-custom-tag:latest
task build-tag -- uvx/mcp-clickhouse myregistry/image:v1.0.0
Arguments:
1. Server path (e.g., npx/context7)
2. Custom tag (e.g., my-custom-tag:latest)
requires:
vars: [CLI_ARGS]
vars:
ARGS: '{{.CLI_ARGS}}'
SERVER_PATH:
sh: echo "{{.ARGS}}" | cut -d' ' -f1
CUSTOM_TAG:
sh: echo "{{.ARGS}}" | cut -d' ' -f2-
SPEC_FILE: '{{.SERVER_PATH}}/spec.yaml'
cmds:
- |
if [ ! -f "{{.SPEC_FILE}}" ]; then
echo "❌ Error: spec.yaml not found at {{.SPEC_FILE}}"
exit 1
fi
- |
if [ -z "{{.CUSTOM_TAG}}" ]; then
echo "❌ Error: Custom tag not specified"
echo "Usage: task build-tag -- <server-path> <custom-tag>"
exit 1
fi
- echo "🏗️ Generating Dockerfile for {{.SERVER_PATH}} with tag {{.CUSTOM_TAG}}"
- build/dockhand build -c "{{.SPEC_FILE}}" -t "{{.CUSTOM_TAG}}"
test-build:
desc: "Test build an MCP server container"
summary: |
Generate Dockerfile and build a container image for testing.
Usage:
task test-build -- npx/context7
task test-build -- uvx/mcp-clickhouse
This will:
1. Generate a Dockerfile
2. Build the container image
3. Test that the container runs
requires:
vars: [CLI_ARGS]
vars:
SERVER_PATH: '{{.CLI_ARGS}}'
PROTOCOL:
sh: echo "{{.SERVER_PATH}}" | cut -d'/' -f1
SERVER_NAME:
sh: echo "{{.SERVER_PATH}}" | cut -d'/' -f2
SPEC_FILE: '{{.SERVER_PATH}}/spec.yaml'
TEST_TAG: 'test-{{.SERVER_NAME}}:latest'
cmds:
- |
if [ ! -f "{{.SPEC_FILE}}" ]; then
echo "❌ Error: spec.yaml not found at {{.SPEC_FILE}}"
exit 1
fi
- echo "🏗️ Testing build for {{.SERVER_PATH}}"
- echo "📝 Generating Dockerfile..."
- build/dockhand build -c "{{.SPEC_FILE}}" -o "Dockerfile.test"
- echo "🔨 Building container image..."
- podman build -t "{{.TEST_TAG}}" -f Dockerfile.test .
- echo "🧪 Testing container..."
- podman run --rm "{{.TEST_TAG}}" --help || echo "⚠️ Container built but --help failed (this may be expected)"
- echo "✅ Test build completed for {{.SERVER_NAME}}"
- echo "🏷️ Image tagged as {{.TEST_TAG}}"
- rm -f Dockerfile.test
build-setup:
desc: "Build and install dockhand CLI"
summary: |
Build the dockhand CLI tool from source.
This needs to be run once or when the tool is updated.
sources:
- "cmd/dockhand/**/*.go"
- "go.mod"
- "go.sum"
generates:
- "build/dockhand"
cmds:
- echo "🔧 Building dockhand CLI..."
- mkdir -p build
- go build -o build/dockhand ./cmd/dockhand
- echo "✅ dockhand CLI built successfully"
- build/dockhand --help
validate-skill:
desc: "Validate a skill from a git repository"
summary: |
Validate a skill specification by cloning the git repo and checking the SKILL.md.
Usage:
task validate-skill -- skills/claude-api
The skill path should be relative to the project root and contain a spec.yaml file.
requires:
vars: [CLI_ARGS]
vars:
SKILL_PATH: '{{.CLI_ARGS}}'
deps: [build-setup]
cmds:
- |
if [ ! -f "{{.SKILL_PATH}}/spec.yaml" ]; then
echo "Error: spec.yaml not found at {{.SKILL_PATH}}/spec.yaml"
exit 1
fi
build/dockhand validate-skill --config "{{.SKILL_PATH}}/spec.yaml"
build-skill:
desc: "Build an OCI skill artifact from a skill specification"
summary: |
Build an OCI skill artifact by cloning a skill from git and packaging it.
Usage:
task build-skill -- skills/claude-api
Add --push to also push to the registry (requires authentication):
PUSH=true task build-skill -- skills/claude-api
requires:
vars: [CLI_ARGS]
vars:
SKILL_PATH: '{{.CLI_ARGS}}'
PUSH: '{{.PUSH | default "false"}}'
deps: [build-setup]
cmds:
- |
if [ ! -f "{{.SKILL_PATH}}/spec.yaml" ]; then
echo "Error: spec.yaml not found at {{.SKILL_PATH}}/spec.yaml"
exit 1
fi
push_flag=""
if [ "{{.PUSH}}" = "true" ]; then
push_flag="--push"
fi
build/dockhand build-skill --config "{{.SKILL_PATH}}/spec.yaml" $push_flag
scan-skill:
desc: "Run skill-scanner on a skill spec (clones source, scans, applies allowlist)"
summary: |
Clone a skill's source at the pinned ref, run Cisco AI Defense
skill-scanner on it, and apply the allowlist from the skill's spec.yaml.
Usage:
task scan-skill -- skills/claude-api
Environment variables:
SKILL_SCANNER_USE_BEHAVIORAL=true - Enable AST/taint analysis
SKILL_SCANNER_USE_LLM=true - Enable LLM analyzer
SKILL_SCANNER_LLM_API_KEY - API key for LLM analyzer
requires:
vars: [CLI_ARGS]
vars:
SKILL_PATH: '{{.CLI_ARGS}}'
SKILL_NAME:
sh: echo "{{.SKILL_PATH}}" | cut -d'/' -f2
SPEC_FILE: '{{.SKILL_PATH}}/spec.yaml'
WORKDIR: '/tmp/skill-scan-{{.SKILL_NAME}}'
cmds:
- |
if [ ! -f "{{.SPEC_FILE}}" ]; then
echo "Error: spec.yaml not found at {{.SPEC_FILE}}"
exit 1
fi
- |
repository=$(yq '.spec.repository' "{{.SPEC_FILE}}")
ref=$(yq '.spec.ref' "{{.SPEC_FILE}}")
skill_path=$(yq '.spec.path // ""' "{{.SPEC_FILE}}")
rm -rf "{{.WORKDIR}}"
mkdir -p "{{.WORKDIR}}"
git clone --filter=tree:0 --no-checkout --quiet "$repository" "{{.WORKDIR}}/repo"
git -C "{{.WORKDIR}}/repo" checkout --quiet "$ref"
if [ -n "$skill_path" ]; then
src_dir="{{.WORKDIR}}/repo/$skill_path"
else
src_dir="{{.WORKDIR}}/repo"
fi
python3 scripts/skill-scan/run_scan.py \
--source "$src_dir" \
--output "{{.WORKDIR}}/scan.json"
python3 scripts/skill-scan/process_scan_results.py \
"{{.WORKDIR}}/scan.json" \
"{{.SKILL_NAME}}" \
"{{.SPEC_FILE}}"
scan-skill-setup:
desc: "Install cisco-ai-skill-scanner via uv"
cmds:
- uv tool install cisco-ai-skill-scanner
- skill-scanner --version || true
build-help:
desc: "Show help for build tasks"
summary: |
Display detailed help and examples for using the build tasks.
cmds:
- |
echo "🏗️ MCP Server Build Tasks"
echo "========================"
echo ""
echo "Available tasks:"
echo " build - Generate Dockerfile to stdout"
echo " build-file - Generate Dockerfile and save to file"
echo " build-tag - Generate Dockerfile with custom tag"
echo " test-build - Generate, build, and test container"
echo " build-setup - Build dockhand CLI tool"
echo " validate-skill - Validate a skill from git"
echo " build-skill - Build an OCI skill artifact"
echo " build-help - Show this help"
echo ""
echo "MCP Server Examples:"
echo " task build -- npx/context7"
echo " task build-file -- npx/context7 Dockerfile"
echo " task build-tag -- uvx/mcp-clickhouse myregistry/image:v1.0.0"
echo " task test-build -- npx/context7"
echo ""
echo "Skill Examples:"
echo " task validate-skill -- skills/claude-api"
echo " task build-skill -- skills/claude-api"
echo " PUSH=true task build-skill -- skills/claude-api"
echo ""
echo "Prerequisites:"
echo " - Run 'task build-setup' first to build the dockhand CLI"
echo " - Ensure podman is running and 'dev' container exists"
echo ""
echo "The generated Dockerfiles can be used with:"
echo " podman build -t my-image:tag -f Dockerfile .