# 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 ```bash cd platform_impl npm install npm run build ``` ### Configuration Copy and edit `config/platform.yaml`: ```bash 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] | | Email | `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 ```bash 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: ```bash 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 ```bash # 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 ```bash # 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: ```bash 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: ```bash 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 |