# Palm MCP Agent Guide

**Purpose**: How an AI agent should interact with Palm efficiently through MCP tools and resources.

**Version**: 0.26.0 · **Resource**: `palm://agent/guide` · **Full inventory**: `docs/MCP.md` · **Project context**: `docs/llms.txt`

**Audience**: Grok, Cursor, Claude, and other agents using `call_connected_tool` / `CallMcpTool` + Palm MCP.

---

## 1. Core Mental Model

Palm = **stateful, path-driven workflow engine** with strong interactive wizard support.

| Concept | Meaning |
|---------|---------|
| **Flows** | Reusable wizards/pipelines (`todo-builder`, `approval`, `onboard`, …) |
| **Sessions / Instances** | Running executions with durable state (`session_id` ≡ `instance_id`) |
| **Assist** | Main conversational entry — `palm_assist` |
| **Paths & Aliases** | Target specific actions (`path=["flows",…]`, `alias="operator-entry/start"`) |
| **MCP Resources** (`palm://…`) | Read-only catalogs, guides, instance trees |
| **MCP Tools** | Write/act — create sessions, send input, resume, cancel |
| **Design (0.25+)** | Safe catalog writes — `palm_design_*` propose → impact → commit |

**Golden rules**:
- **Run a flow** → start with `palm_assist()` unless you have `session_id` or explicit `flow_id`.
- **Create or change a flow definition** → use `palm_design_*` (see §15), not repo files or `palm_definitions_*` writes.

**Operator loop**: definitions → create session → inspect → input → wait on children → resume.

---

## 2. Setup (local default)

```bash
uv sync --extra mcp
PALM_MCP_IN_PROCESS=1 uv run --extra mcp palm-mcp   # stdio → services, no REST server
```

| Variable | Default (this repo) | Purpose |
|----------|---------------------|---------|
| `PALM_MCP_IN_PROCESS` | `1` in `.grok/config.toml` | In-process services (no HTTP) |
| `PALM_LLMS_TXT` | `docs/mcp.txt` | Content for `palm://agent/guide` |
| `PALM_BASE_URL` | `http://127.0.0.1:8080` | REST target when in-process is off |

Grok: `.grok/config.toml` — in-process + `docs/mcp.txt`. Remote proxy: `PALM_MCP_IN_PROCESS=0` + `just palm-server`.

---

## 3. Recommended Starting Pattern

```text
palm_assist()                                    → operator-entry (0.21.7 default)
palm_assist(alias="operator-entry/start")        → explicit operator entry
palm_assist(params={"session_id": id, "value": "yes"})  → continue assist session
```

Then follow choices (Todo Builder, Compositional Parent, Inspect Only) and hand off.

**View modes (0.20–0.21)**:
- **Assistant** — `question`, `choices`, `hint`, `actions` (default on assist paths)
- **Powertool** — `operator_hint`, `step_kind` (default on `palm_flows_*`)
- Opt-in assistant on flows: `palm_flows_session(session_id, format="assistant")`

---

## 4. Agent Rules (memorize)

1. **Session-first** — use `session_id`; `job_id` only when no session handle (`palm_system_inspect_job`).
2. **Plain input** — `input="yes"`, choice slugs, text. No JSON blobs for wizard answers.
3. **Re-inspect after every step** — `palm_flows_session(session_id, format="assistant")` or `palm_assist(params={session_id, flow_id, value})`.
4. **Resources = read, tools = write** — `palm://definitions/*` via FetchMcpResource; invoke definitions via `palm_providers_invoke` (never pass `palm://` to invoke).
5. **Collection steps** — `palm_wizard_collection_action` or `palm_assist(params={session_id, flow_id, collection_action, value})`; **0.21.11+** `params.edit={item_index, …}`; fuzzy tokens `add`/`edit`/`done`/`continue`.
6. **Interactive entry** — `palm_assist` / `palm_flows_create_session`. Never `palm_processes_submit` on processes with `entry_flow`.
7. **Compositional wizards** — check `waiting_for_child`, read `palm://instances/{id}/tree`, call `palm_flows_session_resume_child_wait`.
8. **Prefer `actions` block** (0.21.4) — structured `path`/`alias` over parsing `hint`.
9. **Catalog writes** — use `palm_design_*` (not `palm_definitions_*` create/update) unless docs say otherwise.
10. **Flow names are slugs** — `foo-bar` not `foo bar`; hyphens, lowercase, no spaces.
11. **Choice steps** — reply with choice slug (`beta`) or menu number (`2`); never JSON answer blobs.
12. **After engine upgrade** — restart `palm-mcp` so in-process CQRS wiring reloads (impact/commit otherwise fail).

---

## 5. Common Flows

| Flow | Use case | Start |
|------|----------|-------|
| `todo-builder` | Interactive todo lists | operator-entry or `flows/todo-builder/create` |
| `approval` | Spend / request approvals | `flows/approval/create` |
| `onboard` / `schema-onboard` | Onboarding | `flows/onboard/create` |
| `resource-customer-wizard` | Resource loading | Needs pre-registered resources |
| `compositional-parent` | Nested workflows | Via operator-entry |

Discovery: `palm_flows_list()` · Catalog: `palm://definitions/flows` · Routes: `palm://assist/routes`

---

## 6. Session Management (critical)

Always track: `session_id`, `job_id`, current `step`.

| Need | Tool |
|------|------|
| Inspect session | `palm_flows_session(session_id, format="assistant")` |
| Send answer | `palm_flows_session_input(session_id, input="…")` |
| Unified drive | `palm_assist(params={session_id, flow_id, value})` |
| Stack summary | `palm_flows_compose_status(session_id)` |
| Stuck resource step | `palm_flows_session_resume(session_id)` |
| Child wait | `palm_flows_session_resume_child_wait(session_id)` |
| Multi-step burst | `palm_flows_session_drive(session_id, inputs=[…])` |

**Anti-patterns**: sending multiple inputs without re-inspecting; guessing current step; forgetting `session_id` on continuation.

---

## 7. Tool Description Pattern (for MCP contributors)

When adding or updating Palm MCP tools, use this structure so weak LLMs discover and use them immediately:

```markdown
To use this tool: call_connected_tool(tool_name="palm___<name>", arguments={...}).

[One-sentence purpose]

[When to use + alternatives]

Examples::

    palm_assist()
    palm_assist(alias="operator-entry/start")
    palm_assist(params={"session_id": "inst-xxx", "value": "yes"})

[Optional: path vs alias vs params notes]
```

Key rules:
- Start with the exact `call_connected_tool` instruction (Grok) or equivalent MCP invoke hint.
- Include 3–4 realistic examples.
- Document `path` vs `alias` vs `params`.
- Add "use X instead of Y" when similar tools exist.

Implementation helper: `palm.runtimes.mcp.descriptions.tool_description()`.  
Portable skill: `palm://agent/skill` + `palm://agent/references/*` (on-disk: `docs/skills/palm/`).

---

## 8. Tool Cheat Sheet

| Need | Tool / resource |
|------|-----------------|
| Agent guide (this file) | `palm://agent/guide` |
| Agent skill | `palm://agent/skill` |
| Skill references | `palm://agent/references/agent-guide`, `…/design-flows`, `…/session-management`, `…/common-flows`, `…/mcp-patterns` |
| Create/improve flows | `palm://agent/references/design-flows` · `palm_design_*` |
| Design propose | `palm_design_propose_flow` |
| Design publish | `palm_design_impact` → `palm_design_commit` |
| Project architecture | `docs/llms.txt` |
| Flow catalog | `palm://definitions/flows` |
| Start wizard | `palm_assist()` or `palm_flows_create_session` |
| Command catalog | `palm://assist/routes` |
| Current step | `palm_flows_session` (powertool or `format="assistant"`) |
| Collection UI | `palm_wizard_collection_action` or assist `collection_action` |
| Health | `palm_system_doctor` |
| **Create/improve flow** | `palm_design_propose_flow` → `palm_design_impact` → `palm_design_commit` |
| Design playbook (weak LLMs) | `palm://agent/references/design-flows` |
| Invoke resource definition | `palm_providers_invoke` |
| Instance tree | `palm://instances/{id}/tree` |

**Prompts**: `debug-wizard-block`, `drive-wizard-to-step`, `explain-compositional-stack`, `operator-handoff`

---

## 9. Known Friction & Fixes

| Friction | Solution |
|----------|----------|
| Resource steps failing | Register resources first or use flows without resource deps |
| Losing session context | Re-inspect with `format=assistant` after every step |
| Collection menus | Be explicit: "add" → title → due date → priority |
| Which flow to start | `palm_assist()` or `palm_flows_list` |
| Operator-entry handoff | Send "yes" at summary → handoff alias or create flow directly |
| Create a new flow | §15 — `palm_design_*` loop; see `palm://agent/references/design-flows` |
| `AnalyzeDefinitionImpactQuery` error | Restart `palm-mcp` after upgrading Palm |
| User said "foo bar" flow name | Use slug `foo-bar` in `body.name` |
| Summary step | `confirm_step: true` — only `yes`/`no` when user explicitly confirms |

---

## 10. Philosophy

Palm is ergonomic when treated as a **guided state machine**, not a REST CRUD API.

1. Start with **operator-entry** (`palm_assist()`)
2. Let the user choose via natural language
3. Follow the session step-by-step — always re-read state
4. Use `format=assistant` for human-facing turns

---

## 11. Inspect vs drive (critical — 0.22.1+)

When the user says **inspect**, **look**, **status**, or **what's running**:

1. Use **read tools only**: `palm_flows_session`, `palm_flows_list`, `palm_system_list_waiting`, `palm://definitions/*`.
2. Check **`mutation.mutations_allowed`** in every inspect response — if `false`, never send `value`/`input`.
3. At **`mutation.confirm_step`**, do **not** send `yes`/`no` unless the user explicitly said yes or no.
4. **"Inspect" ≠ operator-entry menu item 3** unless the user picks that choice by name or number — prefer `operator-entry/inspect` or `palm_flows_list` for read-only catalog (0.23.1+).

Every assistant/powertool inspect response includes a `mutation` block:

```json
{
  "mutation": {
    "mutations_allowed": true,
    "requires_user_input": true,
    "step_slug": "intent",
    "input_token": "abc123.1710000000.digest",
    "confirm_step": true,
    "agent_hint": "Confirm step: do not send yes/no unless..."
  }
}
```

Violating this completes wizards irreversibly. See `archive/conversation_export.xml` (anti-pattern: unsolicited `yes` at summary).

---

## 12. `input_token` strict mode (0.23.0+)

When `PALM_MCP_REQUIRE_INPUT_TOKEN=1`, every mutation (`palm_assist` value, `palm_flows_session_input`) must include `input_token` from the last inspect `mutation` block.

| Env | Default | Purpose |
|-----|---------|---------|
| `PALM_MUTATION_SECRET` | dev fallback | HMAC secret for token signing |
| `PALM_MCP_REQUIRE_INPUT_TOKEN` | `0` | `1` = reject writes without valid token |

**Drive loop with strict mode:**

1. `palm_flows_session(session_id=…, format="assistant")` → copy `mutation.input_token`
2. `palm_assist(params={session_id, value, input_token})` → pass token with every write
3. Re-inspect after each input — tokens are step-bound and rotate on inspect

Missing or stale tokens return `mutation_rejected` (HTTP 400 / MCP tool error). Explorer and CLI stay unchanged when the flag is off.

---

## 13. Inspect-only catalog mode (0.23.1+)

Operator-entry choice **`inspect-only`** (menu item 3) enters a **non-terminal catalog step** — session stays `waiting` until the user says **exit**.

| Read alias | Purpose |
|------------|---------|
| `operator-entry/inspect` | Standalone read-only catalog (no session write) |
| `assist/catalog/flows` | List runnable flows |

At catalog step, `operator_mode: inspect` is set on the instance. Use read actions (list flows, list waiting, inspect session) — not summary confirm. Handoff is `kind: none` until exit.

---

## 14. Definition revision migration (0.24+)

Catalog flows are **append-only revisions**. Running instances pin `flow_revision` + snapshot — they do not auto-upgrade when the catalog changes.

| Step | Tool / REST |
|------|-------------|
| Impact | `palm_definitions_analyze_impact(flow_id, target_revision=…)` · `GET /v1/api/definitions/flows/{id}/impact?revision=N` |
| Dry-run | `palm_definitions_migrate_instance(instance_id, target_revision, dry_run=True)` |
| Apply | `palm_definitions_migrate_instance(instance_id, target_revision)` · `POST …/instances/{id}/migrate` |

**Operator loop:** impact → dry-run → apply. Example wizard: `migrate-instance-demo` (see `examples/README.md`).

`GET flow` accepts `?revision=N`. `update_flow` publishes `latest+1` (no overwrite). See [MIGRATION-0.24.md](../MIGRATION-0.24.md).

---

## 15. Create or improve a flow (Design Service — weak-LLM recipe)

**When the user wants a new flow or changes to an existing one** — do **not** edit Python files. Use MCP only.

### New flow — four tools, fixed order

```text
palm_design_propose_flow(body={name, pattern, options})
palm_design_impact(proposal_id="prop-...")
palm_design_commit(proposal_id="prop-...")
palm_flows_describe(flow_id="my-flow")    # confirm revision in catalog
```

Save `proposal_id` from propose. If propose returns `"valid": false`, read `blockers` and fix the body before impact.

### Update existing flow

Add `base_flow_id="existing-id"` to propose. Same impact → commit sequence. Revision number increments.

### Minimal wizard body

```json
{
  "name": "my-flow",
  "pattern": "wizard",
  "options": {
    "include_summary": true,
    "steps": [
      {"slug": "step1", "title": "Step one", "prompt": "Your answer?"}
    ]
  }
}
```

- **`name`** must be a slug (`foo-bar`, not `foo bar`).
- Each step needs **`slug`**, **`title`**, **`prompt`**.
- **`field_type": "choice"`** requires **`choices": ["a","b"]`**.
- **`include_summary": true`** adds a confirm step before finish — user must say yes (do not auto-confirm unless they asked).

### Run the flow (separate from design)

```text
palm_flows_create_session(flow_id="my-flow")
palm_flows_session(session_id, flow_id="my-flow", format="assistant")
palm_flows_session_input(session_id, flow_id="my-flow", input="plain answer")
```

Repeat session → input until `status` is `complete`. Re-inspect after **every** input.

### Choice and summary steps

| Step type | What to send |
|-----------|----------------|
| Text | `input="any plain string"` |
| Choice | `input="beta"` or `input="2"` (from assistant `choices`) |
| Summary | `input="yes"` only when user explicitly confirms |

### Strict commit / input tokens

- Design commit: pass `commit_token` from validate/impact `mutation` when `PALM_MCP_REQUIRE_INPUT_TOKEN=1`.
- Session input: pass `input_token` from last `palm_flows_session` `mutation` block.

### Full walkthrough

See **`palm://agent/references/design-flows`** (worked `foo-bar` example: create → improve → run).

### Do not use for catalog writes

- `palm_definitions_*` direct create/update — integrator path only; agents should prefer `palm_design_*`.