# Cursor tool surfaces in pi

pi-cursor-sdk runs Cursor models through the local `@cursor/sdk` agent runtime by default. A local pi session can expose **three related but different** tool namespaces. This page is the user-facing guide; maintainer replay details live in [Cursor native tool replay](./cursor-native-tool-replay.md).

## The three surfaces

**Version boundary:** the MCP-only opt-out (`PI_CURSOR_NATIVE_TOOLS`) and `/cursor-abort` require **0.5.4 or later**, including [#372](https://github.com/fitchmultz/pi-cursor-sdk/pull/372). Source checkouts preparing 0.5.4 remain candidates until exact npm/GitHub publication records exist; verify the installed artifact separately. Published **0.5.3 ignores the flag and has no such command**. Do not treat these examples as enforcement on an older installed package, or infer feature availability from a development version label alone.

| Surface | Who owns it | Callable by Cursor? | What pi shows |
| --- | --- | --- | --- |
| **Cursor SDK host tools** | Cursor local agent | Yes by default; disabled with `PI_CURSOR_NATIVE_TOOLS=0` | Native replay cards (`read`, `bash`, …) or neutral Cursor activity. Representative ToolType list: [SDK ToolType replay matrix](./cursor-native-tool-replay.md#sdk-tooltype-replay-matrix). |
| **Configured Cursor MCP** | Cursor settings / `~/.cursor/mcp.json` | Yes (when loaded) | Neutral **Cursor MCP** activity cards on replay |
| **Pi bridge (`pi__*`)** | pi-cursor-sdk loopback MCP | Yes, when exposed | Real pi tool names (`cursor_ask_question`, `cursor_activate_skill`, extension tools, …) |

Pi CLI tool toggles apply at the pi tool-registry boundary. `--no-tools`, `--tools`, and `--exclude-tools` can remove pi bridge exposure, but they do **not** disable Cursor SDK host tools or configured Cursor MCP servers.

**Not callable:** `cursor-replay-*` IDs in JSONL, pi history tool names used only for display, and transcript labels. Cursor must call exposed `pi__*` MCP names for bridged pi tools, not the pi card name.

## Opt-in MCP-only local turns

This section requires the 0.5.4+ implementation and publication/installation check described above; it is not available in published npm 0.5.3.

`PI_CURSOR_NATIVE_TOOLS=0` restricts **ordinary LOCAL** agents through the public SDK `AgentOptions.tools: ["mcp"]`. All other main-agent tools are omitted, including native `task`/subagents (whose own curated toolsets do not inherit a main-loop restriction). Unset, blank, unrecognized, or enabled values preserve the SDK's default toolset. The canonical boolean parser accepts `0`, `false`, `off`, `none`, `no`, and `disabled` as off, and `1`, `true`, `on`, `yes`, and `enabled` as on, case-insensitively with surrounding whitespace ignored.

To send file/shell work through Pi's normal execution and `tool_call` hook boundary instead of native Cursor tools:

```bash
# Requires 0.5.4+ containing #372; verify publication/installation (0.5.3 ignores the flag).
PI_CURSOR_NATIVE_TOOLS=0 PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 PI_CURSOR_SETTING_SOURCES=none pi --model cursor/grok-4.6
```

The builtin-exposure flag is still required; disabling native tools does **not** silently expose Pi builtins. Pi's active tool registry and hooks still decide which bridged tools are available or blocked. Disabling the bridge as well leaves no Pi tools callable, but does not by itself disable configured Cursor MCP.

**MCP-only is not Pi-only or a sandbox.** The SDK `mcp` capability group retains configured Cursor MCP and the Pi bridge. Ambient configured MCP remains unless setting sources are narrowed or disabled (`PI_CURSOR_SETTING_SOURCES=none`). Non-Pi MCP calls do not pass through Pi's `tool_call` hooks. A permitted Pi or MCP tool can itself run a shell, access files/network, or delegate arbitrary work; this is no OS/process security boundary.

**Native replay cannot enforce a pre-execution policy.** Native Cursor work runs before its recorded result is replayed into Pi. Pi `tool_call` hooks may block a bridged Pi call before its real `execute()`, but blocking or rewriting native replay cannot prevent or transform the original Cursor command. `PI_CURSOR_NATIVE_TOOL_DISPLAY=0`, `PI_CURSOR_REGISTER_NATIVE_TOOLS=0`, Pi tool toggles, and `PI_CURSOR_PI_TOOL_BRIDGE=0` are not native execution controls. Use the SDK tool-surface opt-out rather than fabricated pre-execution callbacks.

The policy is captured before drain/acquisition and forwarded identically to create and resume (SDK tool restrictions are not persisted by Cursor). Opt-out agents have a distinct pooled/durable compatibility identity; defaults retain historical identity bytes. Changing policy replaces the agent at acquisition instead of reusing/resuming one with the opposite policy. Before draining a pending run, the provider checks its captured policy under the drain lease and rejects an opposite-policy continuation without delivering Pi results back to that SDK run. Ordinary mismatch does not cancel the old run: restore the prior policy to finish it, or invoke `/cursor-abort` to release the exact pending local run owned by this session before retrying. This command sends no model turn. If its owned run has an active Cursor Pi turn, it also invokes that turn's public abort before release; it does not abort a non-Cursor Pi turn or release sibling sessions or Cloud agents. Pi's normal abort only signals an active Pi turn; once the mismatch error has fully settled, idle Pi abort cannot reach that older Cursor waiter. Explicit active provider abort still releases its exact scoped pending run even when the signal was aborted before preparation. No recovery path undoes already-executed work. Fresh text-only LOCAL compaction/tree summary agents continue using `tools: []`, independently of this flag. Cloud with explicit native tools disabled fails before SDK creation or lifecycle side effects rather than silently ignoring the control.

## Discoverability

- **MCP `listTools`** (and pi's MCP catalog when present) lists **MCP servers only** — for example `pi_tools` with `pi__cursor_ask_question`. It does **not** enumerate Cursor SDK host tools such as `Read` or `Shell`.
- **Bootstrap prompts** include a short **Cursor SDK tool boundary** block plus a compact **callable tool surfaces** manifest by default (disable manifest with `PI_CURSOR_TOOL_MANIFEST=0`). The manifest reminds the model that Cursor host/configured MCP tools are controlled by Cursor, while pi tool toggles only affect pi tools/bridge exposure; when bridge tools are exposed, it lists the current `pi__*` names. MCP `listTools` entries for bridged pi tools point back to the bootstrap prompt instead of repeating the full contract.
- **Incremental prompts** omit the full boundary block but keep a short tail guard (including an explicit shell `cd` hint); the session agent retains prior bootstrap context. They also omit invariant Pi system instructions; a changed system prompt forces bootstrap with the new section.
- **In-session debug:** `/cursor-tools` prints bridge/manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and current-registry exposure eligibility, including the builtin-exposure setting. It is not a live-run catalog or health check.

## Diagnosing advertised but unused bridge tools

Enable `PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1` before the turn. The existing scrubbed stderr records correlate observations by safe run ID:

| Record | What it establishes |
| --- | --- |
| `run_created` / `tools_exposed` | Run exposure and pi↔MCP name mapping, not connection |
| `mcp_initialized` | Server receipt of validated `notifications/initialized` |
| `mcp_tools_list` | Catalog-handler output after request validation, with `toolCount` |
| `request_queued` / `request_resolved` / `request_rejected` | Actual bridge call handling |

Initialization/catalog receipts are server observations, not Cursor-client identity, response delivery, model consumption or ongoing health. Absence does not explain why no request occurred. `/cursor-tools` reflects the registry now, not an earlier run's captured surface; exposure alone is not invocation proof. These diagnostics do not enumerate Cursor-configured MCP connections. Do not share logs where tool names are sensitive; endpoint credentials and raw args/results are excluded.

For an advertised-but-unused `pi__subagent`, first identify the active provider/version (especially with multiple Cursor providers installed), then compare the run's exposure, initialization/catalog and call records with persisted pi `toolCall`/`toolResult` rows. Bash-spawned Pi is not evidence of bridged `subagent` execution. The original Windows/two-provider report remains open in [#206](https://github.com/fitchmultz/pi-cursor-sdk/issues/206).

## Pi bridge vs Cursor native

Default behavior:

- Cursor host tools handle files, shell, grep, and edits.
- Prefer exposed `pi__*` tools for the capabilities described by their current schemas and prompt guidelines, including delegation or MCP work. Use Cursor-configured MCP or Cursor-native subagents only when no matching exposed Pi tool is available; do not assume a particular delegation tool name is registered.
- The pi bridge exposes **active pi tools** as `pi__*` MCP names when `PI_CURSOR_PI_TOOL_BRIDGE` is enabled (default on).
- Overlapping pi builtins (`read`, `bash`, `write`, `edit`, `grep`, `find`, `ls`) are **hidden** from the bridge unless `PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1`.

`pi-cursor-sdk` registers `cursor_ask_question` for Cursor models when the bridge is on and `PI_CURSOR_ASK_QUESTION=1`; Cursor sees `pi__cursor_ask_question`. The tool is sequential and emits `pi-cursor-sdk:ask-question:blocked` `{ active }` while awaiting UI input. It is off by default so Cursor proceeds with a stated assumption instead of prompting. Pending bridged calls use a local deadline capped by the effective MCP tool timeout; `PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS` can lower it. When pi has visible Agent Skills loaded, the extension also rewrites pi's skill catalog for Cursor and activates `cursor_activate_skill`; Cursor sees `pi__cursor_activate_skill` and should call it with a listed skill name before applying that skill. The activation result returns the full `SKILL.md`, the skill directory for relative paths, and a bounded list of bundled `scripts/`, `references/`, and `assets/` files without eagerly reading those resources.

```bash
# Enable Cursor's interactive question tool
PI_CURSOR_ASK_QUESTION=1 pi --model cursor/grok-4.6

# Disable pi bridge entirely
PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/grok-4.6

# Expose overlapping pi builtins through the bridge
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/grok-4.6

# Fail a stranded bridge call sooner than the effective MCP tool timeout
PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/grok-4.6

# Announce the bridge URL as localhost and listen on a port or range (for example for a Cursor team MCP allowlist such as http://localhost:800*/mcp).
PI_CURSOR_PI_TOOL_BRIDGE_HOST=localhost PI_CURSOR_PI_TOOL_BRIDGE_PORT=8000-8009 pi --model cursor/grok-4.6

# Disable bootstrap tool manifest
PI_CURSOR_TOOL_MANIFEST=0 pi --model cursor/grok-4.6
```

For `localhost`, the bridge owns both `127.0.0.1` and `::1` on the selected port before advertising its URL; a conflict on either family skips the port, and missing IPv6 fails closed. The default remains IPv4-only. Host/port settings are captured for the shared server lifetime, not changed under active runs; dispose all its runs before changing them.

## Runtime and transport policy

Current defaults:

- Local runtime is the default.
- The pi bridge uses loopback MCP and is the sole implemented Pi-tool transport for local Cursor agents.
- SDK `local.customTools` remains deferred and needs SDK cancellation/deadline support before it can replace the loopback MCP bridge; no transport config is exposed.
- Explicit cloud runtime selection requires first-use acknowledgement (`/cursor-runtime cloud`, `/cursor-runtime cloud --save-user`, `--cursor-cloud-ack`, or `PI_CURSOR_CLOUD_ACK=1`) plus preflight. Project config may save a cloud runtime default but not the acknowledgement. Cloud runs use fresh context by default and do **not** get local pi tools through loopback MCP or `local.customTools`; cloud Pi-tool access would require a separate secure remote bridge and a new product decision.
- Inline cloud MCP is not exposed in the initial cloud runtime because live probes showed first-run/replacement/resume behavior was not deterministic enough.

## Cursor settings vs pi toggles

Disabling or removing an MCP server **only in pi** does not remove Cursor ambient MCP loaded from Cursor config.

| Control | Effect |
| --- | --- |
| `pi --no-tools` | Disables pi built-in/extension/custom tools and therefore removes pi bridge exposure; Cursor SDK host tools still remain callable. |
| `pi --tools ...` / `pi --exclude-tools ...` | Narrows pi's active tool registry and therefore the pi bridge snapshot; Cursor SDK host tools and configured Cursor MCP are unchanged. |
| `PI_CURSOR_NATIVE_TOOLS=0` | Restricts ordinary LOCAL main-agent tools to MCP only, including disabling native task/subagents; Cloud fails closed. Default unchanged. |
| `PI_CURSOR_SETTING_SOURCES=all` (default) | Loads user/project Cursor MCP, plugins, rules (`~/.cursor/mcp.json`, etc.) |
| `PI_CURSOR_SETTING_SOURCES=none` | Disables ambient Cursor setting sources for local agents |
| `PI_CURSOR_SETTING_SOURCES=project,plugins` | Narrows which layers load |
| Empty or edited `~/.cursor/mcp.json` | Changes which user MCP servers Cursor connects to |

To reproduce a **minimal** surface (pi-cursor-sdk + Cursor host only), use extension-only install, empty user MCP config, and `PI_CURSOR_SETTING_SOURCES=none` when you do not need Cursor rules/MCP from disk.

## JSONL ID patterns (debugging)

| ID prefix | Meaning |
| --- | --- |
| `cursor-replay-*` | Display-only replay of Cursor SDK activity |
| `cursor-pi-bridge-run-*` (run) / `cursor-pi-bridge-<32 hex>-t<counter>` (tool) | Live pi execution via bridge |

Example mistake: treating `cursor-replay-…` as a tool to invoke. Replay never re-runs work.

## Related docs

- [Reference — Cursor provider tool contract](reference.md#cursor-provider-tool-contract)
- [Cursor native tool replay](./cursor-native-tool-replay.md)
- [Cursor model UX spec](./cursor-model-ux-spec.md)
