inou/docs/mcp-server-setup.md

5.6 KiB

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)
  • 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:

POST /mcp HTTP/1.1
Host: inou.com
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": { ... }
}

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)

# 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:

{
  "mcpServers": {
    "inou": {
      "url": "https://inou.com/mcp",
      "transport": {
        "type": "http"
      }
    }
  }
}

Claude Desktop handles OAuth flow automatically.

Development

Local Development:

# Portal runs on :8081, proxied through nginx at localhost
# MCP endpoint: https://localhost/mcp

Staging:

# https://dev.inou.com/mcp
# Test OAuth with staging credentials

Production:

# https://inou.com/mcp
# Production OAuth client registered in database
  • 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