Milestone 0: import zappier billing, Verae middleware, and Zapier research
Compose-ready workspace: packages/zappier (rate card, portal, Stripe), packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier (CLI app), vendor/zapier-platform, and research/zapier vendor corpus. Gate 0 structure checks pass. Product code and research are not yet wired.
This commit is contained in:
commit
b4150c8250
1364 changed files with 6814366 additions and 0 deletions
362
research/zapier/MCP-REFERENCE.md
Normal file
362
research/zapier/MCP-REFERENCE.md
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
# Zapier MCP function reference
|
||||
|
||||
**Grok start:** `db.platform_reference.findOne({ kind: "guide", key: "build-new-connector" })`
|
||||
or [PLATFORM-REFERENCE.md](PLATFORM-REFERENCE.md). This file is the MCP branch.
|
||||
|
||||
Mongo: `db.platform_reference.find({ kind: "mcp_function" })` — one document per tool, with JSON Schema, typed inputs, outputs, internals, related tools, and code.
|
||||
|
||||
Hosted server: `https://mcp.zapier.com/api/v1/connect` (closed source, Streamable HTTP).
|
||||
Plugin repo only: `repos/zapier-mcp` (skills + manifests).
|
||||
Live input schemas captured in `raw/site-extras/zapier-mcp-tools-gumloop.json`.
|
||||
|
||||
Official docs still list **14** meta-tools. Live servers expose **17**: the 14 plus `list_zapier_connections`, `manage_zapier_connections`, and rolling-out `write_code_action`.
|
||||
|
||||
---
|
||||
|
||||
## Call graph
|
||||
|
||||
```
|
||||
auto_provision_mcp (also runs on OAuth connect)
|
||||
│
|
||||
▼
|
||||
discover_zapier_actions ──► enable_zapier_action ──► manage_zapier_connections
|
||||
│ │
|
||||
└──────────────► inspect_zapier_actions ◄── list_zapier_connections
|
||||
(repeat for enums / dynamic fields)
|
||||
┌───────────────┴───────────────┐
|
||||
▼ ▼
|
||||
execute_zapier_read_action execute_zapier_write_action
|
||||
│ │
|
||||
└──────── write_code_action ────┘
|
||||
|
||||
Skills: list_zapier_skills → get_zapier_skill("zapier:onboarding")
|
||||
create_zapier_skill / update_zapier_skill / delete_zapier_skill
|
||||
Config UI: get_configuration_url
|
||||
Feedback: send_feedback
|
||||
```
|
||||
|
||||
Safety: reads run free; writes need explicit user approval after you show the payload.
|
||||
Billing: each **successful** execute costs **2 Zapier tasks**. Meta-tools do not. Failures are free.
|
||||
|
||||
Never invent `selected_api` (Gmail is `GoogleMailV2CLIAPI`, not `GmailCLIAPI`) or action keys. Always `inspect_zapier_actions` first.
|
||||
|
||||
---
|
||||
|
||||
## Action management
|
||||
|
||||
### `discover_zapier_actions`
|
||||
|
||||
Search the 9,000+ app catalog for actions this server *could* enable. Call before saying an app is unavailable.
|
||||
|
||||
**Internals:** Catalog lookup (same directory as SDK `listApps` / `listActions`). No OAuth, no mutation. Returns `selected_api` that later tools require verbatim.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
app?: string; // Search by name. Omit for popular apps.
|
||||
};
|
||||
```
|
||||
|
||||
**Output (documented):** `{ apps: [{ app, selected_api, actions[] }] }`
|
||||
|
||||
**Related:** `enable_zapier_action`, `inspect_zapier_actions`, `manage_zapier_connections`
|
||||
**SDK twin:** `zapier.listApps({ search })`, `zapier-sdk list-apps --search`
|
||||
|
||||
```ts
|
||||
await client.callTool({
|
||||
name: "discover_zapier_actions",
|
||||
arguments: { app: "gmail" },
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `enable_zapier_action`
|
||||
|
||||
Add one action (or `*` / omit for all) for a catalog app to this server.
|
||||
|
||||
**Internals:** Writes mcp.zapier.com server config. If the user has no connection, returns `auth_url`. Does not call the partner API.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string; // e.g. "GoogleMailV2CLIAPI" from discover
|
||||
app_display_name?: string; // "Gmail" — for friendly confirmations
|
||||
action?: string; // key, or "*" / omit for all
|
||||
};
|
||||
```
|
||||
|
||||
**Output:** enabled action list, which execute tool to use (read vs write), optional `auth_url`.
|
||||
|
||||
**Related:** `discover_zapier_actions`, `inspect_zapier_actions`, `disable_zapier_action`, `manage_zapier_connections`
|
||||
|
||||
```ts
|
||||
await client.callTool({
|
||||
name: "enable_zapier_action",
|
||||
arguments: {
|
||||
selected_api: "GoogleMailV2CLIAPI",
|
||||
app_display_name: "Gmail",
|
||||
action: "find_email",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `disable_zapier_action`
|
||||
|
||||
Remove one action, or every action for `selected_api`. Does not revoke the Zapier connection.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string;
|
||||
app_display_name?: string;
|
||||
action?: string; // omit = disable the whole app on this server
|
||||
};
|
||||
```
|
||||
|
||||
**Related:** `inspect_zapier_actions`, `enable_zapier_action`
|
||||
|
||||
---
|
||||
|
||||
### `inspect_zapier_actions`
|
||||
|
||||
**Call this first before every execute.** Lists enabled apps/actions and resolves dynamic fields.
|
||||
|
||||
**Internals:** Reads this server's enabled-action table. With `tool_name` + `enum_property` it hits the same Platform dynamic-dropdown endpoint as the visual builder. With parent `params` it returns `dynamic_properties_schema` for fields that depend on earlier answers (spreadsheet → worksheet). Does not run the partner action.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api?: string;
|
||||
action?: string;
|
||||
tool_name?: string; // collision-safe id from a prior inspect
|
||||
connection_id?: number | string; // only if not using the default account
|
||||
enum_property?: string; // field with is_dynamic_enum: true
|
||||
enum_search?: string;
|
||||
enum_cursor?: string;
|
||||
params?: Record<string, unknown>; // parent values for dependent fields
|
||||
};
|
||||
```
|
||||
|
||||
**Output (documented):** apps → actions with `action`, `tool_name`, execute tool name, parameter schema (`is_dynamic_enum`, `dynamic_properties_depends_on`), `connections.default`, plus `dynamic_enum_values` / `dynamic_properties_schema` on follow-up calls.
|
||||
|
||||
**Related:** both `execute_*`, `discover_zapier_actions`, `list_zapier_connections`
|
||||
**SDK twin:** `getActionInputFieldsSchema`, `list-action-input-field-choices`
|
||||
|
||||
```ts
|
||||
await client.callTool({ name: "inspect_zapier_actions", arguments: {} });
|
||||
|
||||
await client.callTool({
|
||||
name: "inspect_zapier_actions",
|
||||
arguments: {
|
||||
tool_name: "SlackCLIAPI.send_channel_message",
|
||||
enum_property: "channel",
|
||||
enum_search: "launches",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `auto_provision_mcp`
|
||||
|
||||
One-shot setup from the user's **own** existing Zapier connections (not shared teammates'). Also runs automatically after OAuth connect. Returns enabled apps plus top Zap titles (skill ideas). No inputs.
|
||||
|
||||
**Related:** `inspect_zapier_actions`, `enable_zapier_action`
|
||||
|
||||
---
|
||||
|
||||
## Execution
|
||||
|
||||
### `execute_zapier_read_action`
|
||||
|
||||
Run a search / lookup / get. No confirmation required. **2 tasks** on success.
|
||||
|
||||
**Internals:** Maps to Zapier Platform search/read `perform` (`runAction({ actionType: "search"|"read" })`) using the user's default connection (or `connection_id`). `params` → `bundle.inputData`. Empty results = not found, not an error.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string;
|
||||
action: string; // exact key from inspect — never guess
|
||||
tool_name?: string; // preferred when keys collide across apps
|
||||
connection_id?: number | string;
|
||||
params?: Record<string, unknown>; // nest dynamic fields under dynamic_properties
|
||||
};
|
||||
```
|
||||
|
||||
**Output:** action-specific records (`results[]` or `data[]`). 401 → `manage_zapier_connections`.
|
||||
|
||||
**Related:** `inspect_zapier_actions`, `discover_zapier_actions`, `enable_zapier_action`
|
||||
**SDK twin:** `repos/sdk/examples/by-app/*/find-*.ts`
|
||||
|
||||
```ts
|
||||
await client.callTool({
|
||||
name: "execute_zapier_read_action",
|
||||
arguments: {
|
||||
selected_api: "GoogleMailV2CLIAPI",
|
||||
action: "find_email",
|
||||
tool_name: "GoogleMailV2CLIAPI.find_email",
|
||||
params: { query: "from:sarah@acme.com newer_than:7d" },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If the user said only a first name, do **not** take the first hit — list candidates.
|
||||
|
||||
---
|
||||
|
||||
### `execute_zapier_write_action`
|
||||
|
||||
Create / update / send. **Show the payload and wait for explicit approval.** **2 tasks** on success. Not rolled back.
|
||||
|
||||
**Input:** same shape as the read execute.
|
||||
|
||||
**Related:** `inspect_zapier_actions`, `execute_zapier_read_action`
|
||||
**SDK twin:** `repos/sdk/examples/by-app/gmail/send-email.ts`
|
||||
|
||||
```ts
|
||||
// 1) inspect + resolve channel enum 2) confirm with user 3) write
|
||||
await client.callTool({
|
||||
name: "execute_zapier_write_action",
|
||||
arguments: {
|
||||
selected_api: "SlackCLIAPI",
|
||||
action: "send_channel_message",
|
||||
tool_name: "SlackCLIAPI.send_channel_message",
|
||||
params: { channel: "C01234567", text: "Release shipped, monitoring now" },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `write_code_action` (rolling out)
|
||||
|
||||
Generate a sandboxed custom action when the catalog has no match. Auth is injected from the connected account — **never put secrets in `requirements`**. Same-name call overwrites.
|
||||
|
||||
**Internals:** Zapier generates code and runs later invokes in a sandbox with the app connection. Closest SDK analog is `zapier.fetch(url, { connection, method })`.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string;
|
||||
code_action_name: string; // e.g. "list_channel_users"
|
||||
requirements: string; // natural language; endpoint, filters, pagination
|
||||
};
|
||||
```
|
||||
|
||||
**Related:** `discover_zapier_actions`, `inspect_zapier_actions`
|
||||
|
||||
---
|
||||
|
||||
## Connections
|
||||
|
||||
### `list_zapier_connections`
|
||||
|
||||
List OAuth grants for one app. Default = the user's own accounts. Set `include_shared: true` only if they asked.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string;
|
||||
include_shared?: boolean;
|
||||
limit?: number; // 1–100, default 20
|
||||
cursor?: string;
|
||||
};
|
||||
```
|
||||
|
||||
**Output (documented):** `{ connections: [{ connection_id, title, owner, is_default, expired }], next_cursor? }`
|
||||
|
||||
**SDK twin:** `zapier.findFirstConnection`, `zapier-sdk find-first-connection`
|
||||
|
||||
---
|
||||
|
||||
### `manage_zapier_connections`
|
||||
|
||||
Mint an `auth_url` and/or set `default_connection_id`. An app **cannot execute** until it has a default connection. After the user finishes OAuth, list then optionally set default.
|
||||
|
||||
**Input**
|
||||
|
||||
```ts
|
||||
type Input = {
|
||||
selected_api: string; // verbatim from discover/inspect
|
||||
app_display_name?: string;
|
||||
default_connection_id?: number | string;
|
||||
};
|
||||
```
|
||||
|
||||
**SDK twin:** `zapier-sdk create-connection` / `get-connection-start-url`
|
||||
|
||||
---
|
||||
|
||||
## Skills, config, feedback
|
||||
|
||||
| Tool | Input | What it does |
|
||||
|------|--------|----------------|
|
||||
| `list_zapier_skills` | `{}` | Names + one-line descriptions. Catalog is dynamic. |
|
||||
| `get_zapier_skill` | `{ name }` | Full Markdown. Packaged: `zapier:onboarding`. |
|
||||
| `create_zapier_skill` | `{ name, description, skillDefinition }` | Persist Markdown. Lock IDs with `ZapierAction[app:action](param: "id", runtime)`. Resolve schemas via `inspect_zapier_actions` (tool text still says `list_enabled_zapier_actions`). |
|
||||
| `update_zapier_skill` | `{ name, description?, skillDefinition? }` | Patch. |
|
||||
| `delete_zapier_skill` | `{ name }` | Permanent. |
|
||||
| `get_configuration_url` | `{}` | Dashboard URL for this server. |
|
||||
| `send_feedback` | `{ feedback: string(1–2000), feedback_positive: boolean }` | Product inbox. |
|
||||
|
||||
Official first-run prompt:
|
||||
|
||||
```text
|
||||
Run the Zapier onboarding skill using get_zapier_skill with name "zapier:onboarding" and follow its instructions.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Client connection (TypeScript)
|
||||
|
||||
```ts
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(
|
||||
new URL("https://mcp.zapier.com/api/v1/connect"),
|
||||
{ requestInit: { headers: { Authorization: `Bearer ${token}` } } },
|
||||
);
|
||||
const client = new Client({ name: "app", version: "1.0.0" });
|
||||
await client.connect(transport);
|
||||
const tools = await client.listTools();
|
||||
```
|
||||
|
||||
Listed clients use OAuth to that same URL and never see the token.
|
||||
|
||||
---
|
||||
|
||||
## Plugin skills (not server tools)
|
||||
|
||||
In `repos/zapier-mcp/plugins/zapier/skills/`:
|
||||
|
||||
| Skill | When |
|
||||
|-------|------|
|
||||
| `zapier-onboard` | First connect / “what is Zapier MCP” |
|
||||
| `zapier-demo` | One read action, live |
|
||||
| `zapier-explore` | Role-tailored toolkit |
|
||||
| `zapier-status` | Health / audit / diagnose |
|
||||
|
||||
Lifecycle rules (`zapier-lifecycle.mdc`): prefer native app MCP over Zapier when both exist; never call both.
|
||||
|
||||
---
|
||||
|
||||
## Reload
|
||||
|
||||
```bash
|
||||
# refresh live schemas (optional)
|
||||
# then:
|
||||
source ~/.mcp-env
|
||||
.venv/bin/python scripts/ingest-mcp-reference.py
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue