Skip to main content
The Claudio web dashboard provides a visual interface to monitor your MCPs, chat with Claudio in real-time, and access documentation without leaving your browser.

Features

  • MCP monitoring: View all configured MCPs with health status
  • Live chat: WebSocket-powered chat with Claude Code CLI
  • Health checks: Test MCP availability and configuration
  • Documentation browser: Access integration guides and workflows
  • Context viewer: Read the current CLAUDE.md configuration
  • REST API: Programmatic access to all features

Quick start

1

Install dependencies

From the Claudio root directory:
source venv/bin/activate
pip install -r channels/web/requirements.txt
2

Start the server

cd channels/web
./start.sh
The server starts on http://localhost:8000.
3

Open the dashboard

Navigate to http://localhost:8000 in your browser.

Configuration

The dashboard reads configuration from environment variables (.env in project root):
.env
# Path to Claude CLI executable
CLAUDE_CLI_PATH=claude

# Working directory for command execution
WORKSPACE_PATH=/Users/yourname/Dev/claudio

# Maximum command execution time (seconds)
COMMAND_TIMEOUT=1800

# Skip MCP permission prompts
SKIP_PERMISSIONS=true
The dashboard automatically loads MCP configuration from mcp/cursor-config.json. Source: channels/web/app.py:38-41

Dashboard pages

Main dashboard (/)

Displays:
  • MCP overview: Cards showing each configured MCP with icon and type
  • Quick stats: Total MCP count
  • Integration docs: Links to integration guides
  • Workflows: Available multi-MCP workflows
Source: channels/web/app.py:419-443

Chat page (/chat)

Full-screen chat interface with:
  • Real-time streaming responses via WebSocket
  • Message history
  • New session button to reset context
  • Connection status indicator
Source: channels/web/app.py:413-416

API endpoints

MCP endpoints

curl http://localhost:8000/api/mcps

GET /api/mcps

Returns all configured MCPs from cursor-config.json:
{
  "github": {
    "url": "https://api.githubcopilot.com/...",
    "env": {
      "GITHUB_PERSONAL_ACCESS_TOKEN": "..."
    }
  },
  "clickup": {
    "command": "npx",
    "args": ["-y", "@ModelContextProtocol/server-clickup"]
  }
}
Source: channels/web/app.py:446-450

GET /api/mcps/health

Runs health checks on all MCPs in parallel:
{
  "checked_at": "2026-02-28T10:30:00",
  "mcps": [
    {
      "name": "github",
      "status": "configured",
      "type": "remote",
      "icon": "🐙",
      "message": "Remote MCP configured"
    },
    {
      "name": "clickup",
      "status": "ready",
      "type": "npx",
      "icon": "✅",
      "message": "npx package: @ModelContextProtocol/server-clickup"
    }
  ]
}
Source: channels/web/app.py:453-466

Health status values

StatusIconMeaning
ready🟢MCP is installed and ready
configured🔵MCP is configured (not verified at runtime)
warning🟡MCP may have issues
error🔴MCP has errors
unknownStatus could not be determined
Source: channels/web/app.py:206-313

Documentation endpoints

curl http://localhost:8000/api/docs/integrations

GET /api/docs/{doc_type}

Returns available documentation files:
[
  {
    "name": "clickup",
    "path": "docs/integrations/clickup/guide.md",
    "has_config": true
  },
  {
    "name": "github",
    "path": "docs/integrations/github/guide.md",
    "has_config": false
  }
]
Source: channels/web/app.py:481-489

GET /api/docs/read?path=...

Reads and returns file content:
{
  "path": "docs/integrations/clickup/guide.md",
  "content": "# ClickUp Integration\n\n..."
}
For security, only files under docs/ can be accessed.
Source: channels/web/app.py:492-509

Context endpoint

curl http://localhost:8000/api/context
Returns the current CLAUDE.md file:
{
  "path": "CLAUDE.md",
  "content": "# Claudio - Asistente de Productividad...\n"
}
Source: channels/web/app.py:512-522

WebSocket chat

Connect to chat

const ws = new WebSocket('ws://localhost:8000/ws/chat');

ws.onopen = () => {
  console.log('Connected to Claudio');
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

Send a message

ws.send(JSON.stringify({
  type: 'message',
  content: 'List my open pull requests'
}));

Start a new session

ws.send(JSON.stringify({
  type: 'new_session'
}));

Message types

Client → Server

type ClientMessage = 
  | { type: 'message', content: string }
  | { type: 'new_session' };

Server → Client

type ServerMessage =
  | { type: 'start' }  // Command execution started
  | { type: 'chunk', content: string }  // Output chunk
  | { type: 'error', content: string }  // Error message
  | { type: 'done', success: boolean, returncode: number }  // Execution finished
  | { type: 'system', content: string };  // System message
Source: channels/web/app.py:360-408

MCP health checks

The dashboard performs smart health checks based on MCP type:

Remote MCPs (GitHub)

Verifies the URL is configured. Does not test connectivity to avoid exposing tokens.
{
  "status": "configured",
  "message": "Remote MCP configured: https://api.githubcopilot.com/..."
}
Source: channels/web/app.py:217-225

NPX packages

Checks if Node.js is available and identifies the package:
{
  "status": "ready",
  "message": "npx package: @ModelContextProtocol/server-clickup"
}
Source: channels/web/app.py:233-253

Python modules

Attempts to import the module:
{
  "status": "ready",
  "message": "Python module: granola_mcp"
}
Source: channels/web/app.py:255-277

Node scripts

Verifies the script file exists:
{
  "status": "ready",
  "message": "Node script: server.js"
}
Source: channels/web/app.py:279-291

File structure

channels/web/
├── app.py              # FastAPI application
├── templates/
│   ├── dashboard.html  # Main dashboard page
│   └── chat.html       # Full-screen chat page
├── requirements.txt    # Python dependencies
├── start.sh           # Launch script
└── README.md

Dependencies

The dashboard uses these packages:
requirements.txt
fastapi==0.109.0        # Web framework
uvicorn[standard]==0.27.0  # ASGI server
jinja2==3.1.3           # Template engine
python-multipart==0.0.6 # Form parsing
python-dotenv==1.0.1    # Environment variables
pyyaml==6.0.1           # YAML parsing
httpx==0.26.0           # Async HTTP client
websockets==12.0        # WebSocket support
Source: channels/web/requirements.txt

Development mode

Start the server with auto-reload for development:
cd channels/web
./start.sh --dev
Or manually:
uvicorn app:app --host 0.0.0.0 --port 8000 --reload
Changes to app.py or templates will trigger automatic reload.

Architecture

Browser
   |
   v
[HTTP Request / WebSocket]
   |
   v
FastAPI (app.py)
   |
   +---> Templates (Jinja2)
   |
   +---> MCP Config (cursor-config.json)
   |
   +---> ClaudeCodeExecutor
           |
           v
      Claude Code CLI (-p flag)
           |
           v
      ~/.claude.json
           |
           v
      MCPs (ClickUp, GitHub, etc.)
The dashboard reads MCP configuration from mcp/cursor-config.json and executes commands through ClaudeCodeExecutor, which streams output via WebSocket. Source: channels/web/app.py:61-166

Security considerations

File access restriction

The /api/docs/read endpoint only allows reading files under docs/:
if not str(full_path).startswith(str(DOCS_PATH)):
    raise HTTPException(status_code=403, detail="Access denied")
Source: channels/web/app.py:498-499

No authentication

The dashboard has no built-in authentication. Only run it on localhost or behind a reverse proxy with authentication.
For production deployment, add authentication middleware or use a reverse proxy like nginx with basic auth.

Health check safety

Health checks for remote MCPs don’t expose tokens:
# Only verify URL is configured, don't test connectivity
result["status"] = "configured"
result["message"] = f"Remote MCP configured: {config['url']}"
Source: channels/web/app.py:224-225

Stopping the server

Ctrl+C

Build docs developers (and LLMs) love