|
| 1 | +# MCP Proxy - Sentrius Integration |
| 2 | + |
| 3 | +This document describes the MCP (Model Context Protocol) proxy implementation in Sentrius, which provides secure MCP endpoints with full zero trust security integration. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The MCP proxy allows AI agents to communicate using the standardized Model Context Protocol while maintaining Sentrius's zero trust security model. All MCP requests are authenticated, authorized, and tracked for audit purposes. |
| 8 | + |
| 9 | +## Security Features |
| 10 | + |
| 11 | +- **JWT Authentication**: All requests require valid Keycloak JWT tokens |
| 12 | +- **Access Control**: Uses `@LimitAccess` annotations for fine-grained permissions |
| 13 | +- **Provenance Tracking**: All MCP operations are logged for audit trails |
| 14 | +- **Zero Trust Validation**: Follows existing Sentrius security patterns |
| 15 | + |
| 16 | +## API Endpoints |
| 17 | + |
| 18 | +### HTTP Endpoints |
| 19 | + |
| 20 | +#### 1. MCP Request Processing |
| 21 | +``` |
| 22 | +POST /api/v1/mcp/ |
| 23 | +``` |
| 24 | + |
| 25 | +**Headers:** |
| 26 | +- `Authorization: Bearer <jwt-token>` |
| 27 | +- `communication_id: <unique-communication-id>` |
| 28 | +- `Content-Type: application/json` |
| 29 | + |
| 30 | +**Request Body:** |
| 31 | +```json |
| 32 | +{ |
| 33 | + "jsonrpc": "2.0", |
| 34 | + "id": "request-id", |
| 35 | + "method": "method-name", |
| 36 | + "params": { |
| 37 | + "key": "value" |
| 38 | + } |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +**Response:** |
| 43 | +```json |
| 44 | +{ |
| 45 | + "jsonrpc": "2.0", |
| 46 | + "id": "request-id", |
| 47 | + "result": { |
| 48 | + "response": "data" |
| 49 | + } |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +#### 2. Capabilities Discovery |
| 54 | +``` |
| 55 | +GET /api/v1/mcp/capabilities |
| 56 | +``` |
| 57 | + |
| 58 | +**Headers:** |
| 59 | +- `Authorization: Bearer <jwt-token>` |
| 60 | + |
| 61 | +**Response:** |
| 62 | +```json |
| 63 | +{ |
| 64 | + "protocolVersion": "2024-11-05", |
| 65 | + "capabilities": { |
| 66 | + "tools": {"listChanged": true}, |
| 67 | + "resources": {"subscribe": true, "listChanged": true}, |
| 68 | + "prompts": {"listChanged": true} |
| 69 | + }, |
| 70 | + "serverInfo": { |
| 71 | + "name": "Sentrius MCP Proxy", |
| 72 | + "version": "1.0.0" |
| 73 | + } |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +#### 3. Health Check |
| 78 | +``` |
| 79 | +GET /api/v1/mcp/health |
| 80 | +``` |
| 81 | + |
| 82 | +**Response:** |
| 83 | +```json |
| 84 | +{ |
| 85 | + "status": "healthy", |
| 86 | + "service": "mcp-proxy", |
| 87 | + "timestamp": "2024-11-05T10:30:00Z" |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +### WebSocket Endpoint |
| 92 | + |
| 93 | +#### Real-time MCP Communication |
| 94 | +``` |
| 95 | +WebSocket: /api/v1/mcp/ws |
| 96 | +``` |
| 97 | + |
| 98 | +**Connection Parameters:** |
| 99 | +- Query parameter: `token=Bearer <jwt-token>` |
| 100 | +- Query parameter: `communication_id=<unique-id>` |
| 101 | +- Query parameter: `user_id=<user-id>` |
| 102 | + |
| 103 | +**Message Format:** |
| 104 | +Same as HTTP endpoint but sent as WebSocket messages. |
| 105 | + |
| 106 | +## Supported MCP Methods |
| 107 | + |
| 108 | +### Core Methods |
| 109 | +- `initialize` - Initialize MCP session and get capabilities |
| 110 | +- `ping` - Connectivity check |
| 111 | + |
| 112 | +### Tools |
| 113 | +- `tools/list` - List available tools |
| 114 | +- `tools/call` - Execute a tool with parameters |
| 115 | + |
| 116 | +### Resources |
| 117 | +- `resources/list` - List available resources |
| 118 | +- `resources/read` - Read a specific resource |
| 119 | + |
| 120 | +### Prompts |
| 121 | +- `prompts/list` - List available prompts |
| 122 | +- `prompts/get` - Get a specific prompt |
| 123 | + |
| 124 | +### LLM Integration |
| 125 | +- `completion` - Request LLM completion (delegates to existing LLM services) |
| 126 | + |
| 127 | +## Usage Examples |
| 128 | + |
| 129 | +### 1. Initialize MCP Session |
| 130 | + |
| 131 | +```bash |
| 132 | +curl -X POST http://localhost:8080/api/v1/mcp/ \ |
| 133 | + -H "Authorization: Bearer YOUR_JWT_TOKEN" \ |
| 134 | + -H "communication_id: init-session-123" \ |
| 135 | + -H "Content-Type: application/json" \ |
| 136 | + -d '{ |
| 137 | + "jsonrpc": "2.0", |
| 138 | + "id": "init-1", |
| 139 | + "method": "initialize", |
| 140 | + "params": {} |
| 141 | + }' |
| 142 | +``` |
| 143 | + |
| 144 | +### 2. List Available Tools |
| 145 | + |
| 146 | +```bash |
| 147 | +curl -X POST http://localhost:8080/api/v1/mcp/ \ |
| 148 | + -H "Authorization: Bearer YOUR_JWT_TOKEN" \ |
| 149 | + -H "communication_id: tools-session-123" \ |
| 150 | + -H "Content-Type: application/json" \ |
| 151 | + -d '{ |
| 152 | + "jsonrpc": "2.0", |
| 153 | + "id": "tools-1", |
| 154 | + "method": "tools/list", |
| 155 | + "params": {} |
| 156 | + }' |
| 157 | +``` |
| 158 | + |
| 159 | +### 3. Execute a Tool |
| 160 | + |
| 161 | +```bash |
| 162 | +curl -X POST http://localhost:8080/api/v1/mcp/ \ |
| 163 | + -H "Authorization: Bearer YOUR_JWT_TOKEN" \ |
| 164 | + -H "communication_id: exec-session-123" \ |
| 165 | + -H "Content-Type: application/json" \ |
| 166 | + -d '{ |
| 167 | + "jsonrpc": "2.0", |
| 168 | + "id": "exec-1", |
| 169 | + "method": "tools/call", |
| 170 | + "params": { |
| 171 | + "name": "secure_command", |
| 172 | + "arguments": { |
| 173 | + "command": "ls -la" |
| 174 | + } |
| 175 | + } |
| 176 | + }' |
| 177 | +``` |
| 178 | + |
| 179 | +### 4. WebSocket Connection (JavaScript) |
| 180 | + |
| 181 | +```javascript |
| 182 | +const token = "YOUR_JWT_TOKEN"; |
| 183 | +const communicationId = "ws-session-123"; |
| 184 | +const userId = "user-123"; |
| 185 | + |
| 186 | +const ws = new WebSocket(`ws://localhost:8080/api/v1/mcp/ws?token=Bearer%20${token}&communication_id=${communicationId}&user_id=${userId}`); |
| 187 | + |
| 188 | +ws.onopen = function(event) { |
| 189 | + console.log('MCP WebSocket connected'); |
| 190 | + |
| 191 | + // Send ping request |
| 192 | + ws.send(JSON.stringify({ |
| 193 | + jsonrpc: "2.0", |
| 194 | + id: "ping-1", |
| 195 | + method: "ping", |
| 196 | + params: {} |
| 197 | + })); |
| 198 | +}; |
| 199 | + |
| 200 | +ws.onmessage = function(event) { |
| 201 | + const response = JSON.parse(event.data); |
| 202 | + console.log('MCP Response:', response); |
| 203 | +}; |
| 204 | +``` |
| 205 | + |
| 206 | +## Error Handling |
| 207 | + |
| 208 | +The MCP proxy returns standard JSON-RPC error responses: |
| 209 | + |
| 210 | +```json |
| 211 | +{ |
| 212 | + "jsonrpc": "2.0", |
| 213 | + "id": "request-id", |
| 214 | + "error": { |
| 215 | + "code": -32602, |
| 216 | + "message": "Invalid params", |
| 217 | + "data": null |
| 218 | + } |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +**Standard Error Codes:** |
| 223 | +- `-32700` Parse error |
| 224 | +- `-32600` Invalid request |
| 225 | +- `-32601` Method not found |
| 226 | +- `-32602` Invalid params |
| 227 | +- `-32603` Internal error |
| 228 | +- `-32001` Unauthorized |
| 229 | +- `-32002` Forbidden |
| 230 | + |
| 231 | +## Configuration |
| 232 | + |
| 233 | +The MCP proxy is automatically configured when the `llm-proxy` module is deployed. No additional configuration is required beyond the standard Sentrius authentication setup. |
| 234 | + |
| 235 | +### Required Environment Variables |
| 236 | + |
| 237 | +- `KEYCLOAK_BASE_URL` - Keycloak server URL |
| 238 | +- `KEYCLOAK_SECRET` - Client secret for authentication |
| 239 | +- Standard Sentrius database and Kafka configuration |
| 240 | + |
| 241 | +## Security Considerations |
| 242 | + |
| 243 | +1. **Authentication**: All requests must include valid JWT tokens |
| 244 | +2. **Authorization**: Uses existing Sentrius role-based access control |
| 245 | +3. **Audit Trail**: All MCP operations are logged to Kafka for provenance tracking |
| 246 | +4. **Rate Limiting**: Inherits rate limiting from Spring Boot actuator |
| 247 | +5. **HTTPS**: Should be deployed with HTTPS in production |
| 248 | + |
| 249 | +## Integration with Existing Services |
| 250 | + |
| 251 | +The MCP proxy integrates seamlessly with existing Sentrius services: |
| 252 | + |
| 253 | +- **Keycloak Service**: For JWT validation |
| 254 | +- **User Service**: For user context and authorization |
| 255 | +- **Provenance Service**: For audit logging |
| 256 | +- **Zero Trust Services**: For ZTAT token validation (when needed) |
| 257 | +- **LLM Services**: For delegation of completion requests |
| 258 | + |
| 259 | +## Testing |
| 260 | + |
| 261 | +Run the MCP proxy tests: |
| 262 | + |
| 263 | +```bash |
| 264 | +mvn test -pl llm-proxy -Dtest="*MCP*" |
| 265 | +``` |
| 266 | + |
| 267 | +## Monitoring |
| 268 | + |
| 269 | +The MCP proxy provides health checks and metrics through: |
| 270 | + |
| 271 | +- Health endpoint: `/api/v1/mcp/health` |
| 272 | +- Spring Boot Actuator: `/actuator/health` |
| 273 | +- OpenTelemetry tracing integration |
| 274 | +- Kafka provenance events for monitoring |
| 275 | + |
| 276 | +## Future Enhancements |
| 277 | + |
| 278 | +Potential future improvements: |
| 279 | + |
| 280 | +1. **Additional MCP Methods**: Support for more MCP protocol methods |
| 281 | +2. **Tool Integration**: Direct integration with Sentrius SSH tools |
| 282 | +3. **Resource Providers**: Integration with Sentrius resource management |
| 283 | +4. **Prompt Management**: Database-backed prompt storage |
| 284 | +5. **Binary Protocol**: Support for binary MCP messages over WebSocket |
0 commit comments