Skip to content

Commit c4292fa

Browse files
committed
feat: initial release — MCP server + CLI for iOS Safari debugging
Go-based MCP server and CLI that speaks WebKit Inspector Protocol natively via ios-webkit-debug-proxy. Covers all 27 WebKit Inspector domains with 100+ MCP tools for AI-driven iOS Safari debugging. Key features: - Target-based message routing for iwdp connections - Network/console/timeline collectors with idempotent start and caps - Full DOM, CSS, Runtime, Debugger, Storage, and Profiling support - Simulator test suite against real Safari - Security: localhost-only WebSocket validation, URL scheme checks
0 parents  commit c4292fa

54 files changed

Lines changed: 12004 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/plugin.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "iwdp-mcp",
3+
"version": "0.1.0",
4+
"description": "iOS Safari debugging via ios-webkit-debug-proxy — MCP server with full WebKit Inspector Protocol support",
5+
"mcpServers": {
6+
"iwdp-mcp": {
7+
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/run.sh"
8+
}
9+
}
10+
}

.github/workflows/lint.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
golangci-lint:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-go@v5
18+
with:
19+
go-version-file: go.mod
20+
21+
- uses: golangci/golangci-lint-action@v7
22+
with:
23+
version: v2.9.0
24+
25+
gofumpt:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- uses: actions/setup-go@v5
31+
with:
32+
go-version-file: go.mod
33+
34+
- name: Install gofumpt
35+
run: go install mvdan.cc/gofumpt@latest
36+
37+
- name: Check formatting
38+
run: |
39+
unformatted=$(gofumpt -l .)
40+
if [ -n "$unformatted" ]; then
41+
echo "Files not formatted with gofumpt:"
42+
echo "$unformatted"
43+
echo ""
44+
echo "Run 'gofumpt -w .' to fix."
45+
exit 1
46+
fi

.github/workflows/release.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
goreleaser:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- uses: actions/setup-go@v5
20+
with:
21+
go-version-file: go.mod
22+
23+
- uses: goreleaser/goreleaser-action@v7
24+
with:
25+
distribution: goreleaser
26+
version: "~> v2"
27+
args: release --clean
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yml

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-go@v5
18+
with:
19+
go-version-file: go.mod
20+
21+
- name: Run tests with coverage
22+
run: go test ./... -v -count=1 -coverprofile=coverage.out
23+
24+
- name: Coverage summary
25+
run: |
26+
total=$(go tool cover -func=coverage.out | tail -1 | awk '{print $NF}')
27+
echo "## Test Coverage" >> "$GITHUB_STEP_SUMMARY"
28+
echo "" >> "$GITHUB_STEP_SUMMARY"
29+
echo "**Total: ${total}**" >> "$GITHUB_STEP_SUMMARY"
30+
echo "" >> "$GITHUB_STEP_SUMMARY"
31+
echo "| Package | Coverage |" >> "$GITHUB_STEP_SUMMARY"
32+
echo "|---------|----------|" >> "$GITHUB_STEP_SUMMARY"
33+
go tool cover -func=coverage.out | grep -v "total:" | awk -F'\t+' '{print $1, $NF}' | sort -u -t' ' -k1,1 | while read -r pkg cov; do
34+
echo "| \`${pkg}\` | ${cov} |" >> "$GITHUB_STEP_SUMMARY"
35+
done
36+
37+
e2e:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- uses: actions/checkout@v4
41+
42+
- uses: actions/setup-go@v5
43+
with:
44+
go-version-file: go.mod
45+
46+
- name: Run e2e tests
47+
run: go test ./e2e/ -v -count=1 -timeout=120s
48+
49+
integration:
50+
runs-on: macos-latest
51+
steps:
52+
- uses: actions/checkout@v4
53+
54+
- uses: actions/setup-go@v5
55+
with:
56+
go-version-file: go.mod
57+
58+
- name: Install ios-webkit-debug-proxy
59+
run: brew install ios-webkit-debug-proxy
60+
61+
- name: Run all tests with integration tag and coverage
62+
run: go test -tags=integration ./... -v -count=1 -timeout=120s -coverprofile=coverage-integration.out
63+
64+
- name: Integration coverage summary
65+
run: |
66+
total=$(go tool cover -func=coverage-integration.out | tail -1 | awk '{print $NF}')
67+
echo "## Integration Test Coverage (includes all tests)" >> "$GITHUB_STEP_SUMMARY"
68+
echo "" >> "$GITHUB_STEP_SUMMARY"
69+
echo "**Total: ${total}**" >> "$GITHUB_STEP_SUMMARY"
70+
echo "" >> "$GITHUB_STEP_SUMMARY"
71+
echo "| Package | Coverage |" >> "$GITHUB_STEP_SUMMARY"
72+
echo "|---------|----------|" >> "$GITHUB_STEP_SUMMARY"
73+
go tool cover -func=coverage-integration.out | grep -v "total:" | awk -F'\t+' '{print $1, $NF}' | sort -u -t' ' -k1,1 | while read -r pkg cov; do
74+
echo "| \`${pkg}\` | ${cov} |" >> "$GITHUB_STEP_SUMMARY"
75+
done
76+
77+
simulator:
78+
runs-on: macos-latest
79+
steps:
80+
- uses: actions/checkout@v4
81+
82+
- uses: actions/setup-go@v5
83+
with:
84+
go-version-file: go.mod
85+
86+
- name: Install ios-webkit-debug-proxy
87+
run: brew install ios-webkit-debug-proxy
88+
89+
- name: Boot iOS Simulator and start iwdp
90+
run: |
91+
eval "$(./scripts/sim-setup.sh)"
92+
echo "IWDP_SIM_WS_URL=$IWDP_SIM_WS_URL" >> "$GITHUB_ENV"
93+
94+
- name: Run simulator tests with coverage
95+
run: go test -tags=simulator ./... -v -count=1 -timeout=300s -coverprofile=coverage-simulator.out
96+
97+
- name: Simulator coverage summary
98+
if: always()
99+
run: |
100+
if [ -f coverage-simulator.out ]; then
101+
total=$(go tool cover -func=coverage-simulator.out | tail -1 | awk '{print $NF}')
102+
echo "## Simulator Test Coverage" >> "$GITHUB_STEP_SUMMARY"
103+
echo "" >> "$GITHUB_STEP_SUMMARY"
104+
echo "**Total: ${total}**" >> "$GITHUB_STEP_SUMMARY"
105+
echo "" >> "$GITHUB_STEP_SUMMARY"
106+
echo "| Package | Coverage |" >> "$GITHUB_STEP_SUMMARY"
107+
echo "|---------|----------|" >> "$GITHUB_STEP_SUMMARY"
108+
go tool cover -func=coverage-simulator.out | grep -v "total:" | awk -F'\t+' '{print $1, $NF}' | sort -u -t' ' -k1,1 | while read -r pkg cov; do
109+
echo "| \`${pkg}\` | ${cov} |" >> "$GITHUB_STEP_SUMMARY"
110+
done
111+
fi
112+
113+
- name: Teardown simulator
114+
if: always()
115+
run: ./scripts/sim-setup.sh --teardown

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Binaries
2+
bin/
3+
./iwdp-mcp
4+
./iwdp-cli
5+
6+
# Coverage
7+
coverage.out
8+
coverage.html
9+
10+
# goreleaser
11+
dist/
12+
13+
# IDE
14+
.idea/
15+
.vscode/
16+
.zed/
17+
*.swp
18+
*.swo
19+
20+
# OS
21+
.DS_Store

.goreleaser.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
version: 2
2+
3+
builds:
4+
- id: iwdp-mcp
5+
main: ./cmd/iwdp-mcp
6+
binary: iwdp-mcp
7+
goos:
8+
- darwin
9+
- linux
10+
goarch:
11+
- amd64
12+
- arm64
13+
14+
- id: iwdp-cli
15+
main: ./cmd/iwdp-cli
16+
binary: iwdp-cli
17+
goos:
18+
- darwin
19+
- linux
20+
goarch:
21+
- amd64
22+
- arm64
23+
24+
archives:
25+
- id: default
26+
builds:
27+
- iwdp-mcp
28+
- iwdp-cli
29+
format_overrides:
30+
- goos: darwin
31+
format: zip
32+
files:
33+
- LICENSE
34+
- README.md
35+
36+
- id: raw-iwdp-mcp
37+
builds:
38+
- iwdp-mcp
39+
format: binary
40+
name_template: "iwdp-mcp_{{ .Os }}_{{ .Arch }}"
41+
42+
- id: raw-iwdp-cli
43+
builds:
44+
- iwdp-cli
45+
format: binary
46+
name_template: "iwdp-cli_{{ .Os }}_{{ .Arch }}"
47+
48+
changelog:
49+
sort: asc
50+
filters:
51+
exclude:
52+
- "^docs:"
53+
- "^test:"
54+
- "^ci:"
55+
56+
release:
57+
github:
58+
owner: nnemirovsky
59+
name: iwdp-mcp

.mcp.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"mcpServers": {
3+
"iwdp-mcp": {
4+
"command": "./scripts/run.sh"
5+
}
6+
}
7+
}

0 commit comments

Comments
 (0)