Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/scripts/lint_skill_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"field-condition",
"graphql",
"introspect",
"kb",
"label",
"member",
"org",
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Open-source toolkit for **Pipefy** developers: a Model Context Protocol (MCP) se

| Component | Package / path | Purpose |
|-----------|----------------|---------|
| **MCP server** | `pipefy-mcp-server` | Exposes **162** tools to MCP clients (Cursor, Claude Desktop, Claude Code, and others). |
| **MCP server** | `pipefy-mcp-server` | Exposes **168** tools to MCP clients (Cursor, Claude Desktop, Claude Code, and others). |
| **CLI** | `pipefy-cli` | Terminal commands aligned with MCP capabilities; see [`docs/parity.md`](docs/parity.md). |
| **SDK** | `pipefy` | Vendor GraphQL client, services, and models shared by MCP and CLI. |
| **Skills** | [`skills/`](skills/) | Markdown playbooks (Anthropic Skills format) for common Pipefy workflows. |
Expand Down Expand Up @@ -141,7 +141,7 @@ Deprecation and semver (post-1.0): [`docs/DEPRECATION.md`](docs/DEPRECATION.md).

## MCP server

The server registers **162 tools** across twelve domains. Canonical names: `PIPEFY_TOOL_NAMES` in [`packages/mcp/src/pipefy_mcp/tools/registry.py`](packages/mcp/src/pipefy_mcp/tools/registry.py).
The server registers **168 tools** across thirteen domains. Canonical names: `PIPEFY_TOOL_NAMES` in [`packages/mcp/src/pipefy_mcp/tools/registry.py`](packages/mcp/src/pipefy_mcp/tools/registry.py).

Tool descriptions and `Args:` blocks come from Python docstrings (what MCP clients show to models). Per-area reference docs cover parameters, edge cases, and cross-cutting behavior.

Expand All @@ -155,6 +155,7 @@ Tool descriptions and `Args:` blocks come from Python docstrings (what MCP clien
| **Reports** | 17 | Pipe and organization reports, async exports. | [docs](docs/mcp/tools/reports.md) |
| **Automations & AI** | 23 | Automations, AI automations, AI agents, validators. | [docs](docs/mcp/tools/automations-and-ai.md) |
| **LLM providers** | 5 | Discovery reads for the organization's LLM providers (custom + Pipefy-managed), vendor model lists, owner defaults, dependencies, and a read-access probe. | [docs](docs/mcp/tools/llm-providers.md) |
| **Knowledge bases** | 6 | Pipe-scoped AI knowledge bases: list all items, plain text CRUD, and a read-access probe. Attach sources to agents/behaviors via `dataSourceIds`. | [docs](docs/mcp/tools/knowledge-bases.md) |
| **iPaaS** | 4 | Lazy discovery, invocation, and app-connection setup for a pipe's iPaaS (Advanced Automations) workspace (`get_ipaas_tools`, `call_ipaas_tool`, plus the connection meta-tools). | [docs](docs/mcp/tools/ipaas.md) |
| **Observability** | 11 | Logs, usage, credits, execution metrics, job exports. | [docs](docs/mcp/tools/observability.md) |
| **Members, email & webhooks** | 11 | Membership, inbox email, webhooks. | [docs](docs/mcp/tools/members-email-webhooks.md) |
Expand Down
1 change: 1 addition & 0 deletions docs/mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Material in this tree describes **`pipefy-mcp-server`**: the MCP process, tool b
| [`tools/reports.md`](tools/reports.md) | Pipe and organization reports, async exports |
| [`tools/automations-and-ai.md`](tools/automations-and-ai.md) | Traditional automations, AI automations, AI agents, validators |
| [`tools/llm-providers.md`](tools/llm-providers.md) | LLM provider discovery: custom + system providers, vendor models, defaults, dependencies, access probe |
| [`tools/knowledge-bases.md`](tools/knowledge-bases.md) | Pipe-scoped AI knowledge bases: list, plain text CRUD, read-access probe |
| [`tools/observability.md`](tools/observability.md) | Logs, usage, credits, execution metrics, job exports |
| [`tools/members-email-webhooks.md`](tools/members-email-webhooks.md) | Membership, inbox email, webhooks |
| [`tools/organization.md`](tools/organization.md) | Organization metadata |
Expand Down
46 changes: 46 additions & 0 deletions docs/mcp/tools/knowledge-bases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Knowledge bases

Pipe-scoped AI knowledge bases: list every item on a pipe, full CRUD for plain-text sources, and a read-access probe. **6 tools.**

Knowledge bases are the data sources an AI agent draws on. Each item's `id` is what you attach to an agent or behavior via `dataSourceIds` (see [Automations & AI](automations-and-ai.md)): use `get_ai_knowledge_bases` to discover the IDs, then `validate_ai_agent_behaviors(data_source_ids=[...])` to check membership before writing the agent.

---

| Tool | Read-only | Role |
|------|-----------|------|
| `get_ai_knowledge_bases` | Yes | Lists every knowledge base item on a pipe (plain texts, documents, data lookups) as one flat list — no pagination. Each item carries `id`, `type` (e.g. `knowledge_base_plain_texts`), `name`, `description`, `updatedAt`. |
| `get_ai_knowledge_base_plain_text` | Yes | Fetches one plain text by `id`, including its full `content`. |
| `create_ai_knowledge_base_plain_text` | No | Creates a plain text. `name`, `content` (1-3500 chars), and `description` (1-900 chars) are all required. |
| `update_ai_knowledge_base_plain_text` | No | Partial update by `plain_text_id`: pass any of `name` / `content` / `description` (at least one); omitted fields keep their stored value. |
| `delete_ai_knowledge_base_plain_text` | No | Deletes a plain text permanently. Two-step: preview with `confirm=false` (default), execute with `confirm=true`. |
| `validate_knowledge_base_access` | Yes | Probes whether the current credential can read a pipe's knowledge bases, classifying failures into structured problems instead of opaque errors. |

## Identifiers: pipe UUID, not numeric ID

Every knowledge base operation is scoped by the pipe **UUID** (`pipe_uuid`), not the numeric pipe ID — this follows the Pipefy GraphQL API. `get_pipe` returns the `uuid` field; `get_ai_knowledge_bases` returns each item's `id` (a data-source UUID) for the plain-text-by-id operations and for `dataSourceIds`.

## Plain-text limits (enforced client-side)

Limits fail fast before the network call, so an over-limit value is rejected with an actionable message rather than a backend 422:

- `content`: required, 1-3500 characters.
- `description`: required, 1-900 characters. The GraphQL schema marks `description` optional, but the backend rejects a blank one, so the toolkit requires it on create.
- `name`: required, non-blank.

On update, only the fields you pass are validated and sent; the others keep their stored values.

## Probe semantics and the write gate

- A green `validate_knowledge_base_access` proves **read access only** (`read_ai_agents` on the pipe) — never the `manage_ai_agents` entitlement that plain-text create / update / delete require.
- An **empty knowledge base list** is a valid green result (`knowledge_base_count: 0`), not a failure.
- The **CLI gates writes** on the probe: `pipefy kb plain-text create` / `update` run the read-access probe first and fail with the classified problem if it is denied, before attempting the mutation.
- The **MCP tools stay explicit-validate-first**: create / update do not auto-probe. Call `validate_knowledge_base_access` yourself before writing.
- **Deletes require confirmation**: the MCP tool needs `confirm=true`; the CLI needs `--yes` (or an interactive prompt).

## Attaching a source to an agent

`validate_ai_agent_behaviors` accepts an optional `data_source_ids` (agent-level). It is unioned with each behavior's `actionParams.aiBehaviorParams.dataSourceIds` and checked against the pipe's knowledge bases: IDs not present on the pipe produce **warnings only** (`valid` stays true). If the knowledge base list cannot be read, a single warning is added and the membership check is skipped — a read failure is never reported as a broken reference.

## Error classification

Failures on this surface are classified by the shared SDK-level module (`pipefy_sdk.graphql_problem`) into structured problems — `permission_denied`, `not_found`, `invalid_arguments`, `feature_not_enabled`, or `runtime` — carried on `error.details.kind` alongside the GraphQL `extensions.code` and `correlation_id`. The same classifier backs the CLI (`pipefy kb ...`), so both surfaces report the same problem kinds.
10 changes: 8 additions & 2 deletions docs/parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This matrix is the source of truth for **MCP tool ↔ `pipefy` CLI** coverage. Update it whenever MCP tools or CLI commands are added, renamed, or removed.

**Registry source:** `PIPEFY_TOOL_NAMES` in `packages/mcp/src/pipefy_mcp/tools/registry.py` (must stay in sync with this table: **162** tools).
**Registry source:** `PIPEFY_TOOL_NAMES` in `packages/mcp/src/pipefy_mcp/tools/registry.py` (must stay in sync with this table: **168** tools).

**Later CLI coverage:** areas such as attachments, field conditions, email, audit export, traditional automations, exports/usage, introspection, and raw GraphQL appear as **shipped** below when the matching Typer commands exist in `packages/cli`.

Expand Down Expand Up @@ -30,6 +30,7 @@ For **database records**, `find_records` result nodes may use **`fields`** while
| `clone_pipe` | `pipefy pipe clone` | shipped | optional `--org`. |
| `create_ai_agent` | `pipefy agent create` | shipped | AI Agents domain; post-v0.1 CLI unless explicitly rescoped. |
| `create_ai_automation` | `pipefy ai-automation create` | shipped | AI Automations domain; post-v0.1 CLI unless explicitly rescoped. |
| `create_ai_knowledge_base_plain_text` | `pipefy kb plain-text create` | shipped | Knowledge bases; pipe-scoped (`--pipe-uuid`, `--name`, `--content` <=3500, `--description` <=900, all required). CLI gates on the read-access probe; limits fail fast client-side. |
| `create_automation` | `pipefy automation create` | shipped | (`--pipe`, `--name`, `--trigger-id`, `--action-id`, optional `--extra` JSON). |
| `create_card` | `pipefy card create` | shipped | (`--fields` JSON, optional `--title`, optional `--phase-id` for `CreateCardInput.phase_id`). |
| `create_card_relation` | `pipefy relation card create` | shipped | — |
Expand All @@ -53,6 +54,7 @@ For **database records**, `find_records` result nodes may use **`fields`** while
| `create_webhook` | `pipefy webhook create` | shipped | — |
| `delete_ai_agent` | `pipefy agent delete` | shipped | AI Agents domain. |
| `delete_ai_automation` | `pipefy ai-automation delete` | shipped | AI Automations domain. |
| `delete_ai_knowledge_base_plain_text` | `pipefy kb plain-text delete` | shipped | Knowledge bases; pipe-scoped (`--id`, `--pipe-uuid`). MCP requires `confirm=true`; CLI requires `--yes` (or interactive prompt). |
| `delete_automation` | `pipefy automation delete` | shipped | destructive: `--yes` or confirm. |
| `delete_card` | `pipefy card delete` | shipped | destructive: `--yes` or interactive confirm. |
| `delete_card_relation` | `pipefy relation card delete` | shipped | requires OAuth (internal API); `--yes`. |
Expand Down Expand Up @@ -91,6 +93,8 @@ For **database records**, `find_records` result nodes may use **`fields`** while
| `get_ai_automation` | `pipefy ai-automation get` | shipped | AI Automations domain. |
| `get_ai_automations` | `pipefy ai-automation list` | shipped | AI Automations domain. |
| `get_ai_credit_usage` | `pipefy usage credits` | shipped | (`--organization`, `--period`). |
| `get_ai_knowledge_base_plain_text` | `pipefy kb plain-text get` | shipped | Knowledge bases; pipe-scoped plain text with content (`--id`, `--pipe-uuid`). |
| `get_ai_knowledge_bases` | `pipefy kb list` | shipped | Knowledge bases; all items on a pipe (plain text, documents, data lookups) with `id` for `dataSourceIds` (`--pipe-uuid`; no pagination). |
| `get_automation` | `pipefy automation get` | shipped | — |
| `get_automation_actions` | `pipefy automation actions list` | shipped | (`--pipe`). |
| `get_automation_event_attributes` | `pipefy automation event-attributes` | shipped | Official ``field_map`` event-attribute token catalog. |
Expand Down Expand Up @@ -161,6 +165,7 @@ For **database records**, `find_records` result nodes may use **`fields`** while
| `unpublish_sub_portal` | `pipefy portal sub-portal unpublish` | shipped | internal_api `updateSubPortalElement(subPortalUuid: null)`; sets `subPortals[].published` to false. |
| `update_ai_agent` | `pipefy agent update` | shipped | AI Agents domain. |
| `update_ai_automation` | `pipefy ai-automation update` | shipped | AI Automations domain. |
| `update_ai_knowledge_base_plain_text` | `pipefy kb plain-text update` | shipped | Knowledge bases; partial update (`--id`, `--pipe-uuid`, optional `--name`/`--content`/`--description`, at least one). CLI gates on the read-access probe; limits fail fast client-side. |
| `update_automation` | `pipefy automation update` | shipped | (`--extra` JSON). |
| `update_card` | `pipefy card update` | shipped | (`--field-updates` JSON, optional title/labels/assignees/due-date). |
| `update_card_field` | `pipefy card update` | shipped | Use `--field-updates` JSON array (). |
Expand All @@ -186,6 +191,7 @@ For **database records**, `find_records` result nodes may use **`fields`** while
| `upload_attachment_to_table_record` | `pipefy attachment upload --record` | shipped | (same supporting flags as card). |
| `validate_ai_agent_behaviors` | `pipefy agent validate-behaviors` | shipped | AI Agents validation tooling. |
| `validate_ai_automation_prompt` | `pipefy ai-automation validate-prompt` | shipped | AI Automations validation tooling. |
| `validate_knowledge_base_access` | `pipefy kb validate-access` | shipped | Knowledge base read-access probe (pipe-scoped, `--pipe-uuid`); green proves read access only (`read_ai_agents`), never write entitlement. |
| `validate_llm_provider_access` | `pipefy ai-provider validate-access` | shipped | LLM provider read-access probe; green proves read access only, never write entitlement. |

## Row count check
Expand All @@ -199,6 +205,6 @@ for n in m.body:
print(len(v.args[0].elts))"
```

Expect **162** tool names in `PIPEFY_TOOL_NAMES` and **162** data rows in the parity table (excluding the header rows).
Expect **168** tool names in `PIPEFY_TOOL_NAMES` and **168** data rows in the parity table (excluding the header rows).

When adding or removing an MCP tool, update **this file** and `PIPEFY_TOOL_NAMES` in the same change set.
10 changes: 10 additions & 0 deletions packages/cli/src/pipefy_cli/commands/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,15 @@ def agent_validate_behaviors(
"values as problems; --no-strict reports them as warnings only."
),
),
data_source_id: list[str] = typer.Option(
[],
"--data-source-id",
help=(
"Agent-level knowledge base ID to attach (repeatable). Unioned with "
"behavior-level dataSourceIds and checked against the pipe's knowledge "
"bases; unknown IDs are warnings only."
),
),
json_out: bool = typer.Option(False, "--json", "-j"),
) -> None:
"""Dry-run behavior validation (``validate_ai_agent_behaviors``)."""
Expand All @@ -353,6 +362,7 @@ async def factory(client: PipefyClient):
pipe.strip(),
behavior_list,
strict_unknown_action_types=strict_unknown,
data_source_ids=data_source_id or None,
)

run_cli_command(ctx, json_out, factory)
Loading
Loading