nanobot/docs/mcp_and_skills_backlog.md
tanyar09 7901f090f9 Add per-agent workspaces and MCP/skills backlog doc
- Add agent_workspaces/{ilia,family,wife} skeletons (AGENTS, USER, SOUL, memory)
- Add scripts/init-agent-workspaces.sh to populate ~/.nanobot/workspaces/
- Mount ~/.nanobot/workspaces/{ilia,family,wife} in multi compose as /workspace
- Document Step 0 and layout in DOCKER_MULTI_BOT_GUIDE.md
- Track docs/mcp_and_skills_backlog.md (force-add; docs/ is gitignored)

Made-with: Cursor
2026-03-30 13:20:38 -04:00

574 lines
30 KiB
Markdown
Raw Permalink 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.

# MCP Integrations & Skills Backlog
> **Living document** — update this file as items are implemented, reprioritized, or new candidates emerge.
>
> Last updated: 2026-03-30
---
## Table of Contents
1. [Current State](#current-state)
2. [Security: Local-Clone Policy](#security-local-clone-policy)
3. [Shortlist — Next Phase](#shortlist--next-phase)
4. [Backlog — Later](#backlog--later)
5. [Skill Catalog](#skill-catalog)
6. [Phase 1 Priorities](#phase-1-priorities)
7. [Implementation Notes](#implementation-notes)
---
## Current State
| Category | What we have today |
|---|---|
| **Built-in tools** | `filesystem` (read/write/edit/list), `exec` (shell), `web` (search + fetch), `message`, `spawn`, `cron`, `email` (IMAP), `calendar` (Google Calendar via built-in tool) |
| **MCP servers** | 1 connected — Gmail MCP (`@gongrzhe/server-gmail-autoauth-mcp`, stdio/npx). See [docs/gmail_mcp_setup.md](gmail_mcp_setup.md). |
| **Skills** | 10 bundled in `nanobot/skills/`: `github`, `gitea`, `calendar`, `cron`, `weather`, `summarize`, `tmux`, `clawhub`, `skill-creator`, `memory` |
| **Agent architecture** | 3 named agents, each running as a **separate Docker container** with its own workspace, personality, and memory (Option B). See below. |
| **Config schema** | `tools.mcpServers``MCPServerConfig` (stdio or HTTP), `tools.toolProfiles``ToolProfileConfig` can further filter tools within a single agent. See `nanobot/config/schema.py`. |
### Agent Workspaces
Each agent is a separate nanobot instance (Docker container) with an isolated workspace under `~/.nanobot/workspaces/`. The workspace contains bootstrap files (`AGENTS.md`, `SOUL.md`, `USER.md`) that define the agent's personality and instructions, plus a `memory/` directory for long-term memory that is private to that agent.
```
~/.nanobot/workspaces/
├── ilia/ # @ilia — personal dev, infra, research
│ ├── AGENTS.md # Dev/infra-focused instructions
│ ├── USER.md # Ilia's profile, preferences
│ ├── SOUL.md # Personality: technical, concise
│ └── memory/
│ └── MEMORY.md
├── family/ # @family — shared household agent
│ ├── AGENTS.md # Family scheduling, coordination
│ ├── USER.md # Family members, kids' info
│ ├── SOUL.md # Personality: warm, organized
│ └── memory/
│ └── MEMORY.md
└── wife/ # @wife — personal assistant for wife
├── AGENTS.md # Personal tasks, calendar, email
├── USER.md # Wife's profile, preferences
├── SOUL.md # Personality: friendly, helpful
└── memory/
└── MEMORY.md
```
Each container mounts its workspace and its own `config.json` (with agent-specific MCP servers, channels, and `allowFrom` lists). Compose service names are `nanobot-user1``user3`.
| Service | Persona | Config dir | Workspace (host → `/workspace`) | Typical channels |
|---|---|---|---|---|
| `nanobot-user1` | @ilia | `~/.nanobot-user1/` | `~/.nanobot/workspaces/ilia` | Telegram, email (Ilia) |
| `nanobot-user2` | @family | `~/.nanobot-user2/` | `~/.nanobot/workspaces/family` | Family Telegram |
| `nanobot-user3` | @wife | `~/.nanobot-user3/` | `~/.nanobot/workspaces/wife` | Telegram, email (wife) |
_Use `scripts/init-agent-workspaces.sh` to create the three workspace trees under `~/.nanobot/workspaces/`._
---
## Security: Local-Clone Policy
All new MCP servers are **cloned locally** into the repository rather than fetched at runtime from npm/PyPI registries. This gives us:
- **Audit control** — we can review every line before running it.
- **Reproducibility** — pinned commits, no surprise upstream updates.
- **Air-gap friendliness** — works on isolated networks after initial clone.
### Directory layout
```
nanobot/
├── mcp-servers/ # <-- NEW: local MCP server clones
│ ├── gitea-mcp/ # git clone from gitea.com/gitea/gitea-mcp
│ ├── google-calendar-mcp/ # git clone from github.com/nspady/google-calendar-mcp
│ ├── mcp-proxmox/ # git clone from github.com/antonio-mello-ai/mcp-proxmox
│ └── fetch-browser/ # git clone from github.com/TheSethRose/Fetch-Browser
├── nanobot/
├── docs/
└── ...
```
### Config pattern (local stdio)
```jsonc
{
"tools": {
"mcpServers": {
"gitea": {
"command": "./mcp-servers/gitea-mcp/gitea-mcp",
"args": ["--token", "$NANOBOT_GITLE_TOKEN", "--url", "http://10.0.30.169:3000"],
"env": {}
}
}
}
}
```
Each server's README in `mcp-servers/<name>/` documents build steps, required env vars, and update procedure.
---
## Shortlist — Next Phase
These are the 4 MCP servers we plan to integrate in the immediate next phase. Each entry is detailed enough to create implementation tickets directly.
---
### S1. Gitea MCP
| Field | Detail |
|---|---|
| **Upstream** | `gitea.com/gitea/gitea-mcp` (official, Go, v1.0.2, 56 stars, Apache-2.0) |
| **Transport** | Stdio (recommended) or SSE |
| **Auth** | Gitea personal-access token — reuse existing `$NANOBOT_GITLE_TOKEN` |
| **Complexity** | **Low** — token and network route to `http://10.0.30.169:3000` already exist |
| **Replaces** | Current curl-based `gitea` skill and hardcoded API commands in `AGENTS.md` |
| **Target agents** | `@ilia` only (dev tooling; not exposed to `@family` or `@wife`) |
#### User stories
- **US-G1**: As `@ilia`, I can say "list open PRs on nanobot" and get a formatted summary without writing curl commands.
- **US-G2**: As `@ilia`, I can say "search code for `MCPServerConfig`" and the agent returns matching files and lines from Gitea.
- **US-G3**: As `@ilia`, I can say "create an issue titled 'Add Proxmox MCP' with label `enhancement`" and the agent creates it in Gitea.
- **US-G4**: As `@ilia`, I can say "show diff for PR #42" and get a readable summary of changes.
#### Technical notes
- **Build**: Go 1.24+. Clone, `go build`, produces single binary `gitea-mcp`.
- **Local clone path**: `mcp-servers/gitea-mcp/`
- **Config entry**:
```jsonc
"gitea": {
"command": "./mcp-servers/gitea-mcp/gitea-mcp",
"args": [],
"env": {
"GITEA_URL": "http://10.0.30.169:3000",
"GITEA_TOKEN": "$NANOBOT_GITLE_TOKEN"
}
}
```
- **Expected tool names**: `mcp_gitea_list_repos`, `mcp_gitea_search_code`, `mcp_gitea_create_issue`, `mcp_gitea_list_pulls`, etc.
- **Safety**: Read operations are safe. Issue/PR creation and file writes should require user confirmation via tool-profile constraints.
---
### S2. Google Calendar MCP
| Field | Detail |
|---|---|
| **Upstream** | `github.com/nspady/google-calendar-mcp` (TypeScript, v2.6.1, 1071 stars, MIT) |
| **Transport** | Stdio via `node` |
| **Auth** | Google OAuth2 (same pattern as Gmail MCP — credentials in `~/.gmail-mcp/`) |
| **Complexity** | **Medium** — OAuth flow is already a solved pattern from Gmail MCP setup; multi-calendar config adds small overhead |
| **Complements** | Existing built-in `calendar` tool; MCP version adds multi-calendar, recurring events, and free/busy queries |
| **Target agents** | All three — `@ilia`, `@family`, `@wife` (each with their own calendar scope) |
#### User stories
- **US-C1**: As `@family`, I can ask "what's on the family calendar this week?" and get a merged view of all family members' events.
- **US-C2**: As `@ilia`, I can say "find a free 1-hour slot tomorrow afternoon" and the agent checks busy/free across my calendars.
- **US-C3**: As `@family`, I can say "add 'Soccer practice' to the family calendar on Saturday at 10am" and it creates the event.
- **US-C4**: As `@ilia`, I can say "reschedule my 2pm meeting to 4pm" and the agent updates the event after confirmation.
- **US-C5**: As `@wife`, I can say "what do I have on Thursday?" and see only events on my personal calendar.
#### Technical notes
- **Build**: `npm install` in cloned repo, run via `node dist/index.js`.
- **Local clone path**: `mcp-servers/google-calendar-mcp/`
- **OAuth setup**: Same Google Cloud project as Gmail MCP. Enable Calendar API, reuse existing OAuth client. Token stored alongside Gmail tokens.
- **Config entry**:
```jsonc
"google_calendar": {
"command": "node",
"args": ["./mcp-servers/google-calendar-mcp/dist/index.js"],
"env": {
"GOOGLE_OAUTH_CREDENTIALS": "~/.gmail-mcp/gcp-oauth.keys.json"
}
}
```
- **Expected tool names**: `mcp_google_calendar_list_events`, `mcp_google_calendar_create_event`, `mcp_google_calendar_freebusy`, `mcp_google_calendar_update_event`, `mcp_google_calendar_delete_event`
- **Migration path**: Phase out built-in `calendar` tool once MCP version is validated. Keep both available during transition via tool profiles.
---
### S3. Proxmox MCP
| Field | Detail |
|---|---|
| **Upstream** | `github.com/antonio-mello-ai/mcp-proxmox` (Python, pip-installable, MIT) |
| **Transport** | Stdio via `python -m mcp_proxmox` |
| **Auth** | Proxmox API token (user `nanobot@pam!mcp-token` + secret) |
| **Complexity** | **Medium** — requires network route to Proxmox cluster API, API token creation on Proxmox, and careful permission scoping |
| **New capability** | Homelab infrastructure visibility and management from chat |
| **Target agents** | `@ilia` only (infrastructure admin; never exposed to `@family` or `@wife`) |
#### User stories
- **US-P1**: As `@ilia`, I can say "show me the status of all VMs" and get a table of names, states, CPU, and RAM usage.
- **US-P2**: As `@ilia`, I can say "how much storage is left on the cluster?" and get aggregate numbers.
- **US-P3**: As `@ilia`, I can say "restart the dev-runner VM" and the agent does so after asking for confirmation.
- **US-P4**: As `@ilia`, I can say "take a snapshot of the nanobot VM before I upgrade" and the agent creates a named snapshot.
#### Technical notes
- **Build**: `pip install -e ./mcp-servers/mcp-proxmox/` into nanobot's venv, or use a dedicated venv.
- **Local clone path**: `mcp-servers/mcp-proxmox/`
- **Proxmox setup**:
1. Create API token: Datacenter → Permissions → API Tokens → Add (`nanobot@pam`, token ID `mcp-token`).
2. Assign minimum roles: `PVEAuditor` for read-only, `PVEVMAdmin` for lifecycle ops (Phase 1 starts read-only).
3. Store token secret in `~/.nanobot/config.json` env or in a `.env` file.
- **Config entry**:
```jsonc
"proxmox": {
"command": "python",
"args": ["-m", "mcp_proxmox"],
"env": {
"PROXMOX_HOST": "https://10.0.30.1:8006",
"PROXMOX_TOKEN_ID": "nanobot@pam!mcp-token",
"PROXMOX_TOKEN_SECRET": "$PROXMOX_TOKEN_SECRET",
"PROXMOX_VERIFY_SSL": "false"
}
}
```
- **Expected tool names**: `mcp_proxmox_list_nodes`, `mcp_proxmox_list_vms`, `mcp_proxmox_list_containers`, `mcp_proxmox_vm_status`, `mcp_proxmox_start_vm`, `mcp_proxmox_stop_vm`, `mcp_proxmox_create_snapshot`, `mcp_proxmox_list_storage`
- **Safety**: Phase 1 deploys with `PVEAuditor` role (read-only). Write operations (start/stop/snapshot) added in Phase 2 behind confirmation prompts. Restricted to `@ilia` profile only — never exposed to `@family`.
---
### S4. Web Fetch / Scraping MCP
| Field | Detail |
|---|---|
| **Upstream** | `github.com/TheSethRose/Fetch-Browser` (TypeScript, headless Chromium, MIT) |
| **Alt candidate** | `github.com/odgrim/mcp-fetch` (TypeScript, Puppeteer, simpler) |
| **Transport** | Stdio via `node` |
| **Auth** | None — no API keys required |
| **Complexity** | **Low** — clone, `npm install`, run; headless Chromium bundled by Puppeteer/Playwright |
| **Augments** | Built-in `web_fetch` tool (which does basic HTTP GET without JS rendering) |
| **Target agents** | All three — `@ilia`, `@family`, `@wife` |
#### User stories
- **US-W1**: As `@ilia`, I can say "fetch the Proxmox release notes page and summarize what's new" and the agent renders the JS-heavy page and extracts content.
- **US-W2**: As `@family`, I can say "get the lunch menu from the school website" and the agent scrapes the dynamically loaded content.
- **US-W3**: As `@ilia`, I can say "grab the pricing table from this SaaS page" and get structured data back.
- **US-W4**: As `@wife`, I can say "find me the best-rated recipe for lasagna" and the agent fetches and summarizes real recipe pages.
#### Technical notes
- **Build**: `npm install` in cloned repo.
- **Local clone path**: `mcp-servers/fetch-browser/`
- **Config entry**:
```jsonc
"web_scraper": {
"command": "node",
"args": ["./mcp-servers/fetch-browser/dist/index.js"],
"env": {}
}
```
- **Expected tool names**: `mcp_web_scraper_fetch_url`, `mcp_web_scraper_search_google`, `mcp_web_scraper_screenshot`
- **Resource note**: Headless Chromium uses ~200400 MB RAM per instance. Consider setting a process timeout or pool limit.
- **Safety**: Read-only by nature. No write side-effects. Safe for both `@ilia` and `@family`.
---
## Backlog — Later
Items below are future candidates, not yet scheduled. Grouped by domain. Each includes a candidate upstream project where one exists.
### Family / Life
| # | Integration | Upstream candidate | Notes |
|---|---|---|---|
| B-F1 | **CalDAV MCP** | `github.com/dominik1001/caldav-mcp` (Python, v0.4.0) | Universal calendar protocol. Enables Nextcloud, iCloud, ownCloud calendars. Useful if family moves off Google. |
| B-F2 | **Shared Todo / Household Tasks MCP** | `github.com/thijs-hakkenberg/mcp_todo` (Python, git-backed) | Git-backed collaborative task list with assignees, due dates, priorities, Kanban web UI, and Telegram bot. Good fit for family chores and grocery lists. |
| B-F3 | **Microsoft To Do MCP** | `github.com/akkilesh-a/microsoft-todo-mcp-server-self-hosted` (TypeScript) | Self-hosted HTTP transport. 15 tools for full task CRUD. Only relevant if family adopts Microsoft ecosystem. |
| B-F4 | **Home Assistant MCP** | TBD (community projects emerging) | Smart home control — lights, thermostat, locks, sensors. Requires Home Assistant instance on LAN. |
| B-F5 | **Shared Documents MCP** | TBD (Nextcloud WebDAV or Google Drive MCP) | Access family shared documents, photos, notes from chat. |
### Research
| # | Integration | Upstream candidate | Notes |
|---|---|---|---|
| B-R1 | **PDF RAG MCP** | `github.com/wesleygriffin/pdfrag` (Python, ChromaDB + sentence-transformers) | Semantic search over PDF papers. OCR support for scanned docs. Persistent vector index. |
| B-R2 | **Knowledge Base / Notes RAG MCP** | `github.com/alejandro-ao/RAG-MCP` (Python, FastMCP + ChromaDB) | Ingest markdown notes, docs, slides. Query with natural language. Supports LlamaParse for multi-format ETL. |
| B-R3 | **Zotero / Reference Manager MCP** | TBD | If user manages academic references in Zotero. Would expose library search, citation export, PDF retrieval. |
| B-R4 | **Arxiv / Semantic Scholar MCP** | TBD (API wrappers exist) | Direct paper search and metadata retrieval from academic APIs. |
### Dev / Infra
| # | Integration | Upstream candidate | Notes |
|---|---|---|---|
| B-D1 | **Filesystem MCP** | `github.com/mark3labs/mcp-filesystem-server` (Go, 622 stars) | Richer file ops than nanobot built-in (search, diff, metadata, copy trees). Useful for workspace automation. |
| B-D2 | **Docker / Portainer MCP** | `github.com/AI-Engineerings-at/homelab-mcp-bundle` (includes Portainer) | Container lifecycle, image management, compose operations. |
| B-D3 | **CI/CD Pipeline MCP** | TBD (Gitea Actions API or Drone) | Query pipeline status, trigger builds, view logs. Partially achievable through Gitea MCP's API. |
| B-D4 | **Logs & Monitoring MCP** | `github.com/AI-Engineerings-at/homelab-mcp-bundle` (includes Grafana, Uptime Kuma) | Query Grafana dashboards, check uptime monitors, search Loki logs. |
| B-D5 | **Backup Status MCP** | TBD (Proxmox Backup Server API or restic wrapper) | Check last backup timestamps, success/failure, storage usage. Could be a thin wrapper skill rather than full MCP. |
| B-D6 | **Database MCP** | TBD (PostgreSQL / SQLite MCP servers exist) | Run read-only queries against app databases for debugging and reporting. |
---
## Skill Catalog
Skills are higher-level task patterns that compose one or more tools (built-in or MCP) into a reusable workflow. Each skill lives as a `SKILL.md` in `nanobot/skills/<name>/` and is loaded by the skills system.
Because agents are **separate containers with separate workspaces**, a skill is available to an agent only if (a) the skill file is present in that workspace's `skills/` dir or in the shared bundled skills, and (b) the MCP servers it depends on are configured in that agent's `config.json`.
### Legend
| Column | Meaning |
|---|---|
| **Skill** | Natural-language trigger name |
| **Description** | What the skill does |
| **MCP deps** | Which MCP servers must be connected in the agent's config |
| **Built-in deps** | Which nanobot built-in tools are also needed |
| **Target agents** | Which agent containers should have this skill deployed (`@ilia`, `@family`, `@wife`) |
| **Safety tier** | `read-only` / `write-confirm` (mutates after user confirmation) / `admin` (restricted + confirm) |
---
### Scheduling Skills
| Skill | Description | MCP deps | Built-in deps | Target agents | Safety tier |
|---|---|---|---|---|---|
| **Plan my week** | List events across all calendars for the next 7 days, highlight conflicts, suggest time blocks for focus work | Google Calendar MCP | — | `@ilia`, `@family`, `@wife` | read-only |
| **Reschedule meeting** | Find a specific event, propose 3 alternative conflict-free times, update the event after user picks one | Google Calendar MCP | — | `@ilia`, `@wife` | write-confirm |
| **Find conflict-free times** | Query free/busy across calendars for a given duration and date range, return available slots | Google Calendar MCP | — | `@ilia`, `@family`, `@wife` | read-only |
### Email Skills
| Skill | Description | MCP deps | Built-in deps | Target agents | Safety tier |
|---|---|---|---|---|---|
| **Triage inbox** | Fetch unread emails, categorize by urgency (action-required / FYI / low-priority), surface top action items | Gmail MCP | `read_emails` | `@ilia`, `@wife` | read-only |
| **Draft replies** | For each action-required email, generate a draft reply. Present drafts for user approval before sending | Gmail MCP | — | `@ilia`, `@wife` | write-confirm |
| **Summarize today's mail** | Produce a concise digest of all emails received today, grouped by sender or topic | Gmail MCP | `read_emails` | `@ilia`, `@family`, `@wife` | read-only |
### Research Skills
| Skill | Description | MCP deps | Built-in deps | Target agents | Safety tier |
|---|---|---|---|---|---|
| **Find relevant papers** | Web-search for papers on a given topic, fetch top results, return title + abstract + URL for each | Web Fetch MCP | `web_search` | `@ilia` | read-only |
| **Summarize URL/PDF** | Fetch a URL (with JS rendering if needed) or read a local PDF, produce a structured summary | Web Fetch MCP | `read_file` | `@ilia`, `@family`, `@wife` | read-only |
| **Generate experiment checklist** | Given a goal description, produce a structured checklist of steps, tools needed, and success criteria | — | — | `@ilia` | read-only |
### Infra Skills
| Skill | Description | MCP deps | Built-in deps | Target agents | Safety tier |
|---|---|---|---|---|---|
| **Show VM status** | List all VMs/containers across Proxmox nodes with state, CPU%, RAM%, and uptime | Proxmox MCP | — | `@ilia` | read-only |
| **Restart non-critical service** | Stop and start a VM by name, but only if it is tagged `non-critical`. Refuse if tagged `critical`. Requires confirmation | Proxmox MCP | — | `@ilia` | admin |
| **Summarize cluster resources** | Aggregate CPU, RAM, and storage usage across all Proxmox nodes, flag any node above 80% utilization | Proxmox MCP | — | `@ilia` | read-only |
| **Pre-upgrade snapshot** | Before a maintenance window, create a named snapshot of specified VMs. Requires confirmation | Proxmox MCP | — | `@ilia` | admin |
### Dev Skills
| Skill | Description | MCP deps | Built-in deps | Target agents | Safety tier |
|---|---|---|---|---|---|
| **Summarize open PRs** | List all open PRs on the nanobot repo with title, author, age, review status, and CI state | Gitea MCP | — | `@ilia` | read-only |
| **Triage Gitea issues** | Fetch open issues, group by label, suggest priority ordering based on age and activity | Gitea MCP | — | `@ilia` | read-only |
| **Search codebase** | Search Gitea-hosted code for a symbol or string pattern, return matching files and line numbers | Gitea MCP | — | `@ilia` | read-only |
| **Create issue from chat** | Turn a conversation excerpt into a well-formatted Gitea issue with title, description, and labels. Requires confirmation | Gitea MCP | — | `@ilia` | write-confirm |
---
## Phase 1 Priorities
These are the items we commit to implementing first, chosen for maximum daily value with manageable complexity.
### Phase 1 MCP Integrations
| Priority | MCP Server | Rationale |
|---|---|---|
| **P1** | **Gitea MCP** | Directly replaces fragile curl-based Gitea access scattered across `AGENTS.md` and the `gitea` skill. Token and network route already exist. Aligns with daily dev workflow — PRs, issues, code search are used every day. |
| **P2** | **Google Calendar MCP** | Complements the existing built-in `calendar` tool with multi-calendar views and free/busy queries. OAuth is already a solved pattern from Gmail MCP. Deployed to all three agents — `@ilia` (work calendar), `@family` (shared family calendar), `@wife` (personal calendar). |
| **P3** | **Proxmox MCP** | Homelab infrastructure is checked frequently but currently requires opening the Proxmox web UI. Starting with read-only (`PVEAuditor`) makes it safe to deploy immediately. Write ops follow in a later phase. |
### Phase 1 Skills
| Priority | Skill | MCP dep | Agents | Safety | Why first |
|---|---|---|---|---|---|
| **S1** | Summarize open PRs | Gitea MCP | `@ilia` | read-only | Used daily; validates Gitea MCP end-to-end |
| **S2** | Plan my week | Google Calendar MCP | `@ilia`, `@family`, `@wife` | read-only | High value for every agent; validates Calendar MCP |
| **S3** | Triage inbox | Gmail MCP (already live) | `@ilia`, `@wife` | read-only | Formalizes an existing ad-hoc pattern; no new MCP needed |
| **S4** | Show VM status | Proxmox MCP | `@ilia` | read-only | Safe first infra skill; validates Proxmox MCP |
| **S5** | Summarize today's mail | Gmail MCP (already live) | `@ilia`, `@family`, `@wife` | read-only | Daily value for all agents; no new MCP needed |
---
## Implementation Notes
### Local clone workflow
```bash
# One-time setup
mkdir -p mcp-servers && cd mcp-servers
# Gitea MCP (Go)
git clone https://gitea.com/gitea/gitea-mcp.git
cd gitea-mcp && go build -o gitea-mcp . && cd ..
# Google Calendar MCP (TypeScript)
git clone https://github.com/nspady/google-calendar-mcp.git
cd google-calendar-mcp && npm install && npm run build && cd ..
# Proxmox MCP (Python)
git clone https://github.com/antonio-mello-ai/mcp-proxmox.git
cd mcp-proxmox && pip install -e . && cd ..
# Fetch Browser (TypeScript)
git clone https://github.com/TheSethRose/Fetch-Browser.git fetch-browser
cd fetch-browser && npm install && npm run build && cd ..
```
To update a server: `cd mcp-servers/<name> && git pull && <rebuild>`. Pin to a known-good commit with `git checkout <sha>` for production stability.
### Per-agent MCP wiring
Since each agent is a separate Docker container, MCP servers are configured in each agent's own `config.json`. An agent only gets the MCP servers listed in its config -- no routing needed.
**`~/.nanobot-user1/config.json`** (@ilia — all MCP servers):
```jsonc
{
"tools": {
"mcpServers": {
"gmail_mcp": { "command": "npx", "args": ["-y", "@gongrzhe/server-gmail-autoauth-mcp"] },
"gitea": { "command": "./mcp-servers/gitea-mcp/gitea-mcp", "args": [], "env": { "GITEA_URL": "http://10.0.30.169:3000", "GITEA_TOKEN": "$NANOBOT_GITLE_TOKEN" } },
"google_calendar": { "command": "node", "args": ["./mcp-servers/google-calendar-mcp/dist/index.js"], "env": { "GOOGLE_OAUTH_CREDENTIALS": "~/.gmail-mcp/gcp-oauth.keys.json" } },
"proxmox": { "command": "python", "args": ["-m", "mcp_proxmox"], "env": { "PROXMOX_HOST": "https://10.0.30.1:8006", "PROXMOX_TOKEN_ID": "nanobot@pam!mcp-token", "PROXMOX_TOKEN_SECRET": "$PROXMOX_TOKEN_SECRET", "PROXMOX_VERIFY_SSL": "false" } },
"web_scraper": { "command": "node", "args": ["./mcp-servers/fetch-browser/dist/index.js"], "env": {} }
}
}
}
```
**`~/.nanobot-user2/config.json`** (@family — scheduling + web only, no dev/infra):
```jsonc
{
"tools": {
"mcpServers": {
"google_calendar": { "command": "node", "args": ["./mcp-servers/google-calendar-mcp/dist/index.js"], "env": { "GOOGLE_OAUTH_CREDENTIALS": "~/.gmail-mcp/gcp-oauth.keys.json" } },
"web_scraper": { "command": "node", "args": ["./mcp-servers/fetch-browser/dist/index.js"], "env": {} }
}
}
}
```
**`~/.nanobot-user3/config.json`** (@wife — email + calendar + web, no dev/infra):
```jsonc
{
"tools": {
"mcpServers": {
"gmail_mcp": { "command": "npx", "args": ["-y", "@gongrzhe/server-gmail-autoauth-mcp"] },
"google_calendar": { "command": "node", "args": ["./mcp-servers/google-calendar-mcp/dist/index.js"], "env": { "GOOGLE_OAUTH_CREDENTIALS": "~/.gmail-mcp/gcp-oauth.keys.json" } },
"web_scraper": { "command": "node", "args": ["./mcp-servers/fetch-browser/dist/index.js"], "env": {} }
}
}
}
```
**MCP server allocation summary:**
| MCP Server | `@ilia` | `@family` | `@wife` |
|---|---|---|---|
| Gmail MCP | yes | -- | yes |
| Gitea MCP | yes | -- | -- |
| Google Calendar MCP | yes | yes | yes |
| Proxmox MCP | yes | -- | -- |
| Web Fetch MCP | yes | yes | yes |
Key points:
- `@family` and `@wife` never see Gitea or Proxmox tools -- those MCP servers are simply absent from their configs.
- `@family` has no email MCP (it's a shared household bot, not tied to one inbox). It still has the built-in `calendar` and `web` tools.
- Each container spawns its own MCP server processes via stdio from the shared `mcp-servers/` directory (mounted read-only into all containers).
### Safety tiers
| Tier | Behavior | Implementation |
|---|---|---|
| **read-only** | Tool executes immediately, no confirmation prompt | Default for query/list/search operations |
| **write-confirm** | Agent presents a summary of what it will do, waits for user "yes" before executing | Enforced in SKILL.md instructions: "Before calling `create_event`, show the user the details and ask for confirmation" |
| **admin** | Same as write-confirm but tool is only available in the `@ilia` container | Enforced by omitting the MCP server from other agents' `config.json` + SKILL.md confirmation instructions |
With separate containers, the strongest security boundary is **not configuring an MCP server at all** in an agent's config. Proxmox and Gitea are never in `@family` or `@wife` configs, so those agents physically cannot call those tools.
Phase 1 deploys **only read-only skills**. Write skills (draft replies, reschedule meeting, create issue, restart VM) are Phase 2 once we validate the read paths.
### Skill file template
New skills follow the existing format in `nanobot/skills/`:
```markdown
---
name: summarize-open-prs
description: "List and summarize all open pull requests on the nanobot Gitea repo."
metadata: {"nanobot":{"emoji":"📋","requires":{"mcp":["gitea"]}}}
---
# Summarize Open PRs
## When to use
User asks about open PRs, pending reviews, or code review status.
## Steps
1. Call `mcp_gitea_list_pulls` with state=open.
2. For each PR, extract: title, author, created date, review status, CI status.
3. Format as a numbered list sorted by age (oldest first).
4. Highlight PRs with no reviews or failing CI.
## Safety
Read-only. No confirmation needed.
```
### Docker considerations
All three containers (`nanobot-user1`, `nanobot-user2`, `nanobot-user3`) share the same Docker image. MCP server processes are spawned inside each container as needed. The Dockerfile must include:
- **Go** (for Gitea MCP binary — or copy pre-built binary)
- **Node.js 18+** (for Calendar MCP and Fetch Browser)
- **Python pip deps** (for Proxmox MCP — install into the same venv or a sidecar)
- **Chromium** (for Fetch Browser headless rendering — `npx puppeteer browsers install chrome` or use Playwright)
The `mcp-servers/` directory is mounted read-only into all containers so each agent can spawn the MCP servers listed in its config. Alternatively, build MCP binaries in a multi-stage Docker build and copy only the artifacts into the image.
**Volume mounts (per container)** — compose services remain `nanobot-user1` / `user2` / `user3`; they map to `@ilia` / `@family` / `@wife` workspaces.
```yaml
nanobot-user1: # @ilia
volumes:
- ~/.nanobot-user1:/root/.nanobot
- ~/.nanobot/workspaces/ilia:/workspace
# Optional: ./mcp-servers:/app/mcp-servers:ro
nanobot-user2: # @family
volumes:
- ~/.nanobot-user2:/root/.nanobot
- ~/.nanobot/workspaces/family:/workspace
nanobot-user3: # @wife
volumes:
- ~/.nanobot-user3:/root/.nanobot
- ~/.nanobot/workspaces/wife:/workspace
```
### Rollout sequence
```
Week 1: Clone repos, build locally, verify each MCP server starts and lists tools
Week 2: Wire Gitea MCP + "Summarize open PRs" skill, validate end-to-end
Week 3: Wire Calendar MCP + "Plan my week" skill, formalize "Triage inbox" skill
Week 4: Wire Proxmox MCP (read-only) + "Show VM status" skill
Week 5: Add "Summarize today's mail" skill, integrate Web Fetch MCP
Week 6: Retrospective, update this document, plan Phase 2 write-skills
```
---
## Changelog
| Date | Change |
|---|---|
| 2026-03-30 | Updated to reflect multi-container workspace architecture (Option B). Added `@wife` as third agent. Rewrote per-agent MCP wiring with separate config.json per container. Updated skill assignments across all three agents. |
| 2026-03-30 | Initial version — shortlist (4 MCP), backlog (16 ideas), skill catalog (16 skills), Phase 1 defined (3 MCP + 5 skills) |