@schultzp2020/pi-cursor
Pi extension for Cursor subscription models via local OpenAI-compatible proxy
Package details
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.4.0- Published
- May 4, 2026
- Downloads
- 517/mo · 517/wk
- Author
- schultzp2020
- License
- MIT
- Types
- extension
- Size
- 444 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/reasoning —
thinkingDeltaevents map toreasoning_contentin 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. By default (modelMappings=normalized), 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 setting controlling the variant sent to Cursor.
Set modelMappings to raw (or PI_CURSOR_RAW_MODELS=1) to see all raw Cursor model variants.
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 |
|---|---|---|---|
| Native Tools Mode | reject, redirect, native |
reject |
PI_CURSOR_NATIVE_TOOLS_MODE |
| Max Mode | on, off |
off |
PI_CURSOR_MAX_MODE |
| Model Mappings | normalized, raw |
normalized |
PI_CURSOR_RAW_MODELS |
| Max Retries | 0, 1, 2, 3, 5 |
2 |
PI_CURSOR_MAX_RETRIES |
Settings persist to ~/.pi/agent/cursor-config.json. Changing Model Mappings triggers provider re-registration to update the model picker. Max Mode is hidden when Model Mappings is set to raw.
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 packages/pi-cursor/scripts/debug-log-timeline.mjs ~/.pi/agent/cursor-debug.jsonl
# Filter by session or time range
node packages/pi-cursor/scripts/debug-log-timeline.mjs --session <id> --since 2026-05-04T00:00:00Z
When disabled (default), all debug functions are zero-cost no-ops.
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
npm run build # Build with Rolldown (~22ms)
npm test # Run unit tests
npm run test:watch # Watch mode
npm run lint # Lint with oxlint (type-aware, strict)
npm run lint:fix # Auto-fix lint issues
npm run format # Format with oxfmt
npm run format:check # Check formatting
npm run generate # Regenerate proto types from proto/aiserver.proto
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:
npm run generate
The agent_pb.ts is vendored directly (the .proto source is not publicly available) and should not be regenerated.
How it works
- Login — PKCE OAuth flow opens
cursor.com/loginDeepControlin the browser, pollsapi2.cursor.sh/auth/polluntil the user completes login. - 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. - Model discovery — Proxy calls
AvailableModels(orGetUsableModelsas fallback) via gRPC to fetch the user's available models. Results are cached to disk for fast subsequent starts. - Provider registration — Extension registers a
cursorprovider with Pi usingapi: 'openai-completions', pointingbaseUrlat the local proxy. - Chat completion — Pi sends standard OpenAI requests to the proxy. The proxy builds an
AgentRunRequestprotobuf, opens an H2 stream toapi2.cursor.sh, and translates the response back into SSE chunks. - Tool calls — Cursor's native tools (read, write, shell) are intercepted and emitted as OpenAI
tool_callsonly 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. - 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.