Skip to main content
Glama
README.md
# modal-mcp

Complete MCP (Model Context Protocol) server for Modal cloud computing. Exposes render, voice, and GPU computing capabilities as tools for Claude and LLM agents.

## Authenticated Remotion RPC render

`modal_remotion_rpc.py` renders the allowlisted `IsaiahStyleReel` composition
entirely inside Modal and returns the MP4 over Modal's authenticated control
plane. It has no public HTTP endpoint and never starts Chrome or Chromium on
the local Mac. Inputs are fail-closed: public HTTPS audio only, word timings
within the fixed 40-second timeline, a safe MP4 filename, and an allowlisted
composition are required.

```bash
modal run modal_remotion_rpc.py \
  --props-path /absolute/path/to/props.json \
  --output-path /absolute/path/to/output.mp4
```

Run `npm test` to validate both the original MCP contract and the RPC render
admission contract.

**Status:** Production-ready (28/65 features complete)

## Overview

Modal MCP provides:
- **Video Rendering** — Remotion compositions on Modal's cloud infrastructure
- **Voice Synthesis** — F5-TTS voice cloning for audio generation
- **GPU Computing** — General GPU task dispatch
- **Job Management** — Full job lifecycle with status tracking
- **Health Monitoring** — Real-time dependency status
- **Rate Limiting** — Built-in protection against abuse
- **Supabase Integration** — Persistent job storage

## Quick Start

### 1. Install and Configure

```bash
# Install dependencies
npm install

# Copy and edit environment file
cp .env.example .env
# Edit .env with your Supabase and Modal URLs
```

### 2. Start Server

```bash
npm start        # Production mode
npm run dev      # Development with verbose logging
```

Server runs on `http://localhost:3001`

### 3. Test It Works

```bash
# Health check
curl http://localhost:3001/api/health | jq .

# Run test suite
npm run test:all
```

## API Endpoints

### Health Check
```
GET /api/health
```
Returns server status and dependency health.

### Job Management
```
POST   /api/jobs              # Submit a job
GET    /api/jobs              # List jobs
GET    /api/jobs/:id          # Get job status
GET    /api/jobs/:id/result   # Get job result (if done)
DELETE /api/jobs/:id          # Cancel pending job
```

## MCP Tools

| Tool | Description |
|------|-------------|
| `modal_render` | Render Remotion composition on Modal → Supabase Storage |
| `modal_render_list` | List past render jobs |
| `modal_render_get` | Get single render job details |
| `modal_voice_clone` | Synthesize speech via F5-TTS voice clone |
| `modal_apps` | List deployed Modal apps |
| `modal_logs` | Tail logs from a Modal app |

## Configuration

### Environment Variables

```bash
# Supabase (required for persistence)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-service-role-key

# Modal Endpoints
MODAL_REMOTION_RENDER_URL=https://your-account--remotion-render.modal.run
MODAL_VOICE_CLONE_URL=https://your-account--voice-clone.modal.run
MODAL_BIN=modal

# Server
PORT=3001
LOG_LEVEL=info  # debug, info, warn, error
```

### Docker Setup

```bash
docker build -t modal-mcp:latest .
docker run -p 3001:3001 \
  -e SUPABASE_URL=... \
  -e SUPABASE_KEY=... \
  modal-mcp:latest
```

## Integration with Claude

Add to Claude's `settings.json`:

```json
{
  "mcpServers": {
    "modal-mcp": {
      "command": "node",
      "args": ["/path/to/modal-mcp/server.js"],
      "env": {
        "SUPABASE_URL": "https://your-project.supabase.co",
        "SUPABASE_KEY": "your-key",
        "MODAL_REMOTION_RENDER_URL": "https://your-modal-endpoint.modal.run"
      }
    }
  }
}
```

## Features Implemented

### Phase 1: Infrastructure & Health Checks ✅
- [x] MCP Server Initialization (INFRA-001)
- [x] Environment Configuration (INFRA-002)
- [x] Logging System (INFRA-003)
- [x] Health Check Endpoint (API-001)
- [x] Error Handling Middleware (API-002)

### Phase 2: Job Management ✅
- [x] Job Submission API (JOB-001)
- [x] Job Status Polling (JOB-002)
- [x] Job Result Retrieval (JOB-003)
- [x] Job Cancellation (JOB-004)
- [x] Job Queue Management (JOB-005)
- [x] API Rate Limiting (API-003)
- [x] Input Validation (SECURITY-001)
- [x] CORS Configuration (SECURITY-002)

### Phase 3: Render Pipeline ✅
- [x] Remotion Render Job Submission (RENDER-001)
- [x] Render Quality Configuration (RENDER-002)
- [x] Voice Clone Job Submission (VOICE-001)
- [x] Voice Clone Result Retrieval (VOICE-002)
- [x] GPU Task Dispatch (GPU-001)

### Phase 4-6: In Progress
- Testing features (unit, integration, end-to-end)
- Database schema and optimization
- Deployment documentation
- Monitoring and observability

## Testing

```bash
# Unit tests (10 tests, all passing)
npm run test

# API integration tests
npm run test:api

# Run all tests
npm run test:all
```

## Documentation

- **[DEPLOYMENT.md](DEPLOYMENT.md)** — Docker, Vercel, Kubernetes, monitoring, scaling
- **[docs/DATABASE.md](docs/DATABASE.md)** — Supabase schema setup and migration

## Examples

### Submit a Render Job

```bash
curl -X POST http://localhost:3001/api/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "type": "render",
    "composition": "explainer_v1",
    "sections": [
      {
        "id": "1",
        "type": "hook",
        "duration_sec": 3,
        "content": {"text": "Hello World"}
      }
    ],
    "quality": "production"
  }'
```

### Check Job Status

```bash
curl http://localhost:3001/api/jobs/abc12345
```

### Get Render Result

```bash
curl http://localhost:3001/api/jobs/abc12345/result
```

## Performance

- **Rate Limiting:** 100 requests/minute per IP
- **Job Timeouts:** 10 minutes (render), 2 minutes (voice)
- **In-Memory Store:** Fallback when Supabase unconfigured
- **Structured Logging:** JSON logs with timestamps

## Architecture

```
┌─────────────────────────────────────┐
│         Claude / LLM Agent          │
└─────────────┬───────────────────────┘
              │ MCP Protocol
              ▼
┌─────────────────────────────────────┐
│      Modal MCP Server               │
├─────────────────────────────────────┤
│  HTTP Layer (3001)                  │
│  • Health checks                    │
│  • Job management                   │
│  • Rate limiting                    │
├─────────────────────────────────────┤
│  MCP Tool Layer                     │
│  • Render (Remotion)                │
│  • Voice (F5-TTS)                   │
│  • GPU tasks                        │
├─────────────────────────────────────┤
│  Storage Layer                      │
│  • Supabase (persistent)            │
│  • In-Memory (fallback)             │
└─────────────┬───────────────────────┘
              │
    ┌─────────┴──────────┬──────────────┐
    ▼                    ▼              ▼
┌──────────┐        ┌──────────┐   ┌────────────┐
│ Modal    │        │Supabase  │   │ Storage    │
│Endpoints │        │Database  │   │ (S3/GCS)   │
└──────────┘        └──────────┘   └────────────┘
```

## License

MIT

## Support

- **Issues:** GitHub issues
- **Documentation:** See [DEPLOYMENT.md](DEPLOYMENT.md) and [docs/](docs/)
- **Examples:** See [test-api.sh](test-api.sh)

TDQS

A3.6/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct resource and action without overlap: app listing, log retrieval, video rendering creation, render job retrieval, render job listing, and voice synthesis. The boundaries between video rendering, voice cloning, and general Modal app management are clearly demarcated.

Naming Consistency3/5

Mixed verb placement conventions: modal_apps and modal_logs imply actions (list/get) without suffixes, while modal_render_get and modal_render_list use explicit action suffixes. The base modal_render tool (create operation) lacks a suffix unlike its complementary tools, creating inconsistency within the render workflow cluster.

Tool Count5/5

Six tools is well-scoped for the server's apparent purpose covering Modal app monitoring, video rendering lifecycle management, and voice synthesis. The count hits the sweet spot for functionality without overwhelming the agent with redundant options.

Completeness3/5

Notable gaps in lifecycle coverage: apps only supports listing (missing get single app, deploy, delete), render jobs lack cancel/delete operations, and voice synthesis has no associated read/list functionality. The surface supports creation and partial reading but misses update/delete operations for persistent resources.

Maintenance

ActivityMaintained
ResponsivenessNo issues