Skip to content

Commit d7432a0

Browse files
committed
fix(smithery): publish automation v3 + GitHub Action for registry refresh
Root cause: Smithery registry caches 5 tools from old publish. Server LIVE returns 13/13 tools. Re-publish will fix. - Updated scripts/smithery-publish.sh (v3): pre-flight validation, before/after snapshots, expected 13 tools gate - New .github/workflows/smithery-publish.yml: manual dispatch workflow with SMITHERY_API_KEY secret for automated future publishing - Evidence file: smithery_p0_evidence.json with full before/after state Blocker: Smithery auth requires browser login (Vercel bot protection blocks VM). User must run publish from local machine.
1 parent 7216788 commit d7432a0

3 files changed

Lines changed: 192 additions & 33 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Publish to Smithery Registry
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
dry_run:
7+
description: 'Dry run (validate only, do not publish)'
8+
required: false
9+
default: 'false'
10+
type: boolean
11+
12+
jobs:
13+
publish:
14+
name: Publish MCP Server to Smithery
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 5
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20'
25+
26+
- name: Pre-flight validation
27+
run: |
28+
echo "=== Pre-flight Validation ==="
29+
30+
# 1. Config schema exists and is valid JSON
31+
python3 -c "import json; json.load(open('scripts/smithery-config-schema.json'))"
32+
echo "✅ Config schema valid"
33+
34+
# 2. Server is reachable and returns tools
35+
TOOL_COUNT=$(curl -sf -X POST "https://forge.synapselayer.org/api/mcp" \
36+
-H "Content-Type: application/json" \
37+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
38+
python3 -c "import sys,json; print(len(json.loads(sys.stdin.read()).get('result',{}).get('tools',[])))")
39+
echo "✅ Server returns $TOOL_COUNT tools"
40+
41+
if [ "$TOOL_COUNT" -lt 13 ]; then
42+
echo "⚠️ Expected 13 tools, got $TOOL_COUNT"
43+
exit 1
44+
fi
45+
46+
- name: Publish to Smithery
47+
if: ${{ inputs.dry_run != 'true' }}
48+
env:
49+
SMITHERY_API_KEY: ${{ secrets.SMITHERY_API_KEY }}
50+
run: |
51+
npx @smithery/cli mcp publish \
52+
https://forge.synapselayer.org/api/mcp \
53+
-n synapselayer/synapse-protocol \
54+
--config-schema scripts/smithery-config-schema.json
55+
56+
- name: Verify publication
57+
if: ${{ inputs.dry_run != 'true' }}
58+
run: |
59+
sleep 5
60+
curl -sf "https://registry.smithery.ai/servers/@synapselayer/synapse-protocol" | \
61+
python3 -c "
62+
import json, sys
63+
data = json.load(sys.stdin)
64+
tools = data.get('tools', [])
65+
print(f'Registry tools: {len(tools)}')
66+
for t in tools:
67+
print(f' ✓ {t[\"name\"]}')
68+
if len(tools) >= 13:
69+
print('✅ All tools published!')
70+
else:
71+
print(f'⚠️ Only {len(tools)}/13 tools — may need cache refresh')
72+
"

scripts/smithery-publish.sh

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,125 @@
11
#!/bin/bash
22
# =============================================================================
3-
# Synapse Layer — Smithery Registry Publish Script v2
3+
# Synapse Layer — Smithery Registry Publish Script v3
44
# Run this on your LOCAL machine (not VM) to authenticate and publish.
5+
#
6+
# Prerequisites:
7+
# - Node.js 20+
8+
# - Internet access to smithery.ai (Vercel-hosted, needs real browser)
9+
#
10+
# Usage:
11+
# chmod +x scripts/smithery-publish.sh
12+
# ./scripts/smithery-publish.sh
513
# =============================================================================
6-
set -e
14+
set -euo pipefail
715

816
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
917
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
1018
CONFIG_SCHEMA="${REPO_ROOT}/scripts/smithery-config-schema.json"
19+
SERVER_URL="https://forge.synapselayer.org/api/mcp"
20+
QUALIFIED_NAME="synapselayer/synapse-protocol"
21+
EXPECTED_TOOLS=13
1122

12-
echo "🧠 Synapse Layer — Smithery Publish Pipeline v2"
23+
echo "🧠 Synapse Layer — Smithery Publish Pipeline v3"
1324
echo "================================================"
1425
echo ""
1526

16-
# 1. Check CLI
27+
# ── Step 0: Pre-flight validation ──────────────────────────────────
28+
echo "📋 Step 0: Pre-flight validation..."
29+
30+
# Check npx
1731
if ! command -v npx &> /dev/null; then
1832
echo "❌ npx not found. Install Node.js 20+ first."
1933
exit 1
2034
fi
21-
echo "✅ Node.js found: $(node --version)"
35+
echo " ✅ Node.js: $(node --version)"
36+
37+
# Check config schema
38+
if [ ! -f "$CONFIG_SCHEMA" ]; then
39+
echo "❌ Config schema not found at $CONFIG_SCHEMA"
40+
exit 1
41+
fi
42+
python3 -c "import json; json.load(open('$CONFIG_SCHEMA'))" 2>/dev/null || {
43+
echo "❌ Config schema is invalid JSON"
44+
exit 1
45+
}
46+
echo " ✅ Config schema valid"
47+
48+
# Check server accessibility
49+
TOOL_COUNT=$(curl -sf -X POST "$SERVER_URL" \
50+
-H "Content-Type: application/json" \
51+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
52+
python3 -c "import sys,json; print(len(json.loads(sys.stdin.read()).get('result',{}).get('tools',[])))" 2>/dev/null || echo "0")
53+
54+
if [ "$TOOL_COUNT" -lt "$EXPECTED_TOOLS" ]; then
55+
echo "❌ Server returns $TOOL_COUNT tools (expected $EXPECTED_TOOLS)"
56+
echo " Fix the MCP server before publishing."
57+
exit 1
58+
fi
59+
echo " ✅ Server returns $TOOL_COUNT tools"
60+
61+
# Snapshot before
62+
echo ""
63+
echo "📸 Current registry state (BEFORE):"
64+
curl -sf "https://registry.smithery.ai/servers/@${QUALIFIED_NAME}" | python3 -c "
65+
import json, sys
66+
data = json.load(sys.stdin)
67+
tools = data.get('tools', [])
68+
print(f' Tools: {len(tools)}')
69+
for t in tools: print(f' - {t[\"name\"]}')
70+
print(f' Description: {data.get(\"description\", \"N/A\")[:80]}...')
71+
" 2>/dev/null || echo " ⚠️ Could not fetch current registry state"
2272
echo ""
2373

24-
# 2. Authenticate
74+
# ── Step 1: Authenticate ──────────────────────────────────────────
2575
echo "🔐 Step 1: Authenticating with Smithery..."
76+
echo " This will open your browser. Log in with your Smithery account."
77+
echo ""
2678
npx @smithery/cli auth login
2779
echo ""
2880

29-
# 3. Verify auth
81+
# Verify auth
3082
echo "🔍 Step 2: Verifying authentication..."
3183
npx @smithery/cli auth whoami
3284
echo ""
3385

34-
# 4. Verify config schema exists
35-
if [ ! -f "$CONFIG_SCHEMA" ]; then
36-
echo "❌ Config schema not found at $CONFIG_SCHEMA"
37-
exit 1
38-
fi
39-
echo "✅ Config schema found: $CONFIG_SCHEMA"
40-
echo ""
41-
42-
# 5. Publish (update existing listing)
86+
# ── Step 3: Publish ───────────────────────────────────────────────
4387
echo "🚀 Step 3: Publishing to Smithery Registry..."
4488
npx @smithery/cli mcp publish \
45-
https://forge.synapselayer.org/api/mcp \
46-
-n synapselayer/synapse-protocol \
89+
"$SERVER_URL" \
90+
-n "$QUALIFIED_NAME" \
4791
--config-schema "$CONFIG_SCHEMA"
48-
49-
echo ""
50-
echo "✅ Published!"
5192
echo ""
5293

53-
# 6. Wait for propagation
54-
echo "⏳ Step 4: Waiting 5s for registry propagation..."
55-
sleep 5
94+
# ── Step 4: Wait and verify ──────────────────────────────────────
95+
echo "⏳ Step 4: Waiting 10s for registry propagation..."
96+
sleep 10
5697

57-
# 7. Verify listing
5898
echo "🔍 Step 5: Verifying listing..."
59-
curl -s "https://registry.smithery.ai/servers/synapselayer/synapse-protocol" | python3 -c "
99+
curl -sf "https://registry.smithery.ai/servers/@${QUALIFIED_NAME}" | python3 -c "
60100
import json, sys
61101
data = json.load(sys.stdin)
62-
print(f' Name: {data.get(\"displayName\")}')
63102
tools = data.get('tools', [])
64-
print(f' Tools: {len(tools)} registered')
103+
print(f' Tools: {len(tools)}')
65104
for t in tools:
66105
print(f' ✓ {t[\"name\"]}')
67-
print(f' URL: {data.get(\"deploymentUrl\")}')
106+
print(f' Description: {data.get(\"description\", \"N/A\")[:80]}...')
68107
print()
69-
expected = 13
70-
if len(tools) >= expected:
71-
print(f'✅ All {len(tools)} tools published successfully!')
108+
if len(tools) >= $EXPECTED_TOOLS:
109+
print(f'✅ SUCCESS: All {len(tools)} tools published!')
72110
else:
73-
print(f'⚠️ Only {len(tools)}/{expected} tools detected — server may need redeployment.')
111+
print(f'⚠️ Only {len(tools)}/$EXPECTED_TOOLS tools — Smithery may need time to refresh cache.')
112+
print(f' Check: https://smithery.ai/servers/{\"$QUALIFIED_NAME\".replace(\"/\", \"/\")}\n')
74113
"
75114

115+
echo ""
116+
echo "📸 Registry state saved. If publishing succeeded, save the SMITHERY_API_KEY"
117+
echo " as a GitHub secret for automated future publishing:"
118+
echo ""
119+
echo " npx @smithery/cli auth whoami --full"
120+
echo " → Copy the API key"
121+
echo " → Go to github.com/SynapseLayer/synapse-layer/settings/secrets/actions"
122+
echo " → Add secret: SMITHERY_API_KEY = <your key>"
123+
echo " → Future publishes: Actions → 'Publish to Smithery Registry' → Run workflow"
76124
echo ""
77125
echo "🎉 Done! Verify at: https://smithery.ai/servers/synapselayer/synapse-protocol"

smithery_p0_evidence.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"mission": "P0 Smithery Distribution Hard Close",
3+
"date": "2026-05-15",
4+
"before": {
5+
"source": "https://registry.smithery.ai/servers/@synapselayer/synapse-protocol",
6+
"tools_count": 5,
7+
"tools": ["recall", "save_to_synapse", "process_text", "search", "health_check"],
8+
"description_has_banned_claim": true,
9+
"banned_claim": "Security Score: 10/10 (MCP)",
10+
"score": 69,
11+
"uptime": "100%"
12+
},
13+
"live_server": {
14+
"url": "https://forge.synapselayer.org/api/mcp",
15+
"tools_count": 13,
16+
"tools": [
17+
"recall", "save_to_synapse", "process_text", "search", "health_check",
18+
"initialize_context", "save_memory", "store_memory", "recall_memory",
19+
"list_memories", "memory_feedback", "neural_handover", "slo_report"
20+
],
21+
"delete_memory_feature_flagged": true,
22+
"protocol_version": "2024-11-05",
23+
"server_version": "2.4.0"
24+
},
25+
"smithery_yaml": {
26+
"location": "synapse-layer/smithery.yaml",
27+
"tools_count": 13,
28+
"version": "2.4.0",
29+
"description_clean": true,
30+
"configSchema_valid": true
31+
},
32+
"root_cause": "Registry was populated at a PREVIOUS publish time when server had only 5 tools. Server now exposes 13 tools. Re-publishing via Smithery CLI will refresh the registry to show all 13.",
33+
"blocker": "Smithery auth requires browser-based login. smithery.ai is hosted on Vercel which blocks VM headless browser (Vercel Security Checkpoint Code 11). Re-publish MUST be done from a machine with a real browser (user's local machine).",
34+
"artifacts_prepared": {
35+
"publish_script": "scripts/smithery-publish.sh",
36+
"config_schema": "scripts/smithery-config-schema.json",
37+
"github_action": ".github/workflows/smithery-publish.yml"
38+
}
39+
}

0 commit comments

Comments
 (0)