Files
MCPletA2A/README.md
2026-04-01 10:43:30 +09:00

215 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |