-
Notifications
You must be signed in to change notification settings - Fork 5
fix: support Claude MCP protocol 2026-07-28 #333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d857a20
cd7a380
a4432f9
f752deb
c8e6a8c
8bf0582
7d517c1
cf6c916
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,11 @@ on: | |
| pull_request: | ||
| branches: [main, master, feature/**] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
| statuses: read | ||
|
|
||
| jobs: | ||
| # Consumer compatibility: the standalone SDK lockfile on every supported | ||
| # Node version, with no workspace tooling involved. | ||
|
|
@@ -118,3 +123,140 @@ jobs: | |
| run: npm run lint --workspace @terminal49/mcp | ||
| - name: Check API gateway (Vite+ and anti-slop) | ||
| run: npm run lint:api | ||
|
|
||
| mcp-protocol-compat: | ||
| name: MCP protocol ${{ matrix.protocol-version }} | ||
| runs-on: ${{ (startsWith(vars.CI_RUNNER, 'blacksmith-') && vars.CI_RUNNER) || 'blacksmith-4vcpu-ubuntu-2404' }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| protocol-version: | ||
| - '2026-07-28' | ||
| - '2025-11-25' | ||
| - '2025-06-18' | ||
| - '2025-03-26' | ||
| - '2024-11-05' | ||
| - '2024-10-07' | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: 24 | ||
| cache: 'npm' | ||
| cache-dependency-path: package-lock.json | ||
| - name: Install workspace dependencies | ||
| run: npm ci | ||
| - name: Build SDK dependency | ||
| run: npm run build --workspace @terminal49/sdk | ||
| - name: Build MCP server | ||
| run: npm run build --workspace @terminal49/mcp | ||
| - name: POST protocol handshake to built MCP server | ||
| env: | ||
| MCP_PROTOCOL_VERSION: ${{ matrix.protocol-version }} | ||
| run: npm run test:protocol --workspace @terminal49/mcp | ||
|
|
||
| mcp-preview-protocol: | ||
| name: MCP preview ${{ matrix.protocol-version }} | ||
| if: >- | ||
| github.event_name == 'pull_request' && | ||
| github.event.pull_request.head.repo.full_name == github.repository && | ||
| github.actor != 'dependabot[bot]' | ||
| needs: [mcp, mcp-protocol-compat] | ||
| runs-on: ${{ (startsWith(vars.CI_RUNNER, 'blacksmith-') && vars.CI_RUNNER) || 'blacksmith-4vcpu-ubuntu-2404' }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| protocol-version: | ||
| - '2026-07-28' | ||
| - '2025-11-25' | ||
| steps: | ||
| - name: Check preview credential availability | ||
| id: credential | ||
| env: | ||
| MCP_EVAL_TOKEN: ${{ secrets.MCP_EVAL_TOKEN }} | ||
| run: | | ||
| if [[ -n "$MCP_EVAL_TOKEN" ]]; then | ||
| echo "available=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "available=false" >> "$GITHUB_OUTPUT" | ||
| echo "::notice::Skipping authenticated preview smoke because MCP_EVAL_TOKEN is unavailable" | ||
| fi | ||
| - uses: actions/checkout@v4 | ||
| if: steps.credential.outputs.available == 'true' | ||
| - uses: actions/setup-node@v6 | ||
| if: steps.credential.outputs.available == 'true' | ||
| with: | ||
| node-version: 24 | ||
| cache: 'npm' | ||
| cache-dependency-path: package-lock.json | ||
| - name: Install workspace dependencies | ||
| if: steps.credential.outputs.available == 'true' | ||
| run: npm ci | ||
| - name: Wait for this commit's Vercel preview | ||
| if: steps.credential.outputs.available == 'true' | ||
| id: vercel | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| PREVIEW_SHA: ${{ github.event.pull_request.head.sha }} | ||
| run: | | ||
| state=pending | ||
| for attempt in {1..60}; do | ||
| state="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${PREVIEW_SHA}/status" \ | ||
| --jq '[.statuses[] | select(.context == "Vercel")][0].state // "pending"')" | ||
| if [[ "$state" == "success" ]]; then | ||
| break | ||
| fi | ||
| if [[ "$state" == "failure" || "$state" == "error" ]]; then | ||
| echo "Vercel preview failed for ${PREVIEW_SHA}" | ||
| exit 1 | ||
| fi | ||
| sleep 10 | ||
| done | ||
| if [[ "$state" != "success" ]]; then | ||
| echo "Timed out waiting for Vercel preview for ${PREVIEW_SHA}" | ||
| exit 1 | ||
| fi | ||
| inspector_url="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${PREVIEW_SHA}/status" \ | ||
| --jq '[.statuses[] | select(.context == "Vercel")][0].target_url // empty')" | ||
| if [[ -z "$inspector_url" ]]; then | ||
| echo "Vercel status for ${PREVIEW_SHA} has no deployment URL" | ||
| exit 1 | ||
| fi | ||
| echo "inspector-url=${inspector_url}" >> "$GITHUB_OUTPUT" | ||
| - name: Resolve Vercel preview endpoint | ||
| if: steps.credential.outputs.available == 'true' | ||
| id: preview | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| VERCEL_INSPECTOR_URL: ${{ steps.vercel.outputs.inspector-url }} | ||
| run: | | ||
| preview_url="$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \ | ||
| --paginate --slurp | jq -r --arg inspector "$VERCEL_INSPECTOR_URL" \ | ||
| 'flatten | [.[] | select((.user.login == "vercel[bot]" or .user.login == "vercel") and (.body | contains($inspector)))][-1].body // "" | (try capture("\\[Preview\\]\\((?<url>https://[^)]+\\.vercel\\.app)\\)") catch {}) | .url // empty')" | ||
| if [[ -z "$preview_url" ]]; then | ||
| echo "Could not resolve a Vercel preview URL for ${VERCEL_INSPECTOR_URL}" | ||
| exit 1 | ||
| fi | ||
| echo "endpoint=${preview_url}/mcp" >> "$GITHUB_OUTPUT" | ||
| - name: POST handshake and tools/list to Vercel preview | ||
| if: steps.credential.outputs.available == 'true' | ||
| env: | ||
| MCP_HTTP_ENDPOINT: ${{ steps.preview.outputs.endpoint }} | ||
| MCP_HTTP_TOKEN: ${{ secrets.MCP_EVAL_TOKEN }} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Issue: |
||
| MCP_PROTOCOL_VERSION: ${{ matrix.protocol-version }} | ||
| run: npm run test:http-protocol --workspace @terminal49/mcp | ||
| - name: Verify preview still belongs to this commit | ||
| if: steps.credential.outputs.available == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| VERCEL_INSPECTOR_URL: ${{ steps.vercel.outputs.inspector-url }} | ||
| run: | | ||
| matches="$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \ | ||
| --paginate --slurp | jq -r --arg inspector "$VERCEL_INSPECTOR_URL" \ | ||
| 'flatten | [.[] | select((.user.login == "vercel[bot]" or .user.login == "vercel") and (.body | contains($inspector)))] | length')" | ||
| if [[ "$matches" != "1" ]]; then | ||
| echo "Vercel preview changed while the smoke test was running" | ||
| exit 1 | ||
| fi | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue: This selects the latest Vercel bot comment independently of
PREVIEW_SHA. If commit B is pushed while commit A's workflow is still running, A can wait for its own successful deployment and then execute the smoke test against B's preview URL, allowing A's check to pass without exercising A's gateway. Resolve the deployment URL fromPREVIEW_SHA, or verify the selected deployment's source SHA before testing it.