For humans and AI agents. Follow these steps in order to set up a complete local AI development environment with MCP Mesh, browser integration, and workflow automation.
This guide sets up:
- MCP Mesh (PostgreSQL) — Control plane for all MCP traffic
- OpenRouter MCP — LLM access (200+ models, vision, image generation)
- Perplexity MCP — Web-grounded research and search
- Mesh Bridge — Browser automation via Chrome extension
- Pilot — Workflow-driven AI agent
- Workflows — JSON-based automation pipelines
┌─────────────────────────────────────────────────────────────────────┐
│ MCP MESH │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ EVENT BUS │ │
│ │ │ │
│ │ user.message.received ◄─── Bridge publishes │ │
│ │ agent.response.* ────────► Bridge/Pilot subscribes │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ │
│ ┌──────────┐ ┌────────────┴────────────┐ ┌────────────────┐ │
│ │ Pilot │ │ mesh-bridge │ │ Other MCPs │ │
│ │ │◄──│ │──►│ │ │
│ │ Workflows│ │ Chrome Extension │ │ • OpenRouter │ │
│ │ Tasks │ │ WhatsApp ↔ Events │ │ • Perplexity │ │
│ └──────────┘ └─────────────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
- Node.js ≥ 22.0.0
- Bun (for local MCPs):
curl -fsSL https://bun.sh/install | bash - Chrome browser (for Mesh Bridge extension)
- API Keys:
- OpenRouter: https://openrouter.ai/keys
- Perplexity: https://perplexity.ai/settings/api
Why PostgreSQL? The Event Bus requires PostgreSQL for reliable pub/sub with LISTEN/NOTIFY. SQLite won't work for event-driven workflows.
# Create a directory for Mesh
mkdir -p ~/mesh && cd ~/mesh
# Download docker-compose file
curl -O https://raw.githubusercontent.com/decocms/mesh/main/deploy/docker-compose.postgres.yml
# Create auth config
cat > auth-config.json << 'EOF'
{
"socialProviders": []
}
EOF
# Create .env file
cat > .env << 'EOF'
BETTER_AUTH_SECRET=your-secret-key-change-this-to-random-string
BETTER_AUTH_URL=http://localhost:3000
BASE_URL=http://localhost:3000
POSTGRES_USER=mesh_user
POSTGRES_PASSWORD=change-this-password
POSTGRES_DB=mesh_db
EOF
# Start Mesh with PostgreSQL
docker compose -f docker-compose.postgres.yml up -dnpx @decocms/mesh
⚠️ This uses SQLite by default. For Event Bus features (Pilot, Bridge workflows), you need PostgreSQL.
Open http://localhost:3000 — you should see the Mesh UI.
Create an account (first user becomes admin).
The OpenRouter MCP provides access to 200+ LLMs with vision and image generation.
npx @firstdoit/openrouter-mcp-multimodal- Go to Connections in Mesh UI
- Click Add Connection → Custom Command
- Configure:
| Field | Value |
|---|---|
| Name | OpenRouter |
| Command | npx |
| Arguments | @firstdoit/openrouter-mcp-multimodal |
-
Add environment variable:
OPENROUTER_API_KEY=your-openrouter-api-key
-
Click Save
mcp_openrouter_chat_completion— Chat with any modelmcp_openrouter_analyze_image— Vision/image analysismcp_openrouter_multi_image_analysis— Analyze multiple imagesgenerate_image— Generate images (Gemini 2.5 Flash Image)search_models— Search available modelsget_model_info— Get model detailsvalidate_model— Check if model ID is valid
To publish a new version:
cd openrouter-mcp-multimodal && npm version patch && npm publish
The official Perplexity MCP server provides web-grounded answers with citations.
npx @perplexity-ai/mcp-server- Go to Connections in Mesh UI
- Click Add Connection → Custom Command
- Configure:
| Field | Value |
|---|---|
| Name | Perplexity |
| Command | npx |
| Arguments | @perplexity-ai/mcp-server |
-
Add environment variable:
PERPLEXITY_API_KEY=your-perplexity-api-key
-
Click Save
perplexity_ask— Simple question with web-grounded answerperplexity_search— Web search with ranked resultsperplexity_chat— Multi-turn conversation with context
Mesh Bridge turns browser events into MCP Event Bus messages.
# Clone the repo
git clone https://github.com/firstdoit/mesh-bridge.git
cd mesh-bridge
bun install- Open Chrome and go to
chrome://extensions - Enable Developer mode (toggle in top-right)
- Click Load unpacked
- Select the
mesh-bridge/extension/folder
You should see the Mesh Bridge extension icon appear.
- Go to Connections → Add Connection → Custom Command
- Configure:
| Field | Value |
|---|---|
| Name | Mesh Bridge |
| Command | bun |
| Arguments | run, start |
| Working Directory | /path/to/mesh-bridge |
- Configure bindings:
- Add EVENT_BUS binding
- Open https://web.whatsapp.com
- Go to your self-chat ("Message Yourself")
- Send a message — the Bridge will publish events to the Event Bus
Pilot is the workflow-driven AI agent that processes events and executes multi-step tasks.
# Clone the MCPs repo (if not already)
git clone https://github.com/decocms/mcps.git
cd mcps/pilot
# Install dependencies
bun install
# Create directories for tasks and workflows
mkdir -p ~/Projects/tasks
mkdir -p ~/Projects/workflowscat > .env << 'EOF'
# Storage paths
TASKS_DIR=~/Projects/tasks
CUSTOM_WORKFLOWS_DIR=~/Projects/workflows
# Default models (via OpenRouter)
FAST_MODEL=google/gemini-2.5-flash
SMART_MODEL=anthropic/claude-sonnet-4
# Default workflow
DEFAULT_WORKFLOW=fast-router
EOF- Go to Connections → Add Connection → Custom Command
- Configure:
| Field | Value |
|---|---|
| Name | Pilot |
| Command | bun |
| Arguments | run, start |
| Working Directory | /path/to/mcps/pilot |
- Configure bindings:
- Add LLM binding → Select
OpenRouter - Add CONNECTION binding → Enable tool discovery
- Add EVENT_BUS binding → For pub/sub
- Add LLM binding → Select
Workflows are JSON files that define multi-step automation.
Create ~/Projects/workflows/research-and-write.json:
{
"id": "research-and-write",
"title": "Research and Write Article",
"description": "Research a topic with Perplexity and write an article using OpenRouter",
"steps": [
{
"name": "research",
"description": "Research the topic using Perplexity",
"action": {
"type": "llm",
"prompt": "Research the following topic thoroughly:\n\n@input.topic\n\n**TOOL USAGE:**\nCall: `perplexity_search({ \"query\": \"@input.topic\" })`\n\nGather:\n- Key facts and statistics\n- Recent developments\n- Expert opinions\n- Multiple perspectives\n\nReturn a comprehensive research summary.",
"model": "fast",
"tools": ["perplexity_search"],
"maxIterations": 10
},
"input": {
"topic": "@input.topic"
}
},
{
"name": "write_draft",
"description": "Write the article based on research",
"action": {
"type": "llm",
"prompt": "Write a well-structured article based on this research:\n\n**Topic:** @input.topic\n\n**Research:**\n@research.response\n\nWrite a compelling article that:\n- Has a strong hook\n- Is well-organized with clear sections\n- Includes specific examples from the research\n- Has a clear conclusion\n\nOutput the full article in markdown format.",
"model": "smart",
"maxIterations": 1
},
"input": {
"topic": "@input.topic",
"research": "@research.response"
}
},
{
"name": "save_to_file",
"description": "Save the article to a file",
"action": {
"type": "llm",
"prompt": "Save this article to a markdown file.\n\n**Article:**\n@write_draft.response\n\n**TOOL USAGE:**\nCall: `WRITE_FILE({ \"path\": \"/tmp/article-@input.timestamp.md\", \"content\": \"@write_draft.response\" })`\n\nConfirm the file was saved.",
"model": "fast",
"tools": ["WRITE_FILE"],
"maxIterations": 3
},
"input": {
"content": "@write_draft.response",
"timestamp": "@input.timestamp"
}
},
{
"name": "format_response",
"description": "Format the final response",
"action": {
"type": "template",
"template": "✅ **Article Complete!**\n\n📝 **@input.topic**\n\n---\n\n@write_draft.response\n\n---\n\n📁 Saved to: `/tmp/article-@input.timestamp.md`"
},
"input": {
"topic": "@input.topic",
"content": "@write_draft.response",
"timestamp": "@input.timestamp"
}
}
],
"inputSchema": {
"type": "object",
"required": ["topic"],
"properties": {
"topic": {
"type": "string",
"description": "The topic to research and write about"
},
"timestamp": {
"type": "string",
"description": "Timestamp for file naming (auto-generated)"
}
}
}
}| Type | Description |
|---|---|
llm |
Call LLM with prompt, optional tools |
tool |
Call a specific MCP tool directly |
template |
String interpolation for formatting |
@input.fieldName— Workflow input@step_name.response— Previous step output@config.modelId— Configuration value
Now for the magic — trigger workflows from WhatsApp.
- Check Mesh UI → all connections should show Connected
- Check Pilot logs for
Subscribed to user.message.received - Check Bridge logs for WebSocket connection
- Open https://web.whatsapp.com → your self-chat
- Type:
research and write about MCP protocol - Pilot will:
- Receive the event from Bridge
- Route to the workflow
- Execute research with Perplexity
- Write the article with OpenRouter
- Save to file
- Respond via Bridge back to WhatsApp
| Command | Action |
|---|---|
research <topic> |
Research using Perplexity |
write about <topic> |
Full research + draft workflow |
list tasks |
See recent tasks |
list workflows |
See available workflows |
check <taskId> |
Check task status |
# Check PostgreSQL is running
docker ps | grep postgres
# Check Mesh logs
docker logs deco-mcp-mesh -f- Verify EVENT_BUS binding is configured
- Check Pilot has subscribed: look for
Subscribed to user.message.receivedin logs - Verify Bridge is publishing events
The extension auto-reconnects. If you see "Extension context invalidated", the page will auto-reload.
- Must be in self-chat ("Message Yourself")
- Check Bridge WebSocket is connected (port 9999)
- Check Pilot is processing events
# Start Mesh
npx @decocms/mesh
# OpenRouter MCP
npx @firstdoit/openrouter-mcp-multimodal
# Perplexity MCP (official)
npx @perplexity-ai/mcp-server
# Publish new OpenRouter version
cd openrouter-mcp-multimodal && npm version patch && npm publish| Name | Type | Command/URL |
|---|---|---|
| OpenRouter | Custom Command | npx @firstdoit/openrouter-mcp-multimodal |
| Perplexity | Custom Command | npx @perplexity-ai/mcp-server |
| Mesh Bridge | Custom Command | bun run start (in mesh-bridge/) |
| Pilot | Custom Command | bun run start (in mcps/pilot/) |
~/Projects/
├── tasks/ # Pilot task storage
├── workflows/ # Custom workflows
├── mesh-bridge/ # Browser bridge
└── mcps/
└── pilot/ # AI agent
- Create more workflows — Explore
~/Projects/workflows/examples - Add more MCPs — Browse https://github.com/decocms/mcps
- Build custom integrations — Mesh Bridge supports adding new domains
- Deploy to production — Use
docker-compose.postgres.ymlwith proper secrets
MIT