MCP Integration
OpenViber integrates with Model Context Protocol (MCP) servers to extend task capabilities with standardized tools and resources.
1. Overview
MCP provides a standard way for AI tasks to interact with external systems. OpenViber acts as an MCP client that connects to one or more MCP servers. Each MCP server provides tools that the task can discover and use during execution.
2. Configuration
Basic Setup
# ~/.openviber/config.yaml
mcp_servers:
- name: "github"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
- name: "postgres"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-postgres"]
env:
DATABASE_URL: "${DATABASE_URL}" Full Configuration Options
mcp_servers:
- name: "github" # Unique identifier
description: "GitHub API access" # Human-readable description
# Process configuration
command: "npx" # Executable
args: ["-y", "@modelcontextprotocol/server-github"]
cwd: "/home/user" # Working directory (optional)
env: # Environment variables
GITHUB_TOKEN: "${GITHUB_TOKEN}"
# Connection settings
startup_timeout_ms: 10000 # Max time to wait for server start
request_timeout_ms: 30000 # Per-request timeout
require_approval: # Tools requiring human approval
- "create_issue"
- "create_pull_request"
# Resource access
expose_resources: true # Allow task to read MCP resources
# Lifecycle
auto_start: true # Start with Viber
restart_on_failure: true # Auto-restart if process dies
max_restarts: 3 # Max restart attempts 3. MCP Concepts
Tools vs Resources
| Concept | Description | Example |
|---|---|---|
| Tools | Actions the task can take | create_issue, run_query |
| Resources | Data the task can read | github://repo/issues, postgres://table/schema |
Tool Discovery
When the Viber starts, it connects to all configured MCP servers and discovers available tools:
// MCP server advertises tools
{
"tools": [
{
"name": "github_create_issue",
"description": "Create a new GitHub issue",
"inputSchema": {
"type": "object",
"properties": {
"repo": { "type": "string" },
"title": { "type": "string" },
"body": { "type": "string" }
},
"required": ["repo", "title"]
}
}
]
}
// OpenViber registers these as task tools
// Task sees: github_create_issue(repo, title, body?) Resource Access
Resources are read-only data sources:
// Task requests a resource
const issues = await mcp.readResource("github://dustland/openviber/issues");
// Returns structured data
{
"uri": "github://dustland/openviber/issues",
"contents": [
{ "number": 42, "title": "Bug in auth", "state": "open" },
// ...
]
} 4. Security Model
Principle of Least Privilege
MCP servers run with minimal permissions:
mcp_servers:
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem"]
# Restrict to specific directories
args_append:
- "/home/user/projects" # Only this directory
- "--read-only" # No writes Approval Gates
Sensitive MCP tools can require human approval:
mcp_servers:
- name: "postgres"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-postgres"]
require_approval:
- "execute_query" # All queries need approval
# Or more granular:
approval_rules:
- pattern: "INSERT|UPDATE|DELETE"
require: true
- pattern: "SELECT"
require: false Credential Isolation
MCP servers are configured per task in ~/.openviber/vibers/{id}.yaml:
mcp_servers:
- name: "github"
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}" # Only GitHub token
# Does NOT receive DATABASE_URL or other secrets Sandboxing (Optional)
MCP servers can run in isolated containers:
mcp_servers:
- name: "untrusted-server"
command: "docker"
args: ["run", "--rm", "-i", "mcp-server-image"]
sandbox:
enabled: true
network: "none" # No network access
memory_limit: "256m"
cpu_limit: "0.5" 5. Lifecycle Management
Startup Sequence
Health Monitoring
// MCP Manager monitors server health
interface McpServerHealth {
name: string;
status: "starting" | "ready" | "unhealthy" | "stopped";
pid?: number;
uptime_ms?: number;
last_request_at?: string;
error?: string;
} Graceful Shutdown
async function shutdownMcpServers() {
// Shutdown all servers when Viber stops
for (const server of mcpServers) {
// 1. Stop accepting new requests
server.pause();
// 2. Wait for in-flight requests (max 5s)
await server.drain(5000);
// 3. Send SIGTERM
server.process.kill('SIGTERM');
// 4. Force kill after timeout
setTimeout(() => server.process.kill('SIGKILL'), 3000);
}
} 6. Error Handling
Server Failures
interface McpError {
type: "connection" | "timeout" | "protocol" | "execution";
server: string;
tool?: string;
message: string;
recoverable: boolean;
}
// Error handling strategy
async function handleMcpError(error: McpError) {
if (error.type === "connection" && error.recoverable) {
// Attempt restart
await restartServer(error.server);
} else {
// Report to task as tool failure
return {
success: false,
error: `MCP server '${error.server}' error: ${error.message}`,
};
}
} Timeout Handling
mcp_servers:
- name: "slow-server"
request_timeout_ms: 60000 # 60 seconds for slow operations
# Per-tool timeouts
tool_timeouts:
quick_lookup: 5000
long_analysis: 120000 7. Tool Namespacing
MCP tools are registered in the task’s tool registry alongside built-in tools:
Server: github
Tool: create_issue
→ Task sees: github_create_issue
Server: gitlab
Tool: create_issue
→ Task sees: gitlab_create_issue Custom Prefixes
mcp_servers:
- name: "github"
tool_prefix: "gh" # gh_create_issue instead of github_create_issue Tool Aliasing
mcp_servers:
- name: "postgres"
tool_aliases:
execute_query: "db_query" # Task sees db_query
list_tables: "db_tables" 8. Resource Protocol
Resource URIs
MCP resources use URI schemes:
github://owner/repo/issues
postgres://database/table/schema
file:///path/to/file Resource Discovery
// List available resources
const resources = await mcp.listResources("github");
// Returns:
// [
// { uri: "github://dustland/openviber/issues", name: "Issues" },
// { uri: "github://dustland/openviber/pulls", name: "Pull Requests" },
// ]
// Read a resource
const data = await mcp.readResource("github://dustland/openviber/issues"); Resource Caching
mcp_servers:
- name: "github"
resource_cache:
enabled: true
ttl_seconds: 300 # Cache for 5 minutes
max_size_mb: 50 9. Integration with Tasks
Tool Registration
// During task initialization
async function registerMcpTools(task: Task, mcpManager: McpManager) {
for (const server of mcpManager.servers) {
// 3. Task discovers tools from all servers
const tools = await server.listTools();
for (const tool of tools) {
task.registerTool({
name: `${server.name}_${tool.name}`,
description: tool.description,
parameters: tool.inputSchema,
execute: async (params) => {
return await server.callTool(tool.name, params);
},
});
}
}
} Context Injection
The Viber injects MCP context into the task’s system prompt:
// In task submission
{
type: "task:submit",
payload: {
goal: "Fix the auth bug",
messages: [...],
mcp_context: [
{ uri: "github://dustland/openviber/issues/42" },
{ uri: "postgres://app/users/schema" }
]
}
} 10. Popular MCP Servers
| Server | Purpose | Package |
|---|---|---|
| GitHub | Repository operations | @modelcontextprotocol/server-github |
| Filesystem | File operations | @modelcontextprotocol/server-filesystem |
| PostgreSQL | Database queries | @modelcontextprotocol/server-postgres |
| Brave Search | Web search | @modelcontextprotocol/server-brave-search |
| Puppeteer | Browser automation | @modelcontextprotocol/server-puppeteer |
| Slack | Team communication | @modelcontextprotocol/server-slack |
11. Creating Custom MCP Servers
For custom integrations, create an MCP server:
// my-mcp-server/index.ts
import { Server } from "@modelcontextprotocol/sdk/server";
const server = new Server({
name: "my-custom-server",
version: "1.0.0",
});
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "my_tool",
description: "Does something useful",
inputSchema: {
type: "object",
properties: {
input: { type: "string" },
},
},
},
],
}));
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "my_tool") {
const result = await doSomethingUseful(request.params.arguments.input);
return { content: [{ type: "text", text: result }] };
}
});
server.connect(process.stdin, process.stdout); Then configure in OpenViber:
mcp_servers:
- name: "my-custom"
command: "node"
args: ["./my-mcp-server/index.js"] Summary
MCP integration in OpenViber:
- Configuration-driven — Add servers via YAML config
- Security-conscious — Approval gates, credential isolation, optional sandboxing
- Lifecycle-managed — Auto-start, health monitoring, graceful shutdown
- Namespaced tools — No collisions between servers
- Resource support — Read-only data access via URIs
This enables tasks to safely interact with external systems while maintaining the stateless Viber principle.