cursor2api

repository·main·Indexed 22 days ago

https://github.com/7836246/cursor2api

A proxy service that converts Cursor's internal documentation and chat interfaces into standard Anthropic Messages API and OpenAI Chat Completions API formats. It enables the use of Claude Code, ChatBox, LobeChat, and other standard clients with Cursor's backend. Version 2.7.8 includes features such as context pressure management, tool smart truncation, and a Vue3-based logs viewer UI for real-time request monitoring.

Tokens
13.1K
Snippets
23
Records
75
Agent score
83%

What's inside cursor2api

  1. Compare /logs and /vuelogs routes

    main

    The system provides two distinct ways to view logs, which coexist independently:

    • /logs: Uses a native HTML page (public/logs.html) and relies on server-side cookie authentication.
    • /vuelogs: Uses the Vue3 Log UI application and handles authentication via a dedicated frontend login page.
  2. Understand the Cognitive Reframing strategy

    main

    Cursor2API uses a technique called Cognitive Reframing to bypass Cursor's strict 'Documentation Assistant' restrictions. Instead of fighting the model's forced identity, the system injects a prompt that tells the model it is writing API documentation and needs to generate JSON examples of tool calls for the user to copy-paste.

    This approach tricks the model into thinking it is performing a safe documentation task rather than executing unauthorized commands, effectively restoring full IDE operation permissions. The system also modifies the referer header to the root path to avoid being routed to the restricted documentation mode.

  3. How multi-layer refusal defense works

    main

    To prevent the model from refusing tasks (like searching news or writing files) due to Cursor's internal filters, the proxy implements four layers of defense:

    1. L1: Context Cleaning (converter.ts): Removes refusal text and permission errors from chat history so the model doesn't 'learn' to refuse.
    2. L2: XML Tag Separation (converter.ts): Separates Claude Code's <system-reminder> from user requests to keep IDE instructions close to user text.
    3. L3: Output Interception (handler.ts): Uses 50+ regex patterns to intercept and replace refusal text in real-time (streaming or non-streaming).
    4. L4: Response Sanitization (handler.ts): Uses sanitizeResponse() to post-process output, replacing Cursor identity references with 'Claude'.
  4. Use Cursor2API with Cursor IDE

    main

    To integrate with Cursor IDE, configure the OPENAI_BASE_URL in the Cursor settings.

    Configuration:

    • Set OPENAI_BASE_URL to your public domain (e.g., https://your-domain.example.com/v1).
    • Note: It is highly recommended to use an HTTPS reverse proxy. Direct local or LAN addresses (like http://localhost:3010/v1) typically do not work in Cursor IDE.
    • Select a Claude model (e.g., claude-sonnet-4-20250514) from the model list. You can view available models via the /v1/models endpoint.

    Important Requirements:

    • A Cursor Pro subscription is usually required to use custom Base URLs/models.
    • Avoid using GPT model names; use Claude model names for best compatibility.
  5. Access the Logs Viewer UI

    main

    Cursor2API provides a Web UI to monitor requests, responses, and tool calls in real-time.

    Accessing the UI: Navigate to http://localhost:3010/logs after starting the service.

    Authentication:

    • If auth_tokens are configured, you must log in to the logs page.
    • You can bypass the login screen by passing the token as a URL parameter: http://localhost:3010/logs?token=sk-your-secret-token-1

    Key Features:

    • Real-time stream: Uses SSE to show request processing stages.
    • Status Filtering: Filter by success, degraded, failure, or intercepted states.
    • Degraded Diagnostics: Identifies why a request was marked degraded (e.g., tool not called, max_tokens not recovered).
    • Persistence: If logging.db_enabled is true, history is stored in SQLite.
    http://localhost:3010/logs?token=sk-your-secret-token-1
  6. Deploy the Log UI using Docker Compose

    main

    Follow these steps to deploy the full stack using Docker:

    1. Prepare configuration: Copy the example config to create your active config.yaml.
    2. Build frontend: Run the build command from the vue-ui directory to ensure assets are in public/vue/.
    3. Launch containers: Use docker compose to build and start the services.
    4. Access UI: Open the browser to the specified route.

    Critical Configuration Notes:

    • Permissions: When mounting config.yaml, do not use the :ro (read-only) flag. The ConfigDrawer needs write access to save changes.
    • Write Errors: If you encounter EACCES: permission denied errors when saving configurations, set the file permissions using chmod 666 config.yaml.
  7. Develop the cursor2api Vue3 Log UI locally

    main

    To develop the UI locally, you need to run both the backend and the frontend development servers. The frontend server (running in the vue-ui directory) automatically proxies /api requests to http://localhost:3010.

    1. Start the backend: From the project root, run:
    npm run dev
    1. Start the frontend: Navigate to the vue-ui directory, install dependencies, and start the Vite server (defaults to http://localhost:5173):
    cd vue-ui && npm install && npm run dev
  8. Build the Vue3 Log UI for production

    main

    Before deploying or using Docker, you must build the frontend assets. The build output is placed in the project root's public/vue/ directory, which the backend serves via the /vuelogs route.

    Warning: You must execute this build step before building a Docker image, otherwise the container will lack the necessary frontend static resources.

    cd vue-ui && npm run build
  9. Use Cursor2API with Claude Code

    main

    To use Claude Code with Cursor2API, set the ANTHROPIC_BASE_URL environment variable to your service address. If you have configured auth_tokens, you must also provide the ANTHROPIC_API_KEY.

    Basic usage:

    export ANTHROPIC_BASE_URL=http://localhost:3010
    claude

    With authentication:

    export ANTHROPIC_BASE_URL=http://localhost:3010
    export ANTHROPIC_API_KEY=sk-your-secret-token-1
    claude
  10. Install and run Cursor2API

    main

    To set up Cursor2API, follow these steps to install dependencies, configure the service, and start it in either development or production mode.

    1. Install dependencies

    npm install

    2. Configure the service

    Copy the example configuration file to config.yaml and modify it as needed:

    cp config.yaml.example config.yaml

    3. Start the service

    Development mode:

    npm run dev

    Production mode:

    npm run build && npm start
    npm install
    cp config.yaml.example config.yaml
    npm run dev
  11. Understand the Responses API SSE event sequence

    main

    When using the Responses API in streaming mode, the server emits a specific sequence of SSE events to represent the lifecycle of a response. A successful text response follows this pattern:

    1. event: response.created
    2. event: response.in_progress
    3. event: response.output_item.added (for the message item)
    4. event: response.content_part.added (for the text part)
    5. event: response.output_text.delta (multiple chunks of text)
    6. event: response.output_text.done
    7. event: response.content_part.done
    8. event: response.output_item.done
    9. event: response.completed (The critical event for client completion)

    For tool calls, the sequence includes function_call type items and response.function_call_arguments.delta events for streaming arguments.

  12. How OpenAI response formats (JSON mode) are handled

    main

    If an OpenAI request includes a response_format with a type other than text (such as json_object or json_schema), the proxy automatically appends a instruction to the last user message to ensure the model complies.

    For json_schema, the schema is stringified and appended to the prompt. For general JSON mode, a suffix like \n\nRespond in plain JSON format without markdown wrapping. is added.