mcp-server-viahuman
v1.0.3
Published
MCP server for ViaHuman - Add human approval gates to LLM workflows
Maintainers
Readme
ViaHuman MCP Server
MCP (Model Context Protocol) server for ViaHuman - Add human approval gates to LLM workflows.
NPM Package: mcp-server-viahuman
Overview
This MCP server enables LLMs like Claude to request human approval during their workflows. When Claude needs your approval, it sends a push notification to your mobile device via the ViaHuman app. You can then approve, reject, or provide input directly from your phone.
Perfect for:
- Getting approval before deploying code
- Reviewing AI-generated content before sending
- Confirming important decisions
- Providing input or edits to AI-generated work
- Adding human oversight to automated processes
Features
- Three MCP Tools:
request_approval,get_approval_status,cancel_approval - Multiple Input Types: Simple approve/reject, text input, number input, dropdown selection, image upload
- Push Notifications: Instant notifications to your mobile device
- Custom Actions: Define your own action buttons (e.g., "deploy", "skip", "edit")
- Intelligent Polling: Automatically waits for user response with exponential backoff
- Type-Safe: Full TypeScript implementation with Zod validation
Prerequisites
- ViaHuman Account: Sign up at your ViaHuman instance
- API Key: Create an API key from the ViaHuman dashboard
- Mobile App: Install the ViaHuman mobile app and log in
- Node.js: Version 18 or higher
Installation
Option 1: Global Installation (Recommended)
npm install -g mcp-server-viahumanOption 2: Local Development
# Clone or navigate to the package
cd mcp-server-viahuman
# Install dependencies
npm install
# Build the package
npm run buildConfiguration
Step 1: Get Your API Key
- Log into your ViaHuman dashboard
- Navigate to Dashboard > API Keys
- Click Create New API Key
- Give it a name (e.g., "Claude Desktop")
- Copy the API key immediately (starts with
vh_live_)
Step 2: Configure Claude Desktop
Add the MCP server to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
For Global Installation:
{
"mcpServers": {
"viahuman": {
"command": "mcp-server-viahuman",
"env": {
"APPROVEFLOW_API_KEY": "vh_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"APPROVEFLOW_API_URL": "https://viahuman.xyz/api"
}
}
}
}For Local Development:
{
"mcpServers": {
"viahuman": {
"command": "node",
"args": [
"/absolute/path/to/mcp-server-viahuman/build/index.js"
],
"env": {
"APPROVEFLOW_API_KEY": "vh_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"APPROVEFLOW_API_URL": "http://localhost:3000/api"
}
}
}
}Environment Variables:
APPROVEFLOW_API_KEY(required): Your API key from the dashboardAPPROVEFLOW_API_URL(required): Base API URL (without/v1suffix)- Production:
https://viahuman.xyz/api
- Production:
LOG_LEVEL(optional):debug,info,warn, orerror(default:info)
Step 3: Restart Claude Desktop
Completely quit and restart Claude Desktop for the configuration to take effect.
No-Permission Mode Setup
When running Claude in no-permission mode (auto-approve disabled), you can configure Claude to use the ViaHuman MCP server for updates and approvals instead of blocking for console input. This is ideal for running multiple Claude instances that work autonomously while still keeping you informed.
Step 1: Add Custom Instructions to Claude Desktop
Add the following custom instructions to your Claude Desktop configuration:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Add or update the "customInstructions" field:
{
"mcpServers": {
"viahuman": {
"command": "mcp-server-viahuman",
"env": {
"APPROVEFLOW_API_KEY": "vh_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"APPROVEFLOW_API_URL": "https://viahuman.xyz/api"
}
}
},
"customInstructions": "# Autonomous Task Execution Protocol\n\nWhen working on tasks, follow this protocol for communication and approvals:\n\n## Regular Updates\n- Send me status updates via the ViaHuman MCP server at key milestones\n- Use `request_approval` with simple approve/reject for progress updates\n- Include clear, descriptive titles (e.g., \"Status: Completed database migration\")\n- Set `wait_for_response: false` for non-blocking updates\n\n## Crucial Task Approvals\nBefore performing ANY of these actions, you MUST request approval:\n- Deleting files or directories\n- Modifying production configurations\n- Making database schema changes\n- Deploying to production environments\n- Running destructive git commands (force push, hard reset, etc.)\n- Installing or removing dependencies\n- Changing security settings or permissions\n- Making API calls that modify external systems\n\nFor approvals:\n- Use descriptive titles that explain WHAT you want to do\n- Include detailed descriptions of WHY and potential impact\n- Set `wait_for_response: true` to block until I respond\n- Provide relevant context in the `context` field\n\n## Task Completion Notifications\nWhen you finish a task:\n- Send a completion notification via `request_approval`\n- Title format: \"Task Complete: [task description]\"\n- Include summary of what was accomplished\n- Set `wait_for_response: false` unless you need feedback\n\n## Example Workflow\n\n### Starting a Task:\n```\nTitle: \"Starting: Refactor authentication module\"\nDescription: \"Beginning refactor of auth module. Will update you at key milestones.\"\nwait_for_response: false\n```\n\n### Before Destructive Action:\n```\nTitle: \"Approval Required: Delete legacy migration files\"\nDescription: \"Found 15 old migration files from 2023. Safe to delete as they've been squashed into base migration.\"\nContext: {files: [\"2023_01_*.sql\"], count: 15}\nwait_for_response: true\n```\n\n### Completion:\n```\nTitle: \"Task Complete: Authentication refactor\"\nDescription: \"Successfully refactored auth module. All tests passing. No breaking changes.\"\nwait_for_response: false\n```\n\n## DO NOT:\n- Never prompt for console input - always use the MCP server\n- Never proceed with destructive actions without approval\n- Never send excessive updates (only at meaningful milestones)\n- Never block on trivial decisions - use your judgment\n\n## DO:\n- Work autonomously on safe, non-destructive tasks\n- Keep me informed via mobile notifications\n- Ask for approval when genuinely needed\n- Provide clear context for decisions\n- Continue working after sending non-blocking updates"
}Note: The customInstructions field must be a single JSON string with escaped newlines (\n). The example above shows it formatted for readability.
Step 2: Simplified Configuration (Copy-Paste Ready)
For easier setup, here's the custom instructions as a single line:
{
"customInstructions": "# Autonomous Task Execution Protocol\n\nWhen working on tasks, follow this protocol:\n\n## Regular Updates\n- Send status updates via ViaHuman MCP server at key milestones\n- Use `request_approval` with simple approve/reject\n- Include clear titles (e.g., \"Status: Completed database migration\")\n- Set `wait_for_response: false` for non-blocking updates\n\n## Crucial Task Approvals\nBefore performing these actions, request approval:\n- Deleting files/directories\n- Modifying production configs\n- Database schema changes\n- Production deployments\n- Destructive git commands\n- Installing/removing dependencies\n- Security changes\n- External API modifications\n\nFor approvals:\n- Descriptive titles explaining WHAT\n- Detailed descriptions of WHY and impact\n- Set `wait_for_response: true` to block\n- Provide context in `context` field\n\n## Task Completion\nWhen finishing tasks:\n- Send completion notification\n- Title: \"Task Complete: [description]\"\n- Include summary of accomplishments\n- Set `wait_for_response: false`\n\n## Examples\n\nStarting: Title: \"Starting: Refactor auth module\" | wait_for_response: false\n\nApproval: Title: \"Approval Required: Delete legacy files\" | Description: \"15 old migrations, safe to delete\" | wait_for_response: true\n\nComplete: Title: \"Task Complete: Auth refactor\" | Description: \"Done. Tests passing.\" | wait_for_response: false\n\n## Rules\n- Never prompt for console input - use MCP server only\n- Never proceed with destructive actions without approval\n- Send updates only at meaningful milestones\n- Work autonomously on safe tasks\n- Keep me informed via mobile notifications"
}Step 3: Restart Claude Desktop
After updating the configuration, completely quit and restart Claude Desktop.
How It Works
- Autonomous Execution: Claude works on tasks without blocking for console input
- Mobile Notifications: You receive updates and approval requests on your phone via ViaHuman
- Selective Blocking: Claude only waits for response on crucial decisions
- Progress Tracking: Non-blocking updates keep you informed without interrupting work
- Multi-Instance: Run multiple Claude instances simultaneously, each sending updates to your phone
Example Session
You: "Refactor the authentication module and fix any bugs you find"
Claude:
- Sends: "Starting: Refactor authentication module" (doesn't wait)
- Works autonomously, reading files and analyzing code
- Finds a bug requiring schema change
- Sends: "Approval Required: Add index to users.email column" (waits for your approval)
- You approve on your phone
- Claude continues and completes the work
- Sends: "Task Complete: Authentication refactor finished" (doesn't wait)
You get 3 mobile notifications total, and Claude worked autonomously in between.
Usage
Once configured, Claude can use the ViaHuman tools to request your approval.
Example 1: Simple Approval
You: "I'm about to deploy to production. Ask for my approval first."
Claude: Uses request_approval tool
Result: You receive a push notification on your mobile device with "Approve" and "Reject" buttons.
Example 2: Text Input for Editing
You: "Draft an email to this customer and get my approval before sending."
Claude: Uses request_approval with input_type: "text"
Result: You see the draft email on your phone and can edit it before approving.
Example 3: Number Input
You: "Before making this AWS purchase, ask me to confirm the budget."
Claude: Uses request_approval with input_type: "number"
Result: You can adjust the budget amount on your phone.
MCP Tools Reference
1. request_approval
Create an approval request and optionally wait for user response.
Parameters:
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| title | string | Yes | - | Title of the approval (max 200 chars) |
| description | string | No | - | Detailed description |
| context | object | No | - | Additional context data (JSON) |
| actions | string[] | No | ["approve", "reject"] | Action buttons to show |
| input_type | enum | No | "none" | Type of input: none, text, number, select, image |
| input_config | object | No | - | Configuration for the input type |
| timeout_seconds | number | No | 3600 | Timeout in seconds (1 hour) |
| wait_for_response | boolean | No | true | Wait for user response |
| polling_interval | number | No | 5 | Polling interval in seconds |
| workflow_id | string (UUID) | No | - | UUID to group related approvals into a workflow thread |
| workflow_name | string | No | - | Human-readable name for the workflow (max 200 chars) |
Input Types:
none - Simple Approve/Reject
{
input_type: "none"
}text - Text Input
{
input_type: "text",
input_config: {
placeholder: "Enter text...",
multiline: true,
max_length: 500,
default_value: "Initial text",
required: false
}
}number - Number Input
{
input_type: "number",
input_config: {
label: "Budget Amount",
min: 0,
max: 10000,
step: 100,
currency: "USD",
default_value: 1000,
required: true
}
}select - Dropdown Selection
{
input_type: "select",
input_config: {
label: "Choose environment",
options: [
{ value: "staging", label: "Staging", description: "Test environment" },
{ value: "production", label: "Production", description: "Live site" }
],
required: true
}
}image - Image Upload
{
input_type: "image",
input_config: {
required: true
}
}Workflow Grouping:
Group related approvals into a workflow thread by providing a workflow_id and optional workflow_name. All approvals with the same workflow_id will be grouped together in the mobile app's Workflows tab, showing a chronological timeline of approvals.
Example: Deployment Workflow
// Generate a unique workflow ID once
const workflowId = crypto.randomUUID(); // e.g., "550e8400-e29b-41d4-a716-446655440000"
// Step 1: Pre-deployment checks
await request_approval({
title: "Run pre-deployment tests?",
workflow_id: workflowId,
workflow_name: "Production Deployment - v2.1.0",
wait_for_response: true
});
// Step 2: Review changes
await request_approval({
title: "Review deployment changes",
description: "Review the diff before deploying",
workflow_id: workflowId,
workflow_name: "Production Deployment - v2.1.0",
input_type: "text",
wait_for_response: true
});
// Step 3: Final confirmation
await request_approval({
title: "Proceed with deployment?",
description: "Final confirmation to deploy to production",
workflow_id: workflowId,
workflow_name: "Production Deployment - v2.1.0",
actions: ["deploy", "cancel"],
wait_for_response: true
});
// All 3 approvals appear in the "Production Deployment - v2.1.0" workflow threadBenefits:
- Organization: View all approvals for a specific task/workflow in one place
- Timeline: See the chronological progression of approvals
- Context: Quickly understand what's part of the same automation flow
- Multi-Instance: Multiple Claude instances can send updates to the same workflow
Returns:
Approval object with status, user response, and timing information.
2. get_approval_status
Check the current status of an approval request.
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| approval_id | string | Yes | The approval UUID |
Returns:
Current approval status with response details if available.
3. cancel_approval
Cancel a pending approval request.
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| approval_id | string | Yes | The approval UUID to cancel |
Returns:
Confirmation of cancellation.
Troubleshooting
MCP Server Not Appearing in Claude Desktop
Solution:
- Verify the configuration file is valid JSON
- Check the path to the executable/build file
- Restart Claude Desktop completely
- Check Claude Desktop logs for errors
API Key Authentication Failures
Symptoms: "Invalid API key" or 401 errors
Solution:
- Verify API key format:
vh_live_orvh_test_followed by 32 hex characters - Check that the API key is active in the dashboard
- Ensure the API URL is correct (with
/apisuffix, no trailing slash) - Verify you copied the full API key (they're long!)
Rate Limit Errors
Symptoms: HTTP 429 errors
Solution:
- Default limit is 60 requests per minute
- Wait for the rate limit window to reset (shown in error message)
- Increase
polling_intervalto reduce API calls - Contact support to increase your rate limit
Timeout Errors
Symptoms: "Approval request timed out"
Solution:
- Increase
timeout_seconds(default is 3600 = 1 hour) - Verify the mobile app is logged in
- Check that push notifications are enabled
- Ensure the mobile device has internet connectivity
No Push Notifications
Symptoms: Approval created but no notification received
Solution:
- Open the mobile app and check for pending approvals
- Verify push notification permissions are enabled
- Check that the device is connected to the internet
- Try logging out and back in to re-register push token
Development
Building
npm run buildDevelopment Mode (Watch)
npm run devRunning Locally
# Build first
npm run build
# Run the server
npm startThe server uses stdio transport, so it will wait for MCP protocol messages on stdin.
Architecture
- Transport: stdio (standard for MCP servers)
- Protocol: Model Context Protocol (MCP)
- API: ViaHuman REST API
- Authentication: Bearer token (API keys)
- Polling: Exponential backoff (5s → 30s max)
API Rate Limits
- Default: 60 requests per minute per API key
- Rate limit headers are included in responses:
X-RateLimit-Limit: Your rate limitX-RateLimit-Remaining: Requests remainingX-RateLimit-Reset: When the limit resets
Security Notes
- API Keys: Never commit API keys to version control
- Environment Variables: Use environment variables for sensitive data
- HTTPS: Use HTTPS for production API URLs
- Permissions: API keys can only access their owner's approvals
Support
- Documentation: ViaHuman Documentation
- Dashboard: ViaHuman Dashboard
License
MIT
Credits
Built with:
- @modelcontextprotocol/sdk - Official MCP TypeScript SDK
- Zod - Schema validation
Made with ❤️ ViaHuman
