Переглянути джерело

docs: update MCP servers documentation for SSE protocol and n8n integration #76

Claude 5 місяців тому
батько
коміт
e1bca5f67d
1 змінених файлів з 210 додано та 89 видалено
  1. 210 89
      docs/MCP_SERVERS.md

+ 210 - 89
docs/MCP_SERVERS.md

@@ -1,23 +1,27 @@
-# MCP HTTP Servers for Webshop API Access
+# MCP SSE Servers for Webshop API Access
 
 ## Overview
 
-This document describes the MCP (Model Context Protocol) HTTP servers implemented for accessing webshop orders and customers data in a GDPR-compliant manner. These servers allow LLMs to access personal data on-demand without storing it in the database.
+This document describes the MCP (Model Context Protocol) SSE (Server-Sent Events) servers implemented for accessing webshop orders and customers data in a GDPR-compliant manner. These servers allow LLMs (like n8n workflows) to access personal data on-demand without storing it in the database.
+
+**Protocol**: MCP over HTTP with Server-Sent Events (2024-11-05)
+**Transport**: HTTP POST with SSE streaming responses
+**Format**: JSON-RPC 2.0
 
 ## Architecture
 
 ```
-┌─────┐    ┌──────────────────┐    ┌────────────────┐    ┌──────────────┐
-│ LLM │───▶│ MCP HTTP Server  │───▶│ Internal API   │───▶│   Webshop    │
-│   │ (Edge Function)  │    │ Key Auth       │    │   API        │
-└─────┘    └──────────────────┘    └────────────────┘    └──────────────┘
-              │                           │
-              │                           │
-              ▼                           ▼
-         ┌─────────────┐          ┌──────────────────┐
-         │   Store     │          │ internal_api_keys│
-         │ Permissions │          │     table        │
-         └─────────────┘          └──────────────────┘
+┌─────────  POST (JSON-RPC)   ┌──────────────────┐    ┌────────────────┐    ┌──────────────┐
+│   n8n   │────────────────────▶│  MCP SSE Server  │───▶│ Internal API   │───▶│   Webshop    │
+│   LLM   │◀────────────────────│ (Edge Function)  │    │ Key Auth       │    │   API        │
+└─────────   SSE Stream         └──────────────────┘    └────────────────┘    └──────────────┘
+                                        │                           │
+                                        │                           │
+                                        ▼                           ▼
+                                   ┌─────────────┐          ┌──────────────────┐
+                                   │   Store     │          │ internal_api_keys│
+                                   │ Permissions │          │     table        │
+                                   └─────────────┘          └──────────────────┘
 ```
 
 ## Implemented MCP Servers
@@ -72,90 +76,119 @@ Authorization: Bearer int_shopcall_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   - `X-RateLimit-Remaining: 150`
   - `X-RateLimit-Reset: 2025-01-15T10:30:00Z`
 
-## MCP Protocol
+## MCP SSE Protocol
+
+### Single Endpoint: POST /
+
+All MCP communication happens through a single POST endpoint using Server-Sent Events.
+
+**URL**: `https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-{platform}/`
 
-### Endpoint: GET /tools
+**Method**: POST
 
-Returns available tools (no authentication required):
+**Authentication**: Required (Bearer token in Authorization header)
+
+**Protocol**: JSON-RPC 2.0 over SSE
+
+### Supported JSON-RPC Methods
+
+#### 1. `initialize` - Initialize MCP connection
 
 **Request:**
 ```bash
-GET /functions/v1/mcp-shopify/tools
-```
+POST /functions/v1/mcp-shopify
+Authorization: Bearer int_shopcall_xxxxx
+Content-Type: application/json
 
-**Response:**
-```json
 {
-  "tools": [
-    {
-      "name": "shopify_list_orders",
-      "description": "List orders from a Shopify store. Returns order details including customer info, items, status, and totals.",
-      "inputSchema": {
-        "type": "object",
-        "properties": {
-          "shop_id": {
-            "type": "string",
-            "description": "The UUID of the Shopify store from the stores table"
-          },
-          "status": {
-            "type": "string",
-            "description": "Filter by order status: any (default), open, closed, cancelled",
-            "enum": ["any", "open", "closed", "cancelled"]
-          },
-          "limit": {
-            "type": "number",
-            "description": "Maximum number of orders to return (default: 50, max: 250)"
-          }
-        },
-        "required": ["shop_id"]
-      }
+  "jsonrpc": "2.0",
+  "id": 1,
+  "method": "initialize",
+  "params": {
+    "protocolVersion": "2024-11-05",
+    "capabilities": {
+      "roots": { "listChanged": true }
+    },
+    "clientInfo": {
+      "name": "n8n",
+      "version": "1.0.0"
     }
-  ]
+  }
 }
 ```
 
-### Endpoint: POST /call
+**Response (SSE Stream):**
+```
+data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"mcp-shopify","version":"1.0.0"}}}
+
+```
 
-Executes a tool (requires authentication):
+#### 2. `tools/list` - Get available tools
 
 **Request:**
 ```bash
-POST /functions/v1/mcp-shopify/call
+POST /functions/v1/mcp-shopify
 Authorization: Bearer int_shopcall_xxxxx
 Content-Type: application/json
 
 {
-  "name": "shopify_list_orders",
-  "arguments": {
-    "shop_id": "abc-123-def-456",
-    "status": "any",
-    "limit": 10
-  }
+  "jsonrpc": "2.0",
+  "id": 2,
+  "method": "tools/list",
+  "params": {}
 }
 ```
 
-**Success Response:**
-```json
+**Response (SSE Stream):**
+```
+data: {"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"shopify_list_orders","description":"List orders from a Shopify store...","inputSchema":{...}}]}}
+
+```
+
+#### 3. `tools/call` - Execute a tool
+
+**Request:**
+```bash
+POST /functions/v1/mcp-shopify
+Authorization: Bearer int_shopcall_xxxxx
+Content-Type: application/json
+
 {
-  "content": [
-    {
-      "type": "text",
-      "text": "{\"count\":3,\"total\":10,\"orders\":[...]}"
+  "jsonrpc": "2.0",
+  "id": 3,
+  "method": "tools/call",
+  "params": {
+    "name": "shopify_list_orders",
+    "arguments": {
+      "shop_id": "abc-123-def-456",
+      "status": "any",
+      "limit": 10
     }
-  ]
+  }
 }
 ```
 
-**Error Response:**
-```json
-{
-  "error": {
-    "code": "STORE_NOT_FOUND",
-    "message": "Shopify store not found"
-  },
-  "isError": true
-}
+**Success Response (SSE Stream):**
+```
+data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\"count\":3,\"total\":10,\"orders\":[...]}"}]}}
+
+```
+
+**Error Response (SSE Stream):**
 ```
+data: {"jsonrpc":"2.0","id":3,"error":{"code":-32603,"message":"Shopify store not found"}}
+
+```
+
+### JSON-RPC Error Codes
+
+| Code | Name | Description |
+|------|------|-------------|
+| -32700 | Parse error | Invalid JSON was received |
+| -32600 | Invalid Request | The JSON sent is not a valid Request object |
+| -32601 | Method not found | The method does not exist / is not available |
+| -32602 | Invalid params | Invalid method parameter(s) |
+| -32603 | Internal error | Internal JSON-RPC error |
 
 ## Store Permissions
 
@@ -267,28 +300,56 @@ curl https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify/tools
 
 ## Testing
 
-### Test Tool Discovery
-
-```bash
-curl https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify/tools
-```
-
-### Test Tool Execution
+### Test with curl
 
 ```bash
 # Set your internal API key
 INTERNAL_API_KEY="int_shopcall_xxxxx"
 SHOP_ID="your-store-uuid"
 
-# List orders
-curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify/call \
+# Test initialize
+curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify \
+  -H "Authorization: Bearer $INTERNAL_API_KEY" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "jsonrpc": "2.0",
+    "id": 1,
+    "method": "initialize",
+    "params": {
+      "protocolVersion": "2024-11-05",
+      "capabilities": {},
+      "clientInfo": {
+        "name": "test-client",
+        "version": "1.0.0"
+      }
+    }
+  }'
+
+# Test tools/list
+curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify \
+  -H "Authorization: Bearer $INTERNAL_API_KEY" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "jsonrpc": "2.0",
+    "id": 2,
+    "method": "tools/list",
+    "params": {}
+  }'
+
+# Test tools/call (list orders)
+curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify \
   -H "Authorization: Bearer $INTERNAL_API_KEY" \
   -H "Content-Type: application/json" \
   -d "{
-    \"name\": \"shopify_list_orders\",
-    \"arguments\": {
-      \"shop_id\": \"$SHOP_ID\",
-      \"limit\": 5
+    \"jsonrpc\": \"2.0\",
+    \"id\": 3,
+    \"method\": \"tools/call\",
+    \"params\": {
+      \"name\": \"shopify_list_orders\",
+      \"arguments\": {
+        \"shop_id\": \"$SHOP_ID\",
+        \"limit\": 5
+      }
     }
   }"
 ```
@@ -297,17 +358,76 @@ curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify/c
 
 ```bash
 # Test missing shop_id
-curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify/call \
+curl -X POST https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-shopify \
   -H "Authorization: Bearer $INTERNAL_API_KEY" \
   -H "Content-Type: application/json" \
-  -d "{
-    \"name\": \"shopify_list_orders\",
-    \"arguments\": {}
-  }"
+  -d '{
+    "jsonrpc": "2.0",
+    "id": 4,
+    "method": "tools/call",
+    "params": {
+      "name": "shopify_list_orders",
+      "arguments": {}
+    }
+  }'
 
-# Expected: MISSING_PARAMS error
+# Expected: JSON-RPC error with missing parameters
 ```
 
+## n8n Integration
+
+### Configuring MCP Servers in n8n
+
+1. **Add MCP Server Credential in n8n:**
+   - Type: `HTTP Streamable`
+   - URL: `https://ztklqodcdjeqpsvhlpud.supabase.co/functions/v1/mcp-woocommerce`
+     - Or use `/mcp-shopify` or `/mcp-shoprenter` based on your needs
+   - Authentication: `Bearer Token`
+   - Add custom header:
+     - Header: `Authorization`
+     - Value: `Bearer int_shopcall_[your-api-key]`
+
+2. **Using MCP Tools in n8n Workflow:**
+   - Add an "AI Agent" or "MCP Tool" node
+   - Select your MCP server credential
+   - The agent will automatically discover available tools
+   - Call tools with required parameters (always include `shop_id`)
+
+3. **Example n8n Tool Call:**
+   ```javascript
+   // In n8n AI Agent node, the MCP client will call:
+   {
+     "name": "woocommerce_list_orders",
+     "arguments": {
+       "shop_id": "uuid-of-woocommerce-store",
+       "status": "completed",
+       "per_page": 10
+     }
+   }
+   ```
+
+### Troubleshooting n8n Integration
+
+**Issue: "No tools found"**
+- Check that the URL ends with the function name (e.g., `/mcp-woocommerce`)
+- Verify the Bearer token is correctly set in headers
+- Check Supabase Edge Function logs for 401 errors
+
+**Issue: "Connection timeout"**
+- Ensure the Edge Function is deployed and active
+- Check network connectivity to Supabase
+- Verify CORS headers are present
+
+**Issue: "401 Unauthorized"**
+- Verify the internal API key is active in the database
+- Check that the API key has `read_orders` permission
+- Ensure the Bearer token format is: `Bearer int_shopcall_...`
+
+**Issue: "Tools executing but returning errors"**
+- Check that `shop_id` parameter is a valid UUID
+- Verify the store exists and matches the platform (e.g., don't use a Shopify store ID with mcp-woocommerce)
+- Check store permissions allow order/customer access
+
 ## Security Best Practices
 
 1. **API Key Management**
@@ -436,5 +556,6 @@ For issues or questions:
 ---
 
 **Last Updated**: 2025-01-12
-**Version**: 1.0.0
+**Version**: 2.0.0 (SSE Protocol)
 **Related Issue**: #76
+**Protocol**: MCP over HTTP with SSE (2024-11-05)