Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:25:43 +08:00
commit bd0f3b67e7
19 changed files with 5648 additions and 0 deletions

222
scripts/init-mcp-server.sh Executable file
View File

@@ -0,0 +1,222 @@
#!/bin/bash
# Initialize a new TypeScript MCP server project
# Usage: ./init-mcp-server.sh [project-name]
set -e
PROJECT_NAME="${1:-mcp-server}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATES_DIR="$(dirname "$SCRIPT_DIR")/templates"
echo "==================================="
echo "TypeScript MCP Server Setup"
echo "==================================="
echo ""
# Create project directory
if [ -d "$PROJECT_NAME" ]; then
echo "❌ Directory '$PROJECT_NAME' already exists"
exit 1
fi
mkdir -p "$PROJECT_NAME"
cd "$PROJECT_NAME"
echo "📁 Created project directory: $PROJECT_NAME"
echo ""
# Ask for template choice
echo "Select MCP server template:"
echo "1) Basic (simple tools)"
echo "2) Tool Server (multiple API integrations)"
echo "3) Resource Server (data exposure)"
echo "4) Full Server (tools + resources + prompts)"
echo "5) Authenticated Server (with API key auth)"
read -p "Choice [1-5]: " choice
case $choice in
1) TEMPLATE="basic-mcp-server.ts" ;;
2) TEMPLATE="tool-server.ts" ;;
3) TEMPLATE="resource-server.ts" ;;
4) TEMPLATE="full-server.ts" ;;
5) TEMPLATE="authenticated-server.ts" ;;
*) echo "Invalid choice"; exit 1 ;;
esac
echo "✅ Selected: $TEMPLATE"
echo ""
# Initialize package.json
echo "📦 Creating package.json..."
cat > package.json << 'EOF'
{
"name": "mcp-server",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "wrangler dev",
"build": "tsc && vite build",
"deploy": "wrangler deploy",
"test": "vitest"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.20.2",
"@cloudflare/workers-types": "^4.20251011.0",
"hono": "^4.10.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.5.29",
"typescript": "^5.7.0",
"vitest": "^3.0.0",
"wrangler": "^4.43.0"
}
}
EOF
# Update project name
sed -i "s/\"name\": \"mcp-server\"/\"name\": \"$PROJECT_NAME\"/" package.json
# Create source directory
mkdir -p src
# Copy template
echo "📄 Copying template..."
cp "$TEMPLATES_DIR/$TEMPLATE" src/index.ts
# Copy wrangler config
echo "⚙️ Creating wrangler.jsonc..."
cp "$TEMPLATES_DIR/wrangler.jsonc" wrangler.jsonc
sed -i "s/\"name\": \"my-mcp-server\"/\"name\": \"$PROJECT_NAME\"/" wrangler.jsonc
# Create tsconfig.json
echo "🔧 Creating tsconfig.json..."
cat > tsconfig.json << 'EOF'
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022"],
"moduleResolution": "bundler",
"types": ["@cloudflare/workers-types"],
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
EOF
# Create .gitignore
echo "🙈 Creating .gitignore..."
cat > .gitignore << 'EOF'
node_modules/
dist/
.wrangler/
.dev.vars
*.log
.DS_Store
EOF
# Create .dev.vars template
echo "🔐 Creating .dev.vars (for local secrets)..."
cat > .dev.vars << 'EOF'
# Local development secrets
# NEVER commit this file to git!
# Example:
# WEATHER_API_KEY=your-key-here
# DATABASE_URL=postgres://...
EOF
# Create README
echo "📝 Creating README.md..."
cat > README.md << EOF
# $PROJECT_NAME
TypeScript MCP server built with the official MCP SDK.
## Setup
\`\`\`bash
# Install dependencies
npm install
# Run locally
npm run dev
# Deploy to Cloudflare Workers
npm run deploy
\`\`\`
## Testing
\`\`\`bash
# Start server
npm run dev
# In another terminal, test with MCP Inspector
npx @modelcontextprotocol/inspector
# Connect to: http://localhost:8787/mcp
\`\`\`
## Endpoints
- \`GET /\` - Server info
- \`POST /mcp\` - MCP protocol endpoint
## Environment Variables
Add secrets to Cloudflare Workers:
\`\`\`bash
wrangler secret put API_KEY
\`\`\`
For local development, add to \`.dev.vars\`:
\`\`\`
API_KEY=your-key
\`\`\`
## Deployment
\`\`\`bash
# Build
npm run build
# Deploy
npm run deploy
# View logs
wrangler tail
\`\`\`
## Documentation
- MCP Specification: https://spec.modelcontextprotocol.io/
- TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
- Cloudflare Workers: https://developers.cloudflare.com/workers/
EOF
# Install dependencies
echo ""
echo "📥 Installing dependencies..."
npm install
echo ""
echo "✅ Setup complete!"
echo ""
echo "Next steps:"
echo " cd $PROJECT_NAME"
echo " npm run dev # Start local server"
echo " npm run deploy # Deploy to Cloudflare"
echo ""
echo "Test with MCP Inspector:"
echo " npx @modelcontextprotocol/inspector"
echo " Connect to: http://localhost:8787/mcp"
echo ""

154
scripts/test-mcp-connection.sh Executable file
View File

@@ -0,0 +1,154 @@
#!/bin/bash
# Test MCP server connectivity and validate endpoints
# Usage: ./test-mcp-connection.sh [URL] [API_KEY]
set -e
# Default to local dev server
URL="${1:-http://localhost:8787/mcp}"
API_KEY="${2:-}"
echo "======================================"
echo "MCP Server Connection Test"
echo "======================================"
echo ""
echo "Testing: $URL"
echo ""
# Build headers
if [ -n "$API_KEY" ]; then
HEADERS=(-H "Content-Type: application/json" -H "Authorization: Bearer $API_KEY")
echo "🔐 Using API key authentication"
else
HEADERS=(-H "Content-Type: application/json")
echo "⚠️ No API key provided (testing without auth)"
fi
echo ""
# Test 1: List tools
echo "1⃣ Testing tools/list..."
TOOLS_RESPONSE=$(curl -s -X POST "$URL" \
"${HEADERS[@]}" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}')
if echo "$TOOLS_RESPONSE" | jq -e '.result.tools' > /dev/null 2>&1; then
TOOL_COUNT=$(echo "$TOOLS_RESPONSE" | jq '.result.tools | length')
echo "✅ Success: Found $TOOL_COUNT tool(s)"
echo "$TOOLS_RESPONSE" | jq '.result.tools[] | {name: .name, description: .description}'
else
echo "❌ Failed to list tools"
echo "Response: $TOOLS_RESPONSE"
exit 1
fi
echo ""
# Test 2: List resources
echo "2⃣ Testing resources/list..."
RESOURCES_RESPONSE=$(curl -s -X POST "$URL" \
"${HEADERS[@]}" \
-d '{
"jsonrpc": "2.0",
"method": "resources/list",
"id": 2
}')
if echo "$RESOURCES_RESPONSE" | jq -e '.result.resources' > /dev/null 2>&1; then
RESOURCE_COUNT=$(echo "$RESOURCES_RESPONSE" | jq '.result.resources | length')
echo "✅ Success: Found $RESOURCE_COUNT resource(s)"
echo "$RESOURCES_RESPONSE" | jq '.result.resources[] | {uri: .uri, name: .name}'
elif echo "$RESOURCES_RESPONSE" | jq -e '.error' > /dev/null 2>&1; then
echo "⚠️ No resources endpoint (some templates don't have resources)"
else
echo "❌ Failed to list resources"
echo "Response: $RESOURCES_RESPONSE"
fi
echo ""
# Test 3: List prompts
echo "3⃣ Testing prompts/list..."
PROMPTS_RESPONSE=$(curl -s -X POST "$URL" \
"${HEADERS[@]}" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/list",
"id": 3
}')
if echo "$PROMPTS_RESPONSE" | jq -e '.result.prompts' > /dev/null 2>&1; then
PROMPT_COUNT=$(echo "$PROMPTS_RESPONSE" | jq '.result.prompts | length')
echo "✅ Success: Found $PROMPT_COUNT prompt(s)"
echo "$PROMPTS_RESPONSE" | jq '.result.prompts[] | {name: .name, description: .description}'
elif echo "$PROMPTS_RESPONSE" | jq -e '.error' > /dev/null 2>&1; then
echo "⚠️ No prompts endpoint (some templates don't have prompts)"
else
echo "❌ Failed to list prompts"
echo "Response: $PROMPTS_RESPONSE"
fi
echo ""
# Test 4: Call first tool (if available)
FIRST_TOOL=$(echo "$TOOLS_RESPONSE" | jq -r '.result.tools[0].name // empty')
if [ -n "$FIRST_TOOL" ]; then
echo "4⃣ Testing tool call: $FIRST_TOOL..."
# Determine arguments based on tool
case "$FIRST_TOOL" in
"echo")
ARGS='{"text": "Hello, MCP!"}'
;;
"add")
ARGS='{"a": 5, "b": 3}'
;;
"get-status")
ARGS='{}'
;;
*)
echo "⚠️ Unknown tool, skipping test"
ARGS=""
;;
esac
if [ -n "$ARGS" ]; then
CALL_RESPONSE=$(curl -s -X POST "$URL" \
"${HEADERS[@]}" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"tools/call\",
\"params\": {
\"name\": \"$FIRST_TOOL\",
\"arguments\": $ARGS
},
\"id\": 4
}")
if echo "$CALL_RESPONSE" | jq -e '.result' > /dev/null 2>&1; then
echo "✅ Success: Tool executed"
echo "$CALL_RESPONSE" | jq '.result'
else
echo "❌ Failed to call tool"
echo "Response: $CALL_RESPONSE"
exit 1
fi
fi
else
echo "4⃣ No tools to test"
fi
echo ""
# Summary
echo "======================================"
echo "✅ Connection test complete!"
echo "======================================"
echo ""
echo "Summary:"
echo " Tools: $TOOL_COUNT"
echo " Resources: ${RESOURCE_COUNT:-0}"
echo " Prompts: ${PROMPT_COUNT:-0}"
echo ""
echo "Server is responding correctly! 🎉"
echo ""