6.8 KiB
6.8 KiB
MCPletA2A
MCPlet Agent Profile (A2A) platform implementation and reference implementation.
Directory Structure
MCPletA2A/
├── platform_impl/ MCPlet Agent Profile Host platform
└── reference_impl/ Cancel-rate reduction scenario reference implementation
Platform (platform_impl)
Implements the MCPlet Agent Profile Host as defined in MCPlet-spec-v202603-03.
Key components:
| Component | File | Role |
|---|---|---|
| MCPlet Host | src/host/mcplet-host.ts |
Main orchestration entry point |
| Pool Registry | src/pools/pool-registry.ts |
Pool membership + per-agent access enforcement |
| MCPlet Discovery | src/discovery/mcplet-discovery.ts |
MCP tools/list + validation + hot-reload |
| LLM Adapter | src/llm/ |
LLM-agnostic interface, Claude implementation |
| Base Agent | src/agents/base-agent.ts |
Abstract agent with Passkey interception + tool loop |
| Director Agent | src/agents/director-agent.ts |
Cron-triggered, anti-concurrent, retry-safe |
| A2A Local Bus | src/a2a/local-bus.ts |
In-process inter-agent message routing |
| A2A External Endpoint | src/a2a/external-endpoint.ts |
HTTP endpoint for External Agents (Bearer auth) |
| Passkey Server | src/passkey/passkey-server.ts |
localhost WebAuthn ceremony page |
| Dashboard | src/dashboard/dashboard-server.ts |
Audit log + tool/agent visibility |
| Audit Log | src/host/audit-log.ts |
In-memory action invocation log |
Setup
cd platform_impl
npm install
npm run build
Configuration
Copy and edit config/platform.yaml:
export ANTHROPIC_API_KEY=sk-ant-...
MCPLET_CONFIG=config/platform.yaml npm start
Reference Implementation (reference_impl)
Demonstrates the cancel-rate reduction scenario from Flow.png.
Flow
[cron 07:00] Director Agent
→ InfoGatheringAgent (info-pool)
fetch_web_content → 天気予報 (明日は雨)
call_external_api → デザート在庫
query_crm → 高キャンセル傾向顧客 5名
query_crm → 明日の予約 6件
→ PlanningAgent (pool-less)
query_erp → 在庫確認
→ 無料デザートキャンペーン立案
→ [店長 Passkey 承認]
→ DispatchAgent (media-pool)
send_email × 5 → 対象顧客にメール送信 (Passkey strict)
MCPlet Inventory
| MCPlet | Tool | Type | Pool | Visibility |
|---|---|---|---|---|
| サイトアクセス | read_site_stats |
read | media-pool | [model] |
send_email |
action | media-pool | [app] | |
| SNS | post_sns |
action | media-pool | [app] |
| 外部Web | fetch_web_content |
read | info-pool | [model] |
| 外部API | call_external_api |
read | info-pool | [model] |
| CRM | query_crm |
read | (none) | [model] |
| ERP | query_erp |
read | (none) | [model] |
| HR | query_hr |
read | (none) | [model] |
Setup
cd reference_impl
npm install
npm run build
# Start mock services (port 5100)
npm run mock
Running MCPlet Servers
Each MCPlet is a standalone MCP server started via stdio. Start all:
node dist/mcplets/info-pool/web-access/index.js
node dist/mcplets/info-pool/api-access/index.js
node dist/mcplets/internal/crm/index.js
node dist/mcplets/internal/erp/index.js
node dist/mcplets/internal/hr/index.js
node dist/mcplets/media-pool/site-access/index.js
node dist/mcplets/media-pool/email/index.js
node dist/mcplets/media-pool/sns/index.js
Production Deployment (a2a-demo.mcplet.ai)
Demo is deployed on a VPS (153.126.215.188) with nginx + Let's Encrypt SSL.
Architecture
External Users
↓ HTTPS
nginx (443, Let's Encrypt auto-renew)
├── / → Dashboard :4000
├── /a2a/* → A2A External Endpoint :4001
└── /passkey-api/* → Passkey API :8443
MCPletA2A (systemd service)
├── Mock Service :5100 (internal only)
└── Platform Host → 8 MCPlet servers (stdio)
Access
- URL: https://a2a-demo.mcplet.ai
- Basic Auth:
admin/m2a69988 - A2A API endpoint (
/a2a/*) does not require Basic Auth (uses Bearer token)
Service Management
# Status / logs
sudo systemctl status mcplet-a2a
journalctl -u mcplet-a2a -f
# Restart / stop
sudo systemctl restart mcplet-a2a
sudo systemctl stop mcplet-a2a
Key Files on VPS
| Path | Description |
|---|---|
/home/ubuntu/MCPletA2A/ |
Project root |
/home/ubuntu/MCPletA2A/deploy/.env |
API keys (OPENROUTER_API_KEY) |
/home/ubuntu/MCPletA2A/deploy/start-vps.sh |
Startup script (used by systemd) |
/etc/systemd/system/mcplet-a2a.service |
systemd unit file |
/etc/nginx/sites-available/a2a-demo.conf |
nginx reverse proxy config |
/etc/letsencrypt/live/a2a-demo.mcplet.ai/ |
SSL certificate (auto-renews) |
Updating
# On local machine: push changes, then on VPS:
cd /home/ubuntu/MCPletA2A
git pull
cd platform_impl && npm run build
cd ../reference_impl && npm run build
sudo systemctl restart mcplet-a2a
Or from local machine via rsync:
rsync -avz --exclude='node_modules' --exclude='dist' --exclude='.logs' --exclude='.pids' --exclude='.env' \
-e ssh . ubuntu@153.126.215.188:/home/ubuntu/MCPletA2A/
ssh ubuntu@153.126.215.188 "cd /home/ubuntu/MCPletA2A/platform_impl && npm run build && cd ../reference_impl && npm run build && sudo systemctl restart mcplet-a2a"
Passkey Modes
| Mode | Config | Behavior |
|---|---|---|
https |
Local dev | Opens browser on server machine |
remote |
Production | Approval via Dashboard web UI notification |
demo |
Testing | Auto-approves all passkey ceremonies |
Current production config: reference_impl/config/reference.yaml → passkey.mode: remote
SSL Certificate
Managed by certbot. Auto-renews before expiry. To manually check:
sudo certbot certificates
sudo certbot renew --dry-run
Spec Compliance
| Requirement | Implementation |
|---|---|
mcpletType declaration + enforcement |
MCPletDiscovery.validate() rejects missing/invalid |
| Visibility filtering | PoolRegistry.getToolsForAgent() filters to model-visible for LLM |
| Per-agent Pool access | PoolRegistry.canAgentAccess() enforced in BaseAgent.invokeMCPlet() |
| action + model-visible + no auth → reject | MCPletDiscovery.validate() |
| Director Agent anti-concurrency | DirectorAgent.running flag |
| A2A local bus process-boundary | A2ALocalBus — in-memory only, no network |
| External Agent auth | Bearer token validation in A2AExternalEndpoint |
| Passkey Web Page (localhost mode) | Dynamic port, loopback-only, auto-close |
| action tool Passkey interception | BaseAgent.invokeMCPlet() Phase 2 intercept |
| Audit log for action tools | AuditLog.record() on every action invocation |