@schultzp2020/pi-cursor

Pi extension for Cursor subscription models via local OpenAI-compatible proxy

Packages

Package details

extension

Install @schultzp2020/pi-cursor from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@schultzp2020/pi-cursor
Package
@schultzp2020/pi-cursor
Version
0.5.0
Published
May 28, 2026
Downloads
501/mo · 62/wk
Author
schultzp2020
License
MIT
Types
extension
Size
446.7 KB
Dependencies
1 dependency · 0 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-cursor

A Pi extension that gives you access to all your Cursor subscription models (Composer, Claude, GPT, Gemini, etc.) inside Pi via a local OpenAI-compatible proxy.

Features

  • Dynamic model discovery — no hard-coded model list. Models are fetched from Cursor's API on startup and cached for fast subsequent launches.
  • Full tool support — native Cursor tools (read, write, shell, grep) are redirected to Pi equivalents only when Pi enabled the mapped tool for the session. MCP tools pass through only when registered in the session tool set, and Cursor-only web/exa queries are rejected.
  • Thinking/reasoningthinkingDelta events map to reasoning_content in SSE, with XML tag filtering as a safety net.
  • Multi-session — multiple Pi sessions share one proxy process via HTTP internal API and a port file at ~/.pi/agent/cursor-proxy.json.
  • Conversation persistence — checkpoints and blob stores are persisted to disk, preventing "blob not found" crashes on long sessions.

Requirements

Installation

pi install npm:@schultzp2020/pi-cursor

Usage

1. Authenticate

Inside Pi, run:

/login

Select Cursor from the provider dropdown, then your browser opens to Cursor's OAuth page. After you log in, Pi polls until authentication completes. Tokens are stored and refreshed automatically.

Windows note: A console window may appear briefly when the browser opens. This is harmless — you can close it safely.

2. Select a model

/model

Pick any Cursor model from the list. Effort-level variants are collapsed — e.g. gpt-5.4-low, gpt-5.4-medium, gpt-5.4-high become a single gpt-5.4 entry, with Pi's reasoning-effort selector controlling the variant sent to Cursor. Models with larger context windows appear as separate entries (e.g. GPT-5.4 [1M]).

3. Chat

Use Pi normally. The extension transparently proxies requests to Cursor's API:

Read package.json and summarize the dependencies.

Tool calls, multi-turn conversations, and reasoning all work.

Settings

Run /cursor in Pi to open the settings menu. Each setting shows its current value and an [ENV] tag when overridden by an environment variable (read-only in that case).

Setting Values Default Env Override
Max Mode on, off off PI_CURSOR_MAX_MODE
Fast on, off off PI_CURSOR_FAST
Thinking on, off on PI_CURSOR_THINKING
Native Tools Mode reject, redirect, native reject PI_CURSOR_NATIVE_TOOLS_MODE
Max Retries 0, 1, 2, 3, 5 2 PI_CURSOR_MAX_RETRIES

Settings persist to ~/.pi/agent/cursor-config.json.

Context window tiers

Models that support multiple context windows are registered as separate entries in the model picker. The default tier has no suffix; larger tiers show the size:

GPT-5.4              ← 272K (default)
GPT-5.4 [1M]         ← 1M context
Opus 4.6             ← 200K (default)
Opus 4.6 [1M]        ← 1M context

Context tiers are discovered dynamically from Cursor's API — the values shown are always the model's actual limits, not hardcoded.

Native Tools Mode

Controls how Cursor's built-in tool calls (read, write, shell, grep, ls, delete, fetch) are handled:

Mode Behavior
reject (default) All native Cursor tool calls are rejected. Only Pi's MCP tools succeed.
redirect Overlapping native tools are transparently redirected through Pi equivalents.
native Overlapping tools execute locally within the proxy, sandboxed to the nearest git root.

Configure via the /cursor command or environment variable:

export PI_CURSOR_NATIVE_TOOLS_MODE=native  # or reject, redirect

Or set it in ~/.pi/agent/cursor-config.json:

{
  "nativeToolsMode": "native"
}

In native mode, filesystem operations are sandboxed to the Allowed Root — the nearest git root of the session's working directory. Paths outside this boundary are rejected.

Debug Logging

Enable structured debug logging to diagnose proxy behavior:

export PI_CURSOR_PROVIDER_DEBUG=1

This writes JSONL entries to ~/.pi/agent/cursor-debug.jsonl. Override the path:

export PI_CURSOR_PROVIDER_EXTENSION_DEBUG_FILE=/path/to/debug.jsonl

View a human-readable timeline:

node scripts/debug-log-timeline.mjs ~/.pi/agent/cursor-debug.jsonl

# Filter by session or time range
node scripts/debug-log-timeline.mjs --session <id> --since 2026-05-04T00:00:00Z

When disabled (default), all debug functions are zero-cost no-ops.

Capturing model parameters

To dump raw Cursor API responses during model discovery (useful for investigating new API fields or context tiers):

PI_CURSOR_CAPTURE_PARAMS=1 pi

On the first model discovery, the proxy captures three response variants (old, with-params, exploded) as JSON files in ~/.pi/agent/cursor-captures/. Each model includes contextTokenLimit and contextTokenLimitForMaxMode showing the available context tiers (e.g. 200K / 1M). See scripts/README.md for a standalone script that does the same without launching Pi.

Architecture

Pi ──(OpenAI API)──▶ Local Proxy ──(gRPC/H2)──▶ api2.cursor.sh
                       :PORT                      Cursor API

The extension spawns a standalone proxy process that translates between OpenAI's chat completions format and Cursor's protobuf Connect protocol over HTTP/2. The proxy is built with Rolldown for tree-shaking and ships as plain JS — no TypeScript flags needed at runtime.

Key design decisions

See docs/adr/ for Architecture Decision Records.

Development

pnpm build            # Build with Rolldown (~22ms)
pnpm test             # Run unit tests
pnpm test:watch       # Watch mode
pnpm lint             # Lint with oxlint (type-aware, strict)
pnpm lint:fix         # Auto-fix lint issues
pnpm format           # Format with oxfmt
pnpm format:check     # Check formatting
pnpm generate         # Regenerate proto types from proto/aiserver.proto

Developer scripts

See scripts/README.md for tools to capture raw Cursor API responses and visualize debug log timelines.

Proto files

The proto/aiserver.proto file and src/proto/agent_pb.ts are vendored from the Hardcode84/opencode-cursor fork (cursor-persists branch). To regenerate aiserver_pb.ts:

pnpm generate

The agent_pb.ts is vendored directly (the .proto source is not publicly available) and should not be regenerated.

How it works

  1. Login — PKCE OAuth flow opens cursor.com/loginDeepControl in the browser, polls api2.cursor.sh/auth/poll until the user completes login.
  2. Proxy startup — Extension spawns a child process running the built proxy. The proxy opens an HTTP server on a random port and writes {"type":"ready","port":N,"models":[...]} to stdout.
  3. Model discovery — Proxy calls AvailableModels via gRPC to fetch the user's available models. Legacy slugs are parsed to determine effort levels, fast/thinking support per model. Results are cached to disk for fast subsequent starts.
  4. Provider registration — Extension registers a cursor provider with Pi using api: 'openai-completions', pointing baseUrl at the local proxy.
  5. Chat completion — Pi sends standard OpenAI requests to the proxy. The proxy builds an AgentRunRequest protobuf, opens an H2 stream to api2.cursor.sh, and translates the response back into SSE chunks.
  6. Tool calls — Cursor's native tools (read, write, shell) are intercepted and emitted as OpenAI tool_calls only if the mapped Pi tool is enabled for the session. MCP tool calls are gated against the same registered tool set, and Cursor-only web/exa queries are rejected so the model falls back to available tools. Results flow back as protobuf frames.
  7. Multi-session — The proxy writes a port file at ~/.pi/agent/cursor-proxy.json. Other Pi sessions discover and reuse the same proxy. Each session sends heartbeats every 10s; the proxy exits 30s after the last heartbeat stops.

License

MIT