happy-mcp-server
v1.2.0
Published
MCP server for observing and controlling Happy Coder sessions
Maintainers
Readme
happy-mcp-server
An MCP (Model Context Protocol) server that lets AI assistants observe and control active Happy Coder sessions. It connects to the Happy relay server via end-to-end encrypted channels, enabling remote session monitoring, message sending, permission management, and session control.
Quick Start
1. Install
npm i -g happy-mcp-server2. Authenticate
Option A: MCP-based authentication (Recommended for Claude Cowork)
Add the server to your MCP client configuration (see MCP Configuration below), then call the authentication_status tool from within your MCP client. The tool returns a QR code and web URL for pairing. Once you scan the QR code with the Happy mobile app, tools activate automatically.
Option B: CLI authentication
happy-mcp-server authScan the QR code with the Happy mobile app to pair your account. This creates credentials at ~/.happy-mcp/credentials.json.
Option C: Environment variable authentication
For ephemeral environments (Claude Cowork, Docker, CI/CD), set the HAPPY_MCP_ACCOUNT_SECRET environment variable:
export HAPPY_MCP_ACCOUNT_SECRET=$(cat ~/.happy-mcp/credentials.json | jq -r .secret)When set, authentication happens instantly on startup with no QR code or credential file required.
3. Choose Your Transport
Option A: Stdio Transport (Default)
Configure happy-mcp-server in your MCP client. See MCP Configuration below.
Option B: HTTP Transport
Start the server with HTTP transport:
happy-mcp-server serve
# Or specify a port:
happy-mcp-server serve --port 3000The server will start at http://127.0.0.1:<port>/mcp (port auto-assigned if not specified).
Commands
happy-mcp-server provides several commands for different modes and authentication:
| Command | Description |
|---------|-------------|
| happy-mcp-server | Start the MCP server using stdio transport (default). Use this mode when configuring the server in MCP clients like Claude Desktop, Claude Code, Cursor, etc. |
| happy-mcp-server serve | Start the MCP server using HTTP transport on an auto-assigned port. The server binds to 127.0.0.1 and reports the listening port and endpoint URL on startup. |
| happy-mcp-server serve --port <port> | Start the HTTP server on a specific port (1-65535). Useful when you need a predictable port number for client configuration or firewall rules. |
| happy-mcp-server auth | Check authentication status. If not authenticated, prompts you to scan a QR code with the Happy mobile app to pair your account. |
| happy-mcp-server auth login | Force a new pairing flow, even if already authenticated. Use this to switch accounts or re-authenticate. |
| happy-mcp-server auth logout | Remove saved credentials from ~/.happy-mcp/credentials.json. |
| happy-mcp-server help | Display help message with available commands. |
Transport Comparison
| Feature | Stdio Transport | HTTP Transport |
|---------|----------------|----------------|
| Use case | MCP client integration (Claude Desktop, Cursor, etc.) | Custom clients, testing, or programmatic access |
| Command | happy-mcp-server | happy-mcp-server serve [--port <port>] |
| Communication | Standard input/output streams | HTTP POST/GET/DELETE to /mcp endpoint |
| Port | N/A (uses stdio) | Auto-assigned or specified with --port |
| Accessibility | Only via client process | HTTP endpoint on localhost (127.0.0.1) |
| Authentication | Lazy (authenticates on first tool call if needed) | Required before startup (fails if credentials missing) |
Configuration
Environment variables customize server behavior:
| Variable | Default | Description |
|----------|---------|-------------|
| HAPPY_SERVER_URL | https://api.cluster-fluster.com | Happy relay server URL. |
| HAPPY_MCP_ACCOUNT_SECRET | (none) | Base64-encoded 32-byte account secret for instant authentication. When set, bypasses credential file and QR pairing. Obtain via: cat ~/.happy-mcp/credentials.json \| jq -r .secret |
| HAPPY_MCP_COMPUTERS | os.hostname() | Comma-separated list of computer hostnames to filter sessions and machines. Use * to show all computers. |
| HAPPY_MCP_PROJECT_PATHS | process.cwd() | Comma-separated list of project path prefixes to filter sessions. Use * to show all paths. |
| HAPPY_MCP_CREDENTIALS_PATH | ~/.happy-mcp/credentials.json | Path to credentials file |
| HAPPY_MCP_LOG_LEVEL | warn | Log level: debug, info, warn, or error. Logs are written to stderr. |
| HAPPY_MCP_SESSION_CACHE_TTL | 300 | Session cache TTL in seconds |
| HAPPY_MCP_ENABLE_START | true | Set to false to disable the start_session tool. |
Available Tools
When authenticated, happy-mcp-server exposes 11 MCP tools grouped into three categories. When unauthenticated, only the authentication_status tool is available to initiate QR-based pairing.
Tool Summary
| Tool | Category | Description |
|------|----------|-------------|
| list_computers | Discovery | List available computers filtered by HAPPY_MCP_COMPUTERS |
| list_sessions | Discovery | List active sessions with status and pending permissions |
| get_session | Discovery | Get detailed info and recent messages for a session |
| watch_session | Discovery | Wait for session state changes (idle, permission pending) |
| send_message | Session Control | Send a message to a session; optionally change permission mode |
| start_session | Session Control | Start a new session on a remote machine |
| stop_session | Session Control | Stop and archive a running session |
| interrupt_session | Session Control | Abort current activity without terminating the session |
| approve_permission | Permission Management | Approve a pending permission request |
| deny_permission | Permission Management | Deny a pending permission request |
| answer_question | Permission Management | Answer an AskUserQuestion prompt from a session |
Discovery Tools
list_computers
List available computers filtered by HAPPY_MCP_COMPUTERS. Shows hostname, online status, and active session count. Use before start_session to find available machines.
No parameters.
list_sessions
List all active Happy Coder sessions. Shows session ID, project path, hostname, status (active/idle/waiting_permission), and pending permissions.
Results are pre-filtered by HAPPY_MCP_COMPUTERS and HAPPY_MCP_PROJECT_PATHS unless those variables are set to *.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| filter | object | No | — | Filter criteria |
| filter.status | enum | No | — | Filter by session status: active, idle, or waiting_permission |
| filter.computer | string | No | — | Filter by computer hostname |
| filter.projectPath | string | No | — | Filter by project path prefix |
get_session
Get detailed information about a specific session including recent messages, metadata, and pending permissions.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID (from list_sessions) |
| includeMessages | boolean | No | true | Whether to include recent messages |
| lastN | number | No | 20 | Number of recent messages to return |
| after | string | No | — | ISO 8601 timestamp — only return messages after this time |
watch_session
Watch one or more sessions for state changes. Returns immediately if any session is idle or has pending permissions. Otherwise waits up to 5 minutes for a state change. If sessions are still active when the timeout is reached, returns current status — call again to continue watching.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionIds | string[] | Yes | — | One or more session IDs to watch |
| timeoutSeconds | number | No | 300 | Maximum wait time in seconds |
Session Control Tools
send_message
Send a message to a Happy Coder session. The message appears as a user message in the session. If the session is actively generating, the message is queued and processed when the session is ready. Can optionally change the permission mode.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID to send the message to |
| message | string | Yes | — | Message text to send |
| meta | object | No | — | Optional metadata |
| meta.permissionMode | enum | No | — | Permission mode: default, acceptEdits, bypassPermissions, plan, read-only, safe-yolo, yolo |
| meta.allowedTools | string[] | No | — | Tools to allow |
| meta.disallowedTools | string[] | No | — | Tools to disallow |
start_session
Start a new Happy Coder session on a remote machine. Requires the machine to be online. Use list_computers to find available machines.
Disabled when
HAPPY_MCP_ENABLE_START=false.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| computer | string | Yes | — | Machine ID (from list_computers) |
| projectPath | string | Yes | — | Working directory for the new session |
| initialMessage | string | No | — | Message to send after the session starts |
| permissionMode | enum | No | — | Permission mode: default, acceptEdits, bypassPermissions, plan, read-only, safe-yolo, yolo |
| agent | enum | No | claude | AI agent to use: claude, codex, or gemini |
stop_session
Stop and archive a running Happy Coder session. Gracefully terminates the CLI process — the session becomes inactive but its message history is preserved. Use this when you are done with a session and want to free up resources.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID to stop |
interrupt_session
Interrupt a running Claude Code session to stop its current activity. Sends an abort signal equivalent to pressing Escape — the session stays alive and can accept new messages afterward. Use this when a session is actively generating output and you need it to stop.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID to interrupt |
Permission Management Tools
approve_permission
Approve a pending permission request in a session. Permission requests appear in get_session and watch_session results.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID |
| requestId | string | Yes | — | Permission request ID to approve, or "all_pending" to approve all |
| mode | enum | No | — | Permission mode to set after approval: default, acceptEdits, bypassPermissions, plan, read-only, safe-yolo, yolo |
| allowTools | string[] | No | — | List of tools to allow |
| decision | enum | No | approved | Approval decision: approved or approved_for_session |
deny_permission
Deny a pending permission request in a session. Can also abort the entire session.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID |
| requestId | string | Yes | — | Permission request ID to deny |
| reason | string | No | — | Feedback text explaining why the request was denied |
| decision | enum | No | denied | Denial type: denied or abort |
answer_question
Answer a question (AskUserQuestion) from a session. Approves the pending permission and sends a user message with the answer.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| sessionId | string | Yes | — | Session ID |
| requestId | string | Yes | — | Question request ID from pending permissions |
| answers | object | Yes | — | Map of question header to selected answer |
HTTP Transport
When running happy-mcp-server serve, the server exposes MCP over HTTP instead of stdio. This mode is useful for custom clients, testing, or programmatic access.
Starting the HTTP Server
# Auto-assign port (reports actual port on startup)
happy-mcp-server serve
# Specify a port
happy-mcp-server serve --port 3000
# With environment variables
HAPPY_MCP_LOG_LEVEL=debug happy-mcp-server serve --port 8080Server Endpoint
The server exposes the MCP protocol at:
http://127.0.0.1:<port>/mcpSecurity: The server binds to 127.0.0.1 (localhost only) and is not accessible from other machines. This prevents unauthorized network access to your Happy Coder sessions.
HTTP Methods
| Method | Endpoint | Purpose |
|--------|----------|---------|
| POST | /mcp | Initialize new MCP session or send requests |
| GET | /mcp | Server-Sent Events (SSE) stream for notifications |
| DELETE | /mcp | Terminate an MCP session |
Requirements
- Authentication required: You must run
happy-mcp-server author setHAPPY_MCP_ACCOUNT_SECRETbefore starting the HTTP server. The server will exit with an error if credentials are not found. - Credential file permissions: The credentials file must have
0600permissions (readable only by owner).
Example: Testing with curl
# Initialize a new MCP session
curl -X POST http://127.0.0.1:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0.0"}}, "id": 1}'MCP Configuration
Add to .mcp.json in your project root or configure via CLI:
claude mcp add --transport stdio happy -- happy-mcp-serverOr manually add to .mcp.json:
{
"mcpServers": {
"happy": {
"type": "stdio",
"command": "happy-mcp-server"
}
}
}With custom environment variables:
{
"mcpServers": {
"happy": {
"type": "stdio",
"command": "happy-mcp-server",
"env": {
"HAPPY_MCP_COMPUTERS": "*",
"HAPPY_MCP_PROJECT_PATHS": "*"
}
}
}
}Add to your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"happy": {
"type": "stdio",
"command": "happy-mcp-server"
}
}
}Add to .cursor/mcp.json in your project or global config:
{
"mcpServers": {
"happy": {
"command": "happy-mcp-server"
}
}
}Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"happy": {
"command": "happy-mcp-server"
}
}
}Add to ~/.continue/config.json:
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "happy-mcp-server"
}
}
]
}
}License
MIT
