loading…
Search for a command to run...
loading…
A self-hosted MCP gateway that aggregates multiple servers into a single endpoint with features for data anonymization and granular permission policies. It inte
A self-hosted MCP gateway that aggregates multiple servers into a single endpoint with features for data anonymization and granular permission policies. It integrates a Telegram bot for real-time 2FA approvals of sensitive operations and secure remote access.
A self-hosted MCP (Model Context Protocol) gateway that sits between Claude Code and multiple MCP servers, providing:
┌─────────────────────────────────────────────────────────────┐
│ TELEGRAM BOT │
│ /status, /grant, /revoke, /tasks, approval callbacks │
│ Executes approved tasks asynchronously │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ PORTERO │
│ ┌────────────────────────────────────────────────────────┐│
│ │ HTTP Server (Express) ││
│ │ - POST /mcp/message (JSON-RPC, Bearer auth) ││
│ │ - GET /health ││
│ └────────────────────────────────────────────────────────┘│
│ ┌────────────────────────────────────────────────────────┐│
│ │ Middleware Pipeline ││
│ │ 1. Anonymization (fake→real on requests) ││
│ │ 2. Policy Check (allow/deny/require-approval) ││
│ │ 3. If approval needed → create task, return pending ││
│ │ 4. If allowed → route to child MCP immediately ││
│ │ 5. Anonymization (real→fake on responses) ││
│ └────────────────────────────────────────────────────────┘│
│ ┌────────────────────────────────────────────────────────┐│
│ │ Task Store (data/tasks.json) ││
│ │ pending-approval → approved → executing → completed ││
│ └────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
│ stdio
┌─────────────┼─────────────┬─────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ MCP 1 │ │ MCP 2 │ │ MCP 3 │ │ MCP 4 │
│(github) │ │(filesys)│ │(google) │ │(stripe) │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
git clone <your-repo-url>
cd portero
npm install
cp .env.example .env
# Edit .env with your settings
Required settings in .env:
# Generate a secure token
BEARER_TOKEN=$(openssl rand -hex 32)
# Get from @BotFather
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
# Get from @userinfobot
TELEGRAM_ADMIN_CHAT_ID=123456789
# Your real info (for anonymization)
REAL_NAME="Your Name"
REAL_EMAIL="[email protected]"
Edit config/mcps.json to define which MCP servers to connect:
{
"mcps": [
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"env": {}
},
{
"name": "github",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
]
}
To add Gmail, Calendar, and Drive integration via workspace-mcp:
.env:GOOGLE_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=your-client-secret
If GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET are not set, Portero will skip the Google MCP and start without it.
The Google tools appear as google/send_email, google/list_events, google/search_files, etc. Write operations (send, create, delete) require Telegram approval; reads are allowed by default. See config/policies.json for the full list.
To add Notion integration:
ntn_).env:NOTION_API_TOKEN=ntn_your-token-here
If NOTION_API_TOKEN is not set, Portero will skip the Notion MCP and start without it. Read operations (search, retrieve pages/blocks) are allowed by default; write operations (create/update/delete) require Telegram approval.
To add Stripe integration for payment management:
.env:STRIPE_API_KEY=sk_test_your-key-here
If STRIPE_API_KEY is not set, Portero will skip the Stripe MCP and start without it.
Default policies:
allowrequire-approvalEdit config/replacements.json to define fake↔real mappings:
{
"replacements": [
{
"fake": "John Doe",
"real": "${REAL_NAME}",
"bidirectional": true
},
{
"fake": "[email protected]",
"real": "${REAL_EMAIL}",
"bidirectional": true,
"caseSensitive": false
}
]
}
Edit config/policies.json to set permission rules:
{
"policies": {
"github/create_issue": "allow",
"github/create_pull_request": "require-approval",
"filesystem/write_file": "require-approval",
"filesystem/read_file": "allow",
"filesystem/delete_file": "deny",
"*": "allow"
},
"defaultPolicy": "allow"
}
./scripts/generate-certs.sh
Or skip SSL for local testing (uses HTTP).
# Development mode (with hot reload)
npm run dev
# Production mode
npm run build
npm start
# Build and start with docker-compose
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"portero": {
"transport": "http",
"url": "https://your-server:8443/mcp/message",
"headers": {
"Authorization": "Bearer your-bearer-token-here"
}
}
}
}
Add to Claude Code system prompt:
Your identity:
- Name: John Doe
- Email: [email protected]
Use these when asked for personal information.
Once running, message your bot:
/status - Show connected MCPs, active grants, pending approvals/grant <pattern> <duration> - Grant temporary access/grant github/* 30m, /grant * 1h/revoke - Revoke all active grants/allow <pattern> - Persistently allow a tool/pattern (no approvals needed)/deny <pattern> - Persistently deny a tool/pattern/rules - List persistent rules/unrule <id> - Remove a persistent rule/tasks - Show recent tasks grouped by status/pending - Show pending approval requests/logs - Show recent audit logs/help - Show all commandsPortero uses a fully asynchronous approval flow — the HTTP request is never blocked waiting for Telegram approval.
github/create_pull_request)pending-approval), sends Telegram message with Approve/Deny buttons, and returns immediately with a task ID{ status: "pending-approval", taskId: "..." } and can continue workingportero/check_task with the task ID to retrieve the resultportero/check_task again laterThis means:
Portero injects these virtual tools alongside your MCP tools:
| Tool | Description |
|---|---|
portero/search_tools |
Search available tools by keyword or category |
portero/call |
Call any tool by its full name (useful for non-pinned tools) |
portero/check_task |
Check status/result of a pending or completed async task |
portero/list_tasks |
List recent tasks with optional status filter |
Replacements support:
responseReplacement for responsescaseSensitive: false for case-insensitive matchingPolicy actions:
allow — Allow without approvaldeny — Block completelyrequire-approval — Request Telegram approval (async)Patterns support wildcards:
github/* — All GitHub tools*/delete_* — All delete operations* — All toolsPolicy priority (highest first):
/allow, /deny commands)config/policies.json)Skip approval for a limited time:
/grant github/* 30m # Grant GitHub access for 30 minutes
/grant * 1h # Grant all access for 1 hour
/revoke # Revoke all grants immediately
Bearer Token — Generate a strong random token:
openssl rand -hex 32
SSL/TLS — Use HTTPS in production (Let's Encrypt, self-signed, or reverse proxy)
Telegram — Only your admin chat ID can control the bot
Firewall — Restrict gateway port (8443) to authorized IPs
Environment Variables — Never commit .env to git
portero/
├── src/
│ ├── index.ts # Entry point
│ ├── config/ # Config loader & types
│ ├── gateway/ # HTTP server & MCP handler
│ ├── mcp/ # MCP client management
│ ├── middleware/ # Anonymizer, policy, approval
│ ├── telegram/ # Telegram bot & admin store
│ ├── db/ # File-backed JSON storage
│ ├── storage/ # Atomic file operations & paths
│ └── utils/ # Logger, crypto
├── config/ # JSON config files
├── data/ # Runtime data (auto-created)
└── scripts/ # Helper scripts
npm run dev # Development with hot reload
npm run build # Compile TypeScript
npm start # Start production build
File-backed JSON storage in ./data/:
approvals.json — Legacy pending approvals (kept for backward compatibility)tasks.json — Async task tracking (pending → approved → executing → completed)grants.json — Temporary access grantsrules.json — Persistent policy rules (from /allow, /deny commands)audit.ndjson — Append-only audit log (NDJSON format)node -v (should be 20+).env file exists and has all required variables./logs/combined.logconfig/mcps.jsonnpx -y @modelcontextprotocol/server-github --versionGITHUB_TOKEN)/startcurl:curl -X POST https://localhost:8443/health
Contributions welcome! Please:
MIT License - see LICENSE file for details
Built for Claude Code users who want privacy, security, and control over their MCP connections.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"portero": {
"command": "npx",
"args": []
}
}
}Read, send and search emails from Claude
Send, search and summarize Slack messages
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)