From 7a6a021295918f15967e6888e2f5cf6b7eda0e21 Mon Sep 17 00:00:00 2001 From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:53:24 +0000 Subject: [PATCH] docs, linting, header unpacking fix Signed-off-by: GitHub --- docs/API_MCP.md | 92 +++++++++++++++++++ server/api_server/api_server_start.py | 4 +- .../api_endpoints/test_mcp_tools_endpoints.py | 2 +- 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/docs/API_MCP.md b/docs/API_MCP.md index c52cdf39..6ab19c4b 100644 --- a/docs/API_MCP.md +++ b/docs/API_MCP.md @@ -19,6 +19,98 @@ All MCP endpoints mirror the functionality of standard REST endpoints but are op --- +## Architecture Overview + +### MCP Connection Flow + +```mermaid +graph TB + A[AI Assistant
Claude Desktop] -->|SSE Connection| B[NetAlertX MCP Server
:20212/mcp/sse] + B -->|JSON-RPC Messages| C[MCP Bridge
api_server_start.py] + C -->|Tool Calls| D[NetAlertX Tools
Device/Network APIs] + D -->|Response Data| C + C -->|JSON Response| B + B -->|Stream Events| A + + style A fill:#e1f5fe + style B fill:#f3e5f5 + style C fill:#fff3e0 + style D fill:#e8f5e8 +``` + +### MCP Tool Integration + +```mermaid +sequenceDiagram + participant AI as AI Assistant + participant MCP as MCP Server (:20212) + participant API as NetAlertX API (:20211) + participant DB as SQLite Database + + AI->>MCP: 1. Connect via SSE + MCP-->>AI: 2. Session established + AI->>MCP: 3. tools/list request + MCP->>API: 4. GET /mcp/sse/openapi.json + API-->>MCP: 5. Available tools spec + MCP-->>AI: 6. Tool definitions + AI->>MCP: 7. tools/call: search_devices + MCP->>API: 8. POST /mcp/sse/devices/search + API->>DB: 9. Query devices + DB-->>API: 10. Device data + API-->>MCP: 11. JSON response + MCP-->>AI: 12. Tool result +``` + +### Component Architecture + +```mermaid +graph LR + subgraph "AI Client" + A[Claude Desktop] + B[Custom MCP Client] + end + + subgraph "NetAlertX MCP Server (:20212)" + C[SSE Endpoint
/mcp/sse] + D[Message Handler
/mcp/messages] + E[OpenAPI Spec
/mcp/sse/openapi.json] + end + + subgraph "NetAlertX API Server (:20211)" + F[Device APIs
/mcp/sse/devices/*] + G[Network Tools
/mcp/sse/nettools/*] + H[Events API
/mcp/sse/events/*] + end + + subgraph "Backend" + I[SQLite Database] + J[Network Scanners] + K[Plugin System] + end + + A -.->|Bearer Auth| C + B -.->|Bearer Auth| C + C --> D + C --> E + D --> F + D --> G + D --> H + F --> I + G --> J + H --> I + + style A fill:#e1f5fe + style B fill:#e1f5fe + style C fill:#f3e5f5 + style D fill:#f3e5f5 + style E fill:#f3e5f5 + style F fill:#fff3e0 + style G fill:#fff3e0 + style H fill:#fff3e0 +``` + +--- + ## Authentication MCP endpoints use the same **Bearer token authentication** as REST endpoints: diff --git a/server/api_server/api_server_start.py b/server/api_server/api_server_start.py index 7da8378f..184adf93 100755 --- a/server/api_server/api_server_start.py +++ b/server/api_server/api_server_start.py @@ -112,7 +112,7 @@ CORS( ) # ------------------------------------------------------------------------------- -# MCP bridge variables + helpers +# MCP bridge variables + helpers # ------------------------------------------------------------------------------- BACKEND_PORT = get_setting_value("GRAPHQL_PORT") @@ -142,7 +142,7 @@ def log_request_info(): # Filter out noisy requests if needed, but user asked for drastic logging mylog("verbose", [f"[HTTP] {request.method} {request.path} from {request.remote_addr}"]) # Filter sensitive headers before logging - safe_headers = {k: v for k, v in request.headers if k.lower() not in ('authorization', 'cookie', 'x-api-key')} + safe_headers = {k: v for k, v in request.headers.items() if k.lower() not in ('authorization', 'cookie', 'x-api-key')} mylog("debug", [f"[HTTP] Headers: {safe_headers}"]) if request.method == "POST": # Be careful with large bodies, but log first 1000 chars diff --git a/test/api_endpoints/test_mcp_tools_endpoints.py b/test/api_endpoints/test_mcp_tools_endpoints.py index 3c1b68cd..92329ba1 100644 --- a/test/api_endpoints/test_mcp_tools_endpoints.py +++ b/test/api_endpoints/test_mcp_tools_endpoints.py @@ -303,4 +303,4 @@ def test_openapi_spec(client, api_token): assert "/devices/network/topology" in spec["paths"] assert "/events/recent" in spec["paths"] assert "/device/{mac}/set-alias" in spec["paths"] - assert "/nettools/wakeonlan" in spec["paths"] \ No newline at end of file + assert "/nettools/wakeonlan" in spec["paths"]