feat: enhance OpenClaw integration with Cursor's AI models
This commit adds comprehensive support for using Cursor's AI models (e.g., Claude, GPT-4) within OpenClaw. Key updates include new setup instructions, model availability details, and usage examples in the documentation. The `setup-models` command is introduced to facilitate configuration and health checks for the Copilot Proxy. Additionally, a new module for managing Cursor models is created to streamline integration. New files added: - `src/cursor-models.ts`: Module for Cursor model management. - Updates to `cursor-mcp.md`, `README.md`, and `index.ts` for enhanced documentation and command functionality.
This commit is contained in:
parent
c473a69f2d
commit
c01df21ea4
@ -207,6 +207,45 @@ Clear and restart a session using the `openclaw_clear_session` tool or:
|
||||
openclaw sessions clear agent:main:cursor
|
||||
```
|
||||
|
||||
## Using Cursor's Models in OpenClaw
|
||||
|
||||
The integration is bidirectional - you can also use Cursor's AI models (Claude, GPT-4, etc.) as providers for OpenClaw.
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Install Copilot Proxy extension** in Cursor (search for "Copilot Proxy" by AdrianGonz97)
|
||||
|
||||
2. **Check the proxy**:
|
||||
```bash
|
||||
openclaw mcp setup-models --check
|
||||
```
|
||||
|
||||
3. **Configure OpenClaw**:
|
||||
```bash
|
||||
openclaw config set agents.defaults.model cursor/claude-sonnet-4
|
||||
```
|
||||
|
||||
### Available Models
|
||||
|
||||
| Model | ID |
|
||||
|-------|-----|
|
||||
| Claude Sonnet 4 | `cursor/claude-sonnet-4` |
|
||||
| Claude Sonnet 4 (Thinking) | `cursor/claude-sonnet-4-thinking` |
|
||||
| GPT-4o | `cursor/gpt-4o` |
|
||||
| GPT-4o Mini | `cursor/gpt-4o-mini` |
|
||||
| o1 | `cursor/o1` |
|
||||
| Gemini 2.5 Pro | `cursor/gemini-2.5-pro` |
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Use Cursor's Claude in OpenClaw
|
||||
openclaw agent --model cursor/claude-sonnet-4 "Help me debug this"
|
||||
|
||||
# In the TUI
|
||||
openclaw tui --model cursor/gpt-4o
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [Gateway Configuration](/gateway/configuration)
|
||||
|
||||
@ -216,6 +216,71 @@ node bin/server.js
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
## Using Cursor's Models with OpenClaw
|
||||
|
||||
You can also use Cursor's AI models (Claude, GPT-4, etc.) as providers for OpenClaw. This enables bidirectional integration:
|
||||
|
||||
- **OpenClaw → Cursor**: Use OpenClaw tools in Cursor (MCP server)
|
||||
- **Cursor → OpenClaw**: Use Cursor's models in OpenClaw
|
||||
|
||||
### Setup Cursor Models
|
||||
|
||||
1. **Install Copilot Proxy extension** in Cursor:
|
||||
- Search for "Copilot Proxy" by AdrianGonz97 in Extensions
|
||||
- Install and restart Cursor
|
||||
|
||||
2. **Check the proxy is running**:
|
||||
```bash
|
||||
openclaw mcp setup-models --check
|
||||
```
|
||||
|
||||
3. **Configure OpenClaw** to use Cursor models:
|
||||
```bash
|
||||
# Set a Cursor model as default
|
||||
openclaw config set agents.defaults.model cursor/claude-sonnet-4
|
||||
```
|
||||
|
||||
Or manually add to `~/.clawdbot/config.yaml`:
|
||||
```yaml
|
||||
models:
|
||||
providers:
|
||||
cursor:
|
||||
baseUrl: "http://localhost:3000/v1"
|
||||
apiKey: "cursor-proxy"
|
||||
api: openai-completions
|
||||
models:
|
||||
- id: claude-sonnet-4
|
||||
name: Claude Sonnet 4
|
||||
contextWindow: 200000
|
||||
```
|
||||
|
||||
### Available Cursor Models
|
||||
|
||||
| Model ID | Description |
|
||||
|----------|-------------|
|
||||
| `cursor/claude-sonnet-4` | Claude Sonnet 4 |
|
||||
| `cursor/claude-sonnet-4-thinking` | Claude Sonnet 4 with extended thinking |
|
||||
| `cursor/gpt-4o` | GPT-4o |
|
||||
| `cursor/gpt-4o-mini` | GPT-4o Mini |
|
||||
| `cursor/o1` | OpenAI o1 (reasoning) |
|
||||
| `cursor/o1-mini` | OpenAI o1-mini |
|
||||
| `cursor/gemini-2.5-pro` | Gemini 2.5 Pro |
|
||||
|
||||
> **Note**: Available models depend on your Cursor subscription tier.
|
||||
|
||||
### Usage Examples
|
||||
|
||||
```bash
|
||||
# Chat using Cursor's Claude
|
||||
openclaw agent --model cursor/claude-sonnet-4 "Explain this code"
|
||||
|
||||
# Send message via channels using GPT-4
|
||||
openclaw message send --model cursor/gpt-4o "Hello from OpenClaw!"
|
||||
|
||||
# Use in TUI
|
||||
openclaw tui --model cursor/claude-sonnet-4
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT - Part of the OpenClaw project.
|
||||
|
||||
@ -78,6 +78,64 @@ const cursorMcpPlugin = {
|
||||
await server.start();
|
||||
});
|
||||
|
||||
// Command to set up Cursor models as a provider
|
||||
mcpCommand
|
||||
.command("setup-models")
|
||||
.description("Configure OpenClaw to use Cursor's AI models via Copilot Proxy")
|
||||
.option("--url <url>", "Copilot Proxy base URL", "http://localhost:3000/v1")
|
||||
.option("--check", "Only check if proxy is running, don't configure")
|
||||
.action(async (opts) => {
|
||||
const {
|
||||
checkCursorProxyHealth,
|
||||
generateCursorProviderConfig,
|
||||
CURSOR_AVAILABLE_MODELS,
|
||||
CURSOR_SETUP_INSTRUCTIONS,
|
||||
} = await import("./src/cursor-models.js");
|
||||
|
||||
console.log("Checking Cursor Copilot Proxy...");
|
||||
const health = await checkCursorProxyHealth(opts.url);
|
||||
|
||||
if (!health.ok) {
|
||||
console.error(`\n❌ Copilot Proxy not accessible: ${health.error}`);
|
||||
console.log(CURSOR_SETUP_INSTRUCTIONS);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("✓ Copilot Proxy is running");
|
||||
|
||||
if (opts.check) {
|
||||
console.log("\nAvailable models:");
|
||||
for (const model of CURSOR_AVAILABLE_MODELS) {
|
||||
console.log(` - cursor/${model.id} (${model.name})`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate and apply config
|
||||
const configPatch = generateCursorProviderConfig({ baseUrl: opts.url });
|
||||
console.log("\nTo use Cursor models, add this to your OpenClaw config:\n");
|
||||
console.log("```yaml");
|
||||
console.log("models:");
|
||||
console.log(" providers:");
|
||||
console.log(" cursor:");
|
||||
console.log(` baseUrl: "${opts.url}"`);
|
||||
console.log(' apiKey: "cursor-proxy"');
|
||||
console.log(" api: openai-completions");
|
||||
console.log(" authHeader: false");
|
||||
console.log(" models:");
|
||||
for (const model of CURSOR_AVAILABLE_MODELS.slice(0, 4)) {
|
||||
console.log(` - id: ${model.id}`);
|
||||
console.log(` name: ${model.name}`);
|
||||
console.log(` contextWindow: ${model.contextWindow}`);
|
||||
}
|
||||
console.log("```");
|
||||
console.log("\nOr run: openclaw config set agents.defaults.model cursor/claude-sonnet-4");
|
||||
console.log("\nAvailable models:");
|
||||
for (const model of CURSOR_AVAILABLE_MODELS) {
|
||||
console.log(` - cursor/${model.id}`);
|
||||
}
|
||||
});
|
||||
|
||||
mcpCommand
|
||||
.command("info")
|
||||
.description("Show MCP server configuration information for Cursor")
|
||||
|
||||
233
extensions/cursor-mcp/src/cursor-models.ts
Normal file
233
extensions/cursor-mcp/src/cursor-models.ts
Normal file
@ -0,0 +1,233 @@
|
||||
/**
|
||||
* Cursor Model Provider for OpenClaw
|
||||
*
|
||||
* This module provides integration with Cursor's Language Model API,
|
||||
* allowing OpenClaw to use models available through Cursor's subscription
|
||||
* (Claude, GPT-4, etc.).
|
||||
*
|
||||
* How it works:
|
||||
* 1. Cursor exposes models via a local HTTP API when the Copilot Proxy extension is active
|
||||
* 2. OpenClaw connects to this API as an OpenAI-compatible endpoint
|
||||
* 3. You can then use Cursor's models in OpenClaw prompts
|
||||
*
|
||||
* Setup:
|
||||
* 1. Install "Copilot Proxy" extension in Cursor
|
||||
* 2. Run `openclaw setup cursor` to configure
|
||||
* 3. Use models like `cursor/claude-sonnet-4` in OpenClaw
|
||||
*/
|
||||
|
||||
import type { CursorMcpConfig } from "./types.js";
|
||||
|
||||
// Default Cursor proxy configuration
|
||||
const DEFAULT_CURSOR_PROXY_URL = "http://localhost:3000/v1";
|
||||
const DEFAULT_CURSOR_PROXY_PORT = 3000;
|
||||
|
||||
// Models typically available through Cursor
|
||||
export const CURSOR_AVAILABLE_MODELS = [
|
||||
{
|
||||
id: "claude-sonnet-4",
|
||||
name: "Claude Sonnet 4",
|
||||
provider: "anthropic",
|
||||
contextWindow: 200000,
|
||||
reasoning: false,
|
||||
},
|
||||
{
|
||||
id: "claude-sonnet-4-thinking",
|
||||
name: "Claude Sonnet 4 (Thinking)",
|
||||
provider: "anthropic",
|
||||
contextWindow: 200000,
|
||||
reasoning: true,
|
||||
},
|
||||
{
|
||||
id: "gpt-4o",
|
||||
name: "GPT-4o",
|
||||
provider: "openai",
|
||||
contextWindow: 128000,
|
||||
reasoning: false,
|
||||
},
|
||||
{
|
||||
id: "gpt-4o-mini",
|
||||
name: "GPT-4o Mini",
|
||||
provider: "openai",
|
||||
contextWindow: 128000,
|
||||
reasoning: false,
|
||||
},
|
||||
{
|
||||
id: "o1",
|
||||
name: "o1",
|
||||
provider: "openai",
|
||||
contextWindow: 200000,
|
||||
reasoning: true,
|
||||
},
|
||||
{
|
||||
id: "o1-mini",
|
||||
name: "o1-mini",
|
||||
provider: "openai",
|
||||
contextWindow: 128000,
|
||||
reasoning: true,
|
||||
},
|
||||
{
|
||||
id: "gemini-2.5-pro",
|
||||
name: "Gemini 2.5 Pro",
|
||||
provider: "google",
|
||||
contextWindow: 1000000,
|
||||
reasoning: false,
|
||||
},
|
||||
] as const;
|
||||
|
||||
export type CursorModelId = (typeof CURSOR_AVAILABLE_MODELS)[number]["id"];
|
||||
|
||||
export type CursorModelConfig = {
|
||||
baseUrl: string;
|
||||
models: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the Cursor proxy is running and accessible
|
||||
*/
|
||||
export async function checkCursorProxyHealth(
|
||||
baseUrl: string = DEFAULT_CURSOR_PROXY_URL,
|
||||
): Promise<{ ok: boolean; error?: string }> {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
const response = await fetch(`${baseUrl}/models`, {
|
||||
method: "GET",
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (response.ok) {
|
||||
return { ok: true };
|
||||
}
|
||||
return { ok: false, error: `HTTP ${response.status}: ${response.statusText}` };
|
||||
} catch (err) {
|
||||
if (err instanceof Error && err.name === "AbortError") {
|
||||
return { ok: false, error: "Connection timeout - is Copilot Proxy running in Cursor?" };
|
||||
}
|
||||
return { ok: false, error: String(err) };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate OpenClaw configuration patch for Cursor models
|
||||
*/
|
||||
export function generateCursorProviderConfig(opts: {
|
||||
baseUrl?: string;
|
||||
models?: string[];
|
||||
}): Record<string, unknown> {
|
||||
const baseUrl = opts.baseUrl ?? DEFAULT_CURSOR_PROXY_URL;
|
||||
const modelIds = opts.models ?? CURSOR_AVAILABLE_MODELS.map((m) => m.id);
|
||||
|
||||
return {
|
||||
models: {
|
||||
providers: {
|
||||
cursor: {
|
||||
baseUrl,
|
||||
apiKey: "cursor-proxy", // Placeholder - Copilot Proxy handles auth
|
||||
api: "openai-completions",
|
||||
authHeader: false,
|
||||
models: modelIds.map((id) => {
|
||||
const model = CURSOR_AVAILABLE_MODELS.find((m) => m.id === id);
|
||||
return {
|
||||
id,
|
||||
name: model?.name ?? id,
|
||||
api: "openai-completions",
|
||||
reasoning: model?.reasoning ?? false,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: model?.contextWindow ?? 128000,
|
||||
maxTokens: 8192,
|
||||
};
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
agents: {
|
||||
defaults: {
|
||||
models: Object.fromEntries(modelIds.map((id) => [`cursor/${id}`, {}])),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructions for setting up Cursor model integration
|
||||
*/
|
||||
export const CURSOR_SETUP_INSTRUCTIONS = `
|
||||
# Using Cursor's Models with OpenClaw
|
||||
|
||||
## Prerequisites
|
||||
1. Cursor IDE with an active subscription (Pro/Business)
|
||||
2. The "Copilot Proxy" VS Code extension installed in Cursor
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### Step 1: Install Copilot Proxy Extension
|
||||
In Cursor, go to Extensions and search for "Copilot Proxy" by AdrianGonz97.
|
||||
Install it and restart Cursor.
|
||||
|
||||
### Step 2: Start the Proxy Server
|
||||
The extension should start automatically. Verify it's running:
|
||||
- Look for "Copilot Proxy" in the status bar
|
||||
- Or check http://localhost:3000/v1/models in your browser
|
||||
|
||||
### Step 3: Configure OpenClaw
|
||||
Run the setup command:
|
||||
openclaw setup cursor
|
||||
|
||||
Or manually add to your config (~/.clawdbot/config.yaml):
|
||||
|
||||
models:
|
||||
providers:
|
||||
cursor:
|
||||
baseUrl: "http://localhost:3000/v1"
|
||||
apiKey: "cursor-proxy"
|
||||
api: openai-completions
|
||||
authHeader: false
|
||||
models:
|
||||
- id: claude-sonnet-4
|
||||
name: Claude Sonnet 4
|
||||
contextWindow: 200000
|
||||
- id: gpt-4o
|
||||
name: GPT-4o
|
||||
contextWindow: 128000
|
||||
|
||||
### Step 4: Use Cursor Models
|
||||
Now you can use Cursor's models in OpenClaw:
|
||||
|
||||
# Set as default model
|
||||
openclaw config set agents.defaults.model cursor/claude-sonnet-4
|
||||
|
||||
# Use in a specific message
|
||||
openclaw message send --model cursor/gpt-4o "Hello!"
|
||||
|
||||
# Use in the TUI
|
||||
openclaw tui --model cursor/claude-sonnet-4
|
||||
|
||||
## Available Models (depends on your Cursor subscription)
|
||||
- cursor/claude-sonnet-4
|
||||
- cursor/claude-sonnet-4-thinking
|
||||
- cursor/gpt-4o
|
||||
- cursor/gpt-4o-mini
|
||||
- cursor/o1
|
||||
- cursor/o1-mini
|
||||
- cursor/gemini-2.5-pro
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Proxy not responding
|
||||
- Ensure Cursor is running with the Copilot Proxy extension active
|
||||
- Check if http://localhost:3000/v1/models returns a response
|
||||
- Try restarting Cursor
|
||||
|
||||
### Model not available
|
||||
- Your Cursor subscription may not include all models
|
||||
- Check Cursor's model selector to see which models you have access to
|
||||
|
||||
### Authentication errors
|
||||
- Ensure you're logged into Cursor with your subscription account
|
||||
- The proxy uses your Cursor session for authentication
|
||||
`;
|
||||
Loading…
Reference in New Issue
Block a user