inou/docs/mcp-server-setup.md

213 lines
5.6 KiB
Markdown

# inou MCP Server - Technical Documentation
## Overview
The inou MCP (Model Context Protocol) server provides direct HTTPS access to health data for LLM integration. **No bridge is required** - Claude (Desktop/web) calls the server directly.
## Endpoint
**Production:** `https://inou.com/mcp`
**Staging:** `https://dev.inou.com/mcp`
## Architecture
```
┌─────────────────┐
│ Claude Desktop │
│ or Web App │
└────────┬────────┘
│ HTTPS (Streamable HTTP transport)
│ OAuth 2.0 Bearer token
┌─────────────────┐
│ inou.com/mcp │
│ (Portal Service)│
└────────┬────────┘
┌─────────────────┐
│ lib (RBAC) │
│ + SQLite DB │
└─────────────────┘
```
**No bridge, no stdio, no localhost proxy.**
## Protocol
- **Transport:** Streamable HTTP ([MCP Specification](https://modelcontextprotocol.io/specification/draft/basic/transports#http-with-sse))
- **Protocol Version:** `2025-06-18`
- **Server Name:** `inou-health`
- **Server Version:** `1.0.0`
## Authentication
### OAuth 2.0 Flow
MCP uses standard OAuth 2.0 Authorization Code flow with PKCE:
1. **Authorization:** `https://inou.com/oauth/authorize`
2. **Token Exchange:** `https://inou.com/oauth/token`
3. **UserInfo:** `https://inou.com/oauth/userinfo`
4. **Token Revocation:** `https://inou.com/oauth/revoke`
### OAuth Metadata Endpoints
- **Authorization Server Metadata:** `https://inou.com/.well-known/oauth-authorization-server`
- **Protected Resource Metadata:** `https://inou.com/.well-known/oauth-protected-resource`
### Using Access Tokens
MCP requests include the OAuth access token in the Authorization header:
```http
POST /mcp HTTP/1.1
Host: inou.com
Authorization: Bearer {access_token}
Content-Type: application/json
```
The portal's MCP handler:
1. Extracts the access token
2. Looks up the associated dossier (user)
3. Creates an AccessContext for RBAC enforcement
4. Routes to the appropriate tool handler
## Available Tools
All tools enforce RBAC - users can only access data they have permission to view.
### Imaging Tools
- `list_dossiers` - List accessible patient dossiers
- `list_studies` - List imaging studies (MRI, CT, X-ray)
- `list_series` - List series within a study (filter by AX, T1, FLAIR, etc.)
- `list_slices` - List individual slices with position metadata
- `fetch_image` - Fetch slice image as base64 PNG (with optional window/level)
- `fetch_contact_sheet` - Thumbnail grid for navigation (**NOT for diagnosis**)
### Lab Tools
- `get_categories` - List available data categories with entry counts
- `query_entries` - Query entries by category (labs, documents, etc.)
### Genome Tools
- `query_genome` - Query genetic variants by gene, rsid, category, or free-text search
### System Tools
- `get_version` - Server version info
## Implementation
The MCP server is implemented in the **portal** service (`portal/mcp_http.go`):
- **MCP Request Handler:** `handleMCPRequest()` - routes JSON-RPC calls
- **Tool Implementations:** `portal/mcp_tools.go` - all 11 tool handlers
- **OAuth Handlers:** Dynamic client registration, token exchange, userinfo
- **Session Management:** OAuth sessions stored in database
## Security
1. **OAuth 2.0** - Standard authorization framework
2. **RBAC** - All data access enforced at entry level
3. **FIPS 140-3** - Encryption for data at rest
4. **Read-Only** - All MCP tools are read-only (no mutations)
5. **Audit Logging** - All MCP access logged to audit table
## Testing
### Manual Test (curl)
```bash
# 1. Get an OAuth token (you'll need client credentials)
curl -X POST https://inou.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code={code}&client_id={client_id}&client_secret={client_secret}"
# 2. Call MCP with token
curl -X POST https://inou.com/mcp \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_dossiers",
"arguments": {}
}
}'
```
### Claude Desktop Integration
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"inou": {
"url": "https://inou.com/mcp",
"transport": {
"type": "http"
}
}
}
}
```
Claude Desktop handles OAuth flow automatically.
## Development
**Local Development:**
```bash
# Portal runs on :8081, proxied through nginx at localhost
# MCP endpoint: https://localhost/mcp
```
**Staging:**
```bash
# https://dev.inou.com/mcp
# Test OAuth with staging credentials
```
**Production:**
```bash
# https://inou.com/mcp
# Production OAuth client registered in database
```
## Related Files
- `portal/mcp_http.go` - MCP server implementation
- `portal/mcp_tools.go` - Tool handlers
- `portal/oauth.go` - OAuth 2.0 handlers
- `docs/mcp-usage-examples.md` - Usage examples for end users
- `docs/anthropic-submission.md` - Connector directory submission
## Troubleshooting
**Images not loading:**
- Check OAuth token is valid
- Verify RBAC permissions (CheckAccess logs)
- Check object storage has files (du -sh /tank/inou/objects/)
**"Unauthorized" errors:**
- Token expired (tokens are valid for 1 hour)
- User lacks access to requested dossier
- Check audit log for access attempts
**Empty responses:**
- RBAC blocking access
- No data exists for query
- Check lib logs for errors