The shortest path to a working human+agent Sheets workflow in April 2026 is Claude Code with MCP, not the Claude web UI. Claude's native web/desktop Google Sheets integration is the weakest of the three major providers — its official Sheets add-on is effectively broken, and its Drive connector is read-focused. But Claude Code paired with the mcp-google-sheets MCP server (xing5, 654 stars, 19 tools) gives you full CRUD, formatting, formulas, and multi-sheet support today. For the Gmail/Drive→Sheet→Fortnox expense workflow, every step is feasible with current tooling. The Fortnox bridge works via either REST API (supplier invoices/vouchers) or SIE4 file generation — both are confirmed working patterns. The recommended architecture is one Claude Skill (sheets-collab) backed by two MCP servers (Google Workspace + Google Sheets), with a verb vocabulary that maps cleanly to actual backend capabilities.
Provider-by-provider capability matrix
The three major LLM providers occupy very different positions relative to Google Sheets. Gemini dominates inside the spreadsheet; Claude dominates in agentic/MCP workflows; ChatGPT sits in the middle with the broadest connector ecosystem but weakest Sheets-specific depth.
| Capability | ChatGPT (web/agent) | Claude (web/desktop) | Gemini (web/Sheets) |
|---|---|---|---|
| Native in-Sheets AI | ❌ Third-party add-ons only | ❌ Broken official add-on | ✅ Side panel + =AI() + Fill with Gemini |
| Read Sheets from chat | ✅ Drive App connector | ✅ Drive connector | ✅ Drive + native in Sheets |
| Write to Sheets from chat | ⚠️ Agent creates .xlsx; Drive actions emerging | ⚠️ Configurable but limited | ✅ Tables, formulas, charts, formatting |
| Create new Sheets | ⚠️ Creates Excel files | ⚠️ Via MCP on Desktop only | ✅ "Help me create" (March 2026) |
| Multiple tabs | Read only | Via MCP | ✅ Full multi-tab with selection |
| Formula generation | Via third-party add-ons | Via MCP | ✅ Native, including =AI() |
| Formatting | ❌ | Via MCP | ✅ Conditional formatting, number formats |
| Multi-turn editing | Moderate (Agent mode) | Low (web); better via MCP | Moderate-good (history lost on reload) |
| Multi-step compound actions | Via Agent | Via MCP tool chains | ✅ Single prompt → multiple actions (Oct 2025) |
| Minimum paid tier | Plus $20/mo | Pro $20/mo | Workspace + Gemini or AI Pro $20/mo |
| Best-in-class for | Broad connector ecosystem | Agentic MCP workflows | Native Sheets manipulation |
Opinionated pick for Konrad's use case: Claude Code + MCP for the agentic workflow, with Gemini in Sheets as the human-side editing companion. This hybrid gives you the best agent (Claude) controlling Sheets via API while the best in-sheet AI (Gemini) assists the human during review. They don't conflict — Claude writes via API, Konrad reviews with Gemini's side panel help.
Agentic and coding tools
| Tool | Status | Direct Sheets CRUD | Auth complexity | Solo dev cost | Best for |
|---|---|---|---|---|---|
| Claude Code + MCP | GA | ✅ Full via MCP | Medium (GCP setup) | $20/mo (Pro) | Terminal-based Sheets automation |
| Gemini CLI + MCP | GA, open-source | ✅ Full via MCP | Medium | Free (generous tier) | Google-ecosystem developers |
| Google Workspace Studio | GA (March 2026) | ✅ Via Workspace | Low | ~$12/mo (Business) | No-code Workspace agents |
| OpenAI Codex | GA | ❌ Writes code, not Sheets | Low | $20/mo (Plus) | Code generation only |
| Zapier MCP | GA | ✅ Full | Low (managed) | $30/mo | Quick no-code setup |
| n8n + AI | GA | ✅ Full | Medium | Free (self-host) | Complex AI pipelines |
| OpenAI Operator | Research preview | ⚠️ Browser control | Medium | $200/mo (Pro) | Experimental only |
| Project Mariner | Limited (US, AI Ultra) | ⚠️ Browser control | Low | $250/mo | Not practical today |
Key finding: MCP is the dominant protocol. Every serious agentic tool now supports MCP. It was donated to the Linux Foundation in December 2025, cementing it as the standard. StackOne For Konrad's self-hosted Ubuntu/Coolify setup, this is ideal — MCP servers run as simple processes alongside his existing infrastructure.
MCP and API landscape for Google Sheets, Drive, and Gmail
Google's official MCP story
Google shipped managed MCP servers in December 2025, but initially focused on Cloud services (BigQuery, GCE, GKE), not Workspace. ChatForest Google Cloud The Workspace path is through gws — a Rust binary wrapping all Google Workspace APIs with a built-in MCP server mode MCP Servers (gws mcp -s drive,gmail,sheets). Mintlify It's designed "with agents in mind" and supports service filtering. VentureBeat Each service exposes 10–80 tools, so filtering is essential to stay under MCP client tool limits. Mintlify
Google also maintains an open-source repo at github.com/google/mcp github with Workspace listed as a Gemini CLI extension. ChatForest GitHub The official Workspace Developer Tools MCP server currently serves developer documentation only, not live API operations DEV Community — a common source of confusion.
The three MCP servers that matter for this project
1. xing5/mcp-google-sheets — The Sheets specialist
- 654 stars, 19 tools, Python, uvx mcp-google-sheets@latest GitHub
- Full CRUD: create spreadsheets, add worksheets, read/write ranges, batch operations, formatting, sharing MCP Servers +2
- Auth: service account (recommended) or OAuth 2.0 GitHub PyPI
- ~13K tokens for all tool definitions; use tool filtering to reduce GitHub PyPI
- Self-hosted via Docker or bare process
- Pick this for: Dedicated Sheets operations with minimal token overhead
2. taylorwilsdon/google_workspace_mcp — The full Workspace suite
- 12 services (Gmail, Drive, Sheets, Docs, Calendar, Apps Script, etc.), 100+ tools Workspace MCP GitHub
- OAuth 2.1 multi-user support, GitHub Claude .dxt one-click install Workspace MCP
- Managed cloud hosting available at workspacemcp.com
- MIT license, Workspace MCP HTTP or stdio transport
- Pick this for: When you need Gmail + Drive + Sheets in one server
3. Composio — Zero-auth managed option - 44 Google Sheets tools Rube including "Execute SQL on Spreadsheet" Composio - Managed OAuth — Composio handles token refresh Composio - SOC 2 Type 2 compliant Composio - Hosted only, no self-hosting - Pick this for: Fastest initial setup, but vendor dependency
Auth models compared
| Server | OAuth 2.0 | Service account | Managed auth | Self-hostable |
|---|---|---|---|---|
| xing5/mcp-google-sheets | ✅ | ✅ (recommended) | ❌ | ✅ Docker/bare |
| taylorwilsdon workspace | ✅ (2.1) | ❌ | ✅ (cloud option) | ✅ + cloud |
| Composio | ✅ (managed) | ✅ (managed) | ✅ | ❌ |
| Zapier MCP | Managed | N/A | ✅ | ❌ |
Google gws CLI |
✅ | ✅ | ❌ | ✅ |
For Konrad's self-hosted setup, the best combination is xing5/mcp-google-sheets (for precise Sheets operations, service account auth, Docker-friendly) plus taylorwilsdon/google_workspace_mcp (for Gmail search and Drive file access). Both are MIT-licensed and can run in Coolify containers.
Practical gotchas
- Service accounts require sharing: Each spreadsheet/folder must be shared with the service account email. PyPI This is the biggest friction point.
- API rate limits: 300 read/300 write requests per minute per project, 100 requests per 100 seconds per user. More than sufficient for collaborative workflows; tight for bulk processing.
- Token context cost: The 19-tool xing5 server consumes ~13K tokens just for definitions. Filter to only the tools you need. GitHub PyPI
- OAuth token refresh: OAuth tokens expire hourly. Service accounts handle this automatically; OAuth 2.0 requires refresh token management.
- 5 million cell limit per Google Sheet Latenode — not a concern for expense tracking but worth knowing.
Direct Google APIs (what MCP servers miss)
Most MCP servers don't expose: pivot table creation, data validation rules, developer metadata, filter views, protected ranges (full API), chart customization beyond basics, and Drive file revisions/real-time watching. For advanced operations, direct Google Sheets API v4 calls via Apps Script or REST remain necessary.
Feasibility walkthrough: Gmail/Drive/zip → Sheet → Fortnox
Step 1: Ingest expenses from Gmail and/or Drive
Complexity: Medium — well-trodden path with existing templates.
The taylorwilsdon MCP server gives Claude Code direct access to search Gmail by label, read email bodies, and access attachments. n8n For receipt OCR, the pipeline is: Gmail attachment → download via Drive API → OCR via Gemini API or Google Cloud Vision → structured JSON → write to Sheet.
Multiple proven n8n workflow templates exist for exactly this: "AI-Powered Financial Document Extraction from Gmail to Google Sheets" uses Gemini for OCR and outputs 25+ standardized fields. n8n A Claude Code Skill could replicate this logic using MCP tools.
For .zip archives: Claude Code can unzip locally, iterate over receipt images/PDFs, extract data via multimodal analysis (Claude handles images natively), and batch-write results to a Sheet.
Human-in-the-loop handoff: After the initial extraction pass, flag low-confidence extractions (blurry receipts, ambiguous amounts, foreign currencies) in a dedicated Review Status column. The human reviews these in Google Sheets while the agent watches for status changes.
Simple parts: Gmail search by label, reading email metadata, writing structured data to Sheets. Complex parts: OCR accuracy on photographed receipts (70–90% depending on quality), currency detection, VAT rate inference, supplier matching against existing Fortnox supplier register.
Step 2: Create and structure the Google Sheet
Complexity: Simple — this is what MCP does best.
Claude Code via mcp-google-sheets can create a new spreadsheet, add tabs GitHub (e.g., "Expenses", "Suppliers", "Review", "Export Log"), set up headers, apply formatting, add data validation dropdowns for VAT rates (25%, 12%, 6%, 0%) and voucher series, insert conditional formatting for review status, and populate the initial data — all in a single multi-turn session.
The recommended sheet structure has 13 core columns:
| Column | Example | Notes |
|---|---|---|
| Supplier Name | "Kontorsmaterial AB" | From OCR/email |
| Supplier Number | "101" | Fortnox ID (auto-assignable) |
| Invoice/Transaction Date | 2025-01-15 | |
| Due Date | 2025-02-15 | For supplier invoices |
| Description | "Kontorsmaterial jan" | |
| Total Amount (incl. VAT) | 1250.00 | |
| Net Amount (excl. VAT) | 1000.00 | |
| VAT Amount | 250.00 | |
| VAT Rate % | 25 | Dropdown: 25/12/6/0 |
| Expense Account | 6110 | BAS kontoplan code |
| Currency | SEK | |
| Voucher Series | A | |
| External Invoice # | F-2025-001 | Supplier's own number |
Plus optional columns: Currency Rate, Cost Center, Project, Receipt File (Drive link), Payment Account, OCR Number, Review Status, Comments.
Human-in-the-loop handoff: The Sheet itself IS the handoff surface. Konrad reviews in the browser, corrects account codes, adjusts VAT rates, resolves flagged items. The agent can watch for a "Ready to Export" status column change.
Step 3: Export to Fortnox
Complexity: Medium for API path, Simple for SIE4 path.
Two confirmed export paths exist. Path A (recommended for automation): Google Apps Script or n8n reads the Sheet, constructs Fortnox API payloads (POST to /3/supplierinvoices or /3/vouchers), handles OAuth 2.0 token refresh, and optionally uploads receipt images to Fortnox's inbox and links them to the created records. Make.com has a native "Create Supplier Invoice" action that handles all of this with zero code. Make
Path B (recommended for simplicity): A ~150-line Apps Script generates a SIE4 plain-text file from the Sheet data, saves it to Drive, and Konrad manually imports it in Fortnox via Company Name → Import. Fortnox SIE4 is a tagged text format Invoicedataextraction — trivially generated from structured data. GitHub This path requires no API registration, no OAuth complexity, and works with any Fortnox plan that includes Bokföring.
Simple parts: SIE4 file generation (it's just structured text), Fortnox SIE4 import (built-in UI feature), reading structured data from Sheets. Complex parts: Fortnox OAuth 2.0 setup (one-time), ensuring debit/credit rows balance, supplier register synchronization, receipt file attachment via API.
The Sheet → Fortnox bridge is feasible
Confirmed. Both paths work:
REST API path: Fortnox's API at api.fortnox.se/3/ supports creating supplier invoices (/3/supplierinvoices) and vouchers (/3/vouchers) with full row-level detail. Fortnox Profitbase Authentication is OAuth 2.0 (JWTs, ~1 hour expiry, ~45-day refresh tokens). GitHub Rate limit is 25 requests per 5 seconds Fortnox — more than adequate. Fortnox API access requires free developer registration at fortnox.se/developer; the Fortnox customer needs the Bokföring module. GitHub Fortnox Each supplier invoice requires balanced debit/credit rows referencing BAS kontoplan accounts (2440 for leverantörsskulder, 2640/2641 for ingående moms, expense accounts like 5010/6110 for the cost). Fortnox
SIE4 path: SIE4 is Sweden's universal accounting interchange format — plain text, trivially parseable and generatable. GitHub Fortnox natively imports SIE types 1–4. Fortnox A working SIE4 file needs: header tags (#FLAGGA, #SIETYP 4, #FNAMN, #ORGNR, #RAR, #KPTYP BAS2014), account definitions (#KONTO), and voucher blocks (#VER with #TRANS rows). Commercial Excel-to-SIE4 converters already exist (Financial Template Store), and open-source Python generators are on GitHub. Financialtemplatestore Generating SIE4 from a Google Sheet via Apps Script is a known, working pattern.
The likely best path for Konrad: start with SIE4 generation (zero API complexity, works immediately) and graduate to REST API when the volume justifies automation.
SQL-esque vocabulary proposal
What the prior art teaches us
Twelve tools were evaluated for their vocabulary design. The key patterns:
Google Sheets QUERY() proves that SQL-lite works in spreadsheets. Ben Collins Its vocabulary — SELECT, WHERE, GROUP BY, ORDER BY, LIMIT, LABEL, FORMAT — is familiar to anyone with basic SQL knowledge. Coupler.io Blog Limitation: no JOINs, no subqueries, columns referenced by letter not name. Spreadsheet Point
DuckDB's GSheets extension (by the Evidence team) proves that full SQL over Sheets is viable, including write-back via COPY table TO 'sheet_url' (FORMAT gsheet). Duckdb-gsheets This is the closest existing implementation to what the Skill needs.
Grist is the most relevant design paradigm. It treats a spreadsheet as a relational database natively — typed columns, reference columns (foreign keys), Python formulas, SQL API endpoint. Its key insight: the spreadsheet IS the database, not a view of one. This is exactly the mental model the Claude Skill should adopt.
Steampipe demonstrates that APIs can be queried as SQL tables. Its Google Sheets plugin maps each tab to a Postgres table, enabling JOINs across tabs and even with other API data. This pattern is powerful for the "USE sheet as context" verb.
Rows.com shows the best hybrid vocabulary: spreadsheet formulas + QUERY function + natural language AI + API functions (GET, POST). Rows Its AI Analyst generates calculated columns, joins tables, and creates charts from natural language — the closest commercial product to what the Skill aims to be.
The verb vocabulary
The vocabulary is designed around a principle: every verb maps to at least one working backend today, and the Skill's help text tells the user exactly which backend is active.
| Verb | What it does | Syntax examples | Backend support |
|---|---|---|---|
| VIEW | Open and display a sheet, tab, .xlsx, or .csv | VIEW "Budget Q1" / VIEW tab:Expenses / VIEW file.xlsx |
MCP (read range), Claude Code (filesystem for local files) |
| SEARCH | Find files across Drive | SEARCH "invoices 2025" in:Drive/Accounting / SEARCH *.pdf in:Gmail label:receipts |
MCP (Drive search, Gmail search) |
| CREATE | Make a new Sheet with optional structure | CREATE "Expenses 2025" WITH cols: Date, Supplier, Amount, VAT, Account |
MCP (create spreadsheet + add worksheets + write headers) |
| READ | Query data with filters | READ Expenses WHERE Amount > 500 AND VAT = 25% / READ A1:D10 |
MCP (read range), Sheets QUERY() |
| UPDATE | Modify existing cells or ranges | UPDATE Expenses SET Account = 6110 WHERE Supplier = "IKEA" |
MCP (batch update) |
| DELETE | Remove rows matching a condition | DELETE FROM Expenses WHERE Status = "Duplicate" |
MCP (clear values, delete rows via batch) |
| COMBINE | Merge data from multiple sources | COMBINE Gmail:receipts + Drive:invoices INTO "All Expenses 2025" |
MCP chain (search → read → create → write) |
| CONVERT | Export to another format | CONVERT "Expenses 2025" TO SIE4 / CONVERT TO CSV / CONVERT TO Fortnox API |
Apps Script (SIE4), MCP (export), REST (Fortnox) |
| COMMENT | Add notes or enter suggesting mode | COMMENT B5 "Verify this VAT rate" / SUGGEST MODE ON |
MCP (notes API), or metadata column |
| HISTORY | Show version history or changes | HISTORY "Budget Q1" last 7 days |
Drive API (revisions), MCP (Drive) |
| USE | Load a sheet as context for the conversation | USE "Expenses 2025" AS context / USE tab:Suppliers AS lookup |
MCP (read all → inject into context) |
| WATCH | Monitor for changes | WATCH "Expenses 2025" every 5min / WATCH ON CHANGE notify |
Polling (MCP read on interval), Drive push notifications, Apps Script time-driven triggers |
| COLLAB | Coordinate human+agent editing | COLLAB START — agent writes to tab:Import, human reviews tab:Review / COLLAB STATUS |
Partition-based: agent owns designated ranges via MCP, human edits elsewhere |
| REFRESH | Re-read data or re-run a query | REFRESH / REFRESH Expenses |
MCP (re-read range) |
Concurrency and collaboration design
True simultaneous human+agent editing is viable today, but with important constraints. Google Sheets uses cell-level last-writer-wins conflict resolution. Edits to different cells merge cleanly. Same-cell conflicts: last write wins, Quora no locking mechanism exists.
The critical design pattern is data ownership partitioning: the agent writes to designated tabs/ranges (e.g., Import, Staging), the human edits in others (e.g., Review, Approved). Protected ranges can enforce these boundaries. The COLLAB verb makes this explicit.
The killer limitation: Apps Script onEdit and onChange triggers do NOT fire when changes come from the API. This means the agent cannot detect human edits via triggers. The workaround is polling (agent periodically re-reads the sheet) or a webhook pattern (human clicks an Apps Script button that calls a webhook to notify the agent). The WATCH verb abstracts this — it polls by default, with an option to wire up Drive push notifications for near-real-time detection of human saves.
Claude Skill architecture recommendation
One Skill, not a set
Use a single Skill called sheets-collab with a modular SKILL.md. Rationale: Skills are conversation-scoped instructions — splitting into multiple Skills forces the user to switch contexts or load multiple Skills. A single Skill with clear sections is discoverable and composable. The verb vocabulary provides internal modularity without requiring Skill boundaries.
SKILL.md structure
sheets-collab/
├── SKILL.md # Core: verb vocabulary, auth status, capability map
├── schema/
│ ├── expense-sheet.json # Column definitions for expense tracking
│ ├── fortnox-fields.json # Fortnox API required fields
│ └── sie4-template.txt # SIE4 header template
├── scripts/
│ ├── sie4-export.js # Apps Script for SIE4 generation
│ └── fortnox-auth.md # OAuth setup instructions
└── examples/
├── expense-workflow.md # Step-by-step expense pipeline
└── verb-examples.md # Syntax examples for every verb
The SKILL.md should contain:
- Capability declaration: Which MCP servers are available, what auth is configured, what verbs are active vs. unavailable
- Verb reference: The full vocabulary with syntax, mapped to which MCP tool each verb calls
- Schema awareness: The expense sheet structure (column names, types, validation rules, BAS kontoplan account code reference)
- Collaboration protocol: How data ownership partitioning works, how to signal "ready for review" vs. "ready for export"
- Fortnox bridge docs: Minimum fields, SIE4 format spec summary, API endpoint reference
- Escape hatches: When to drop to raw Apps Script, when to use Gemini in Sheets instead, when to suggest the human do something manually
MCP servers to wire up
For the self-hosted Ubuntu/Coolify setup:
-
xing5/mcp-google-sheets — Primary Sheets operations. Run via Docker:
uvx mcp-google-sheets@latest. PyPI GitHub Auth: service account (create a GCP project, download JSON key, share target Drive folder with service account email). PyPI GitHub Filter tools to the ~10 most-used to save context tokens. GitHub PyPI -
taylorwilsdon/google_workspace_mcp — Gmail search, Drive file access, Calendar (if needed later). Workspacemcp Run via Docker or
npx. Auth: OAuth 2.1 (one-time browser flow, then tokens persist). Workspacemcp GitHub Use the managed cloud option at workspacemcp.com if self-hosting OAuth is too fiddly initially. -
Fortnox (later): No MCP server exists. Build a thin custom MCP server wrapping
api.fortnox.se/3/with three tools:create_supplier_invoice,create_voucher,upload_receipt. Or skip this and use the SIE4 export path.
Register in Claude Code:
claude mcp add googlesheets --transport stdio -- uvx mcp-google-sheets@latest
claude mcp add workspace --transport http "https://workspacemcp.com/your-endpoint"
How the collaboration workflow should feel
Session start: User opens Claude Code (or Claude Desktop with MCP) and loads the sheets-collab Skill. Types: SEARCH Gmail label:receipts after:2025-03-01. Claude searches Gmail via the workspace MCP, lists matching emails with attachments.
Extraction: User types: COMBINE these receipts INTO "March 2025 Expenses". Claude reads each email/attachment, extracts expense data (using its own multimodal capabilities for images, or calling Gemini API for OCR), creates a new Google Sheet with the standard schema, writes all extracted data, flags low-confidence rows in a Review Status column.
Collaborative review: User opens the Sheet in browser. Sees the data. Uses Gemini in Sheets' side panel to help verify formulas, spot-check totals. Corrects account codes, updates VAT rates. Changes Review Status from "Needs Review" to "Approved" for verified rows.
Agent monitors: Back in Claude, user types: WATCH "March 2025 Expenses" tab:Expenses. Claude polls the sheet every few minutes, reports: "12 of 15 rows now marked Approved." User types: READ Expenses WHERE Status = "Needs Review" to see remaining items.
Export: User types: CONVERT "March 2025 Expenses" TO SIE4 WHERE Status = "Approved". Claude reads the approved rows, generates a SIE4 file, saves it to Drive. User downloads and imports into Fortnox. Done.
The entire workflow keeps the human in control of validation while the agent handles the tedious extraction, structuring, and format conversion. The Sheet is the shared workspace — both the agent and human can see and manipulate it, with clear ownership boundaries.
Automation later: what changes
Moving from collaborative to semi-autonomous to headless requires three upgrades, each independent:
Semi-autonomous (agent does more, human approves less): Add confidence scoring to the extraction step. High-confidence rows (>95% OCR match, known supplier, standard VAT rate) get auto-approved. Only edge cases surface for human review. Implementation: add a Confidence column to the Sheet, set a threshold in the Skill config. Effort: ~2 hours of Skill tuning.
Scheduled/cron (agent runs on a timer): Use n8n self-hosted on Coolify to trigger the full pipeline on a schedule — watch Gmail for new receipts, extract, write to Sheet, notify Konrad via Slack/email with a summary of what was added and what needs review. The Skill's WATCH verb becomes an n8n cron trigger instead of a polling loop. Alternatively, use Apps Script time-driven triggers Google (minimum interval: 1 minute). Effort: ~4 hours to set up n8n workflow or Apps Script trigger.
Headless/fully autonomous (no human in the loop): Wire the Fortnox API directly. Agent extracts → writes to Sheet → auto-exports approved rows to Fortnox → uploads receipt images → marks rows as "Exported" in Sheet. Requires building the thin Fortnox MCP server (or using Make.com's native Fortnox connector as a bridge). Make Add a reconciliation check: compare Fortnox voucher totals against Sheet totals to catch drift. Effort: ~8 hours for Fortnox API integration + reconciliation logic.
The progression is deliberate: start with the human seeing everything, then gradually hand off the boring parts. The Sheet remains the single source of truth at every stage — even in headless mode, the Sheet is the audit log. This matches Konrad's collaboration-first priority and lets him tighten the autonomy dial at his own pace.
One final note on Gemini CLI: It's free, open-source (98.7K GitHub stars), supports the same MCP servers, and runs natively in the Google ecosystem. If Konrad ever wants a second agent working alongside Claude — say, Gemini handling in-Sheets formula generation while Claude handles the extraction pipeline — the MCP architecture makes this trivial. Both agents talk to the same Sheet via the same protocol. The verb vocabulary in the Skill doesn't care which agent executes it.