Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ temp/

# Jest cache
.jest/
.claude/

# Local artifacts
trash/
.entire/
test-mcp.mjs
tmux/
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ MCP Client (Claude Code)
→ ToolHandlers (handlers.ts)
→ executeCommand (command.ts)
→ Codex CLI

→ BrowserUseToolHandler (handlers.ts)
→ BrowserUseBridge (bridge.ts)
→ Playwright (peer dependency)
→ Chromium instances
```

### Key Files
Expand All @@ -55,6 +60,11 @@ MCP Client (Claude Code)
| `src/session/storage.ts` | In-memory session storage for conversation context |
| `src/utils/command.ts` | Command spawning with streaming support and Windows compatibility |
| `src/errors.ts` | Custom error classes (ValidationError, ToolExecutionError) |
| `src/browser-use/bridge.ts` | Singleton browser session manager (lazy Playwright init) |
| `src/browser-use/client.ts` | Playwright session operations (launch, screenshot, click, etc.) |
| `src/browser-use/handlers.ts` | Browser tool handler — dispatches on `action` parameter |
| `src/browser-use/definitions.ts` | Browser tool MCP schema and annotations |
| `src/browser-use/types.ts` | Zod schemas for browser actions, key normalization |

### MCP Tools

Expand All @@ -64,6 +74,7 @@ MCP Client (Claude Code)
- **listSessions**: View active conversation sessions
- **ping**: Test server connection
- **help**: Get Codex CLI help
- **browser**: Playwright-based browser automation via a single `action` parameter (`open`, `screenshot`, `navigate`, `click`, `type`, `key`, `scroll`, `drag`, `close`, `status`). Playwright is a peer dependency — lazy-loaded on first use.

### Session Management

Expand Down
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
[![npm downloads](https://img.shields.io/npm/dm/codex-mcp-server.svg)](https://www.npmjs.com/package/codex-mcp-server)
[![license](https://img.shields.io/npm/l/codex-mcp-server.svg)](https://www.npmjs.com/package/codex-mcp-server)

Bridge between Claude and OpenAI's Codex CLI — get AI-powered code analysis, generation, and review right in your editor.
Bridge between Claude and OpenAI's Codex CLI — get AI-powered code analysis, generation, and review right in your editor. Also includes optional browser automation via Playwright.

```mermaid
graph LR
A[Claude Code] --> B[Codex MCP Server]
B --> C[Codex CLI]
C --> D[OpenAI API]
B --> E[Browser Use]
E --> F[Chromium]

style A fill:#FF6B35
style B fill:#4A90E2
style C fill:#00D4AA
style D fill:#FFA500
style E fill:#9B59B6
style F fill:#E74C3C
```

## Quick Start
Expand Down Expand Up @@ -54,6 +58,7 @@ Use review to check my uncommitted changes
| `codex` | AI coding assistant with session support, model selection, and structured output metadata |
| `review` | AI-powered code review for uncommitted changes, branches, or commits |
| `websearch` | Web search using Codex CLI with customizable result count and search depth |
| `browser` | Browser automation via Playwright — open, screenshot, click, type, scroll, drag, navigate ([setup](docs/browser-use.md)) |
| `listSessions` | View active conversation sessions |
| `ping` | Test server connection |
| `help` | Get Codex CLI help |
Expand Down Expand Up @@ -90,8 +95,14 @@ Use codex to return structuredContent with threadId metadata when available
**Web search:**
```
Use websearch with query "TypeScript 5.8 new features"
Use websearch with query "Rust vs Go performance 2025" and numResults 15
Use websearch with query "React Server Components" and searchDepth "full"
```

**Browser Automation:**
```
Use browser with action "status" to check if Playwright is available
Use browser with action "open", sessionId "web1", and url "https://example.com"
Use browser with action "screenshot" and sessionId "web1" to see the page
Use browser with action "click", sessionId "web1", x 100, and y 200
```

## Requirements
Expand All @@ -105,6 +116,7 @@ Use websearch with query "React Server Components" and searchDepth "full"
## Documentation

- **[API Reference](docs/api-reference.md)** — Full tool parameters and response formats
- **[Browser Use](docs/browser-use.md)** — Playwright setup, tools, and troubleshooting
- **[Session Management](docs/session-management.md)** — How conversations work
- **[Codex CLI Integration](docs/codex-cli-integration.md)** — Version compatibility and CLI details

Expand Down
37 changes: 36 additions & 1 deletion docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ All tools include annotations that provide hints to MCP clients about tool behav
|------|---------|---------------|-------------------|------------------|-----------------|
| `codex` | Execute Codex CLI | `false` | `true` | `false` | `true` |
| `review` | Code Review | `true` | `false` | `true` | `true` |
| `websearch` | Web Search | `true` | `false` | `true` | `true` |
| `ping` | Ping Server | `true` | `false` | `true` | `false` |
| `help` | Get Help | `true` | `false` | `true` | `false` |
| `listSessions` | List Sessions | `true` | `false` | `true` | `false` |
| `browser` | Browser Control | `false` | `true` | `false` | `true` |

### Progress Notifications
For long-running operations, the server sends `notifications/progress` messages when the client includes a `progressToken` in the request `_meta`.
Expand Down Expand Up @@ -439,4 +441,37 @@ Optional:
### Optional Configuration
- **CODEX_HOME**: Custom directory for Codex CLI configuration
- **Session Limits**: Configurable in server implementation (default: 100)
- **TTL Settings**: Configurable session expiration (default: 24 hours)
- **TTL Settings**: Configurable session expiration (default: 24 hours)

## Browser Use

Cross-platform browser automation via Playwright. See [Browser Use](browser-use.md) for setup instructions.

### `browser` — Browser Control

**Annotations:** `readOnlyHint: false`, `destructiveHint: true`, `idempotentHint: false`, `openWorldHint: true`

A single tool for all browser operations, selected via the `action` parameter.

| Parameter | Type | Required | Action | Default | Description |
|-----------|------|----------|--------|---------|-------------|
| `action` | enum | yes | all | — | `open`, `screenshot`, `navigate`, `click`, `type`, `key`, `scroll`, `drag`, `close`, `status` |
| `sessionId` | string | see below | all except `status` | — | Browser session ID |
| `url` | string | no | `open`, `navigate` | — | URL to open or navigate to |
| `headless` | boolean | no | `open` | `true` | Run without visible window |
| `viewportWidth` | integer | no | `open` | `1440` | Viewport width in pixels |
| `viewportHeight` | integer | no | `open` | `900` | Viewport height in pixels |
| `x` | number | no | `click` | — | X coordinate (viewport-relative) |
| `y` | number | no | `click` | — | Y coordinate (viewport-relative) |
| `button` | enum | no | `click` | `left` | `left`, `right`, or `middle` |
| `clickCount` | integer | no | `click` | `1` | Number of clicks |
| `text` | string | no | `type` | — | Text to type into focused element |
| `key` | string | no | `key` | — | Key or combo (`Enter`, `Control+a`, `Meta+s`) |
| `direction` | enum | no | `scroll` | — | `up`, `down`, `left`, or `right` |
| `amount` | integer | no | `scroll` | `300` | Scroll amount in pixels |
| `fromX` | number | no | `drag` | — | Start X coordinate |
| `fromY` | number | no | `drag` | — | Start Y coordinate |
| `toX` | number | no | `drag` | — | End X coordinate |
| `toY` | number | no | `drag` | — | End Y coordinate |

Modifier keys are auto-normalized: `Cmd`/`Command` → `Meta`, `Ctrl` → `Control`, `Opt`/`Option` → `Alt`.
67 changes: 67 additions & 0 deletions docs/browser-use.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Browser Use

Playwright-based browser automation. Launch a real Chromium browser, take screenshots, click, type, scroll, drag, and navigate — all via a single MCP tool with an `action` parameter.

## Architecture

```text
Claude Code
→ codex-mcp-server
→ BrowserUseBridge (singleton, lazy init)
→ Playwright (peer dependency)
→ Chromium instances
```

The bridge manages multiple concurrent browser sessions. Playwright is only imported on first use — no impact on codex/review startup when browser tools aren't used.

## Setup

```bash
npm install playwright
npx playwright install chromium
```

Playwright is a **peer dependency** — install it separately. The server works fine without it; the browser tool will return a helpful error if Playwright isn't available.

## Tool: `browser`

A single tool for all browser operations. Every call requires an `action` parameter.

### Session Lifecycle

| Action | Example | Description |
|--------|---------|-------------|
| `open` | `{ "action": "open", "sessionId": "s1", "url": "https://example.com" }` | Launch a browser session. Optional: `url`, `headless` (default true), `viewportWidth` (default 1440), `viewportHeight` (default 900) |
| `status` | `{ "action": "status" }` | Check if Playwright is available and list active sessions |
| `close` | `{ "action": "close", "sessionId": "s1" }` | Close a session and clean up resources |

### Navigation & Capture

| Action | Example | Description |
|--------|---------|-------------|
| `navigate` | `{ "action": "navigate", "sessionId": "s1", "url": "https://example.com/page2" }` | Navigate to a URL |
| `screenshot` | `{ "action": "screenshot", "sessionId": "s1" }` | Take a screenshot. Returns base64 PNG image data + page URL + title |

### Input Actions

| Action | Example | Description |
|--------|---------|-------------|
| `click` | `{ "action": "click", "sessionId": "s1", "x": 100, "y": 200 }` | Click at viewport coordinates. Optional: `button` (left/right/middle), `clickCount` |
| `type` | `{ "action": "type", "sessionId": "s1", "text": "hello world" }` | Type text into the focused element |
| `key` | `{ "action": "key", "sessionId": "s1", "key": "Control+a" }` | Press a key or combo. Modifier keys auto-normalized (`Cmd`→`Meta`, `Ctrl`→`Control`) |
| `scroll` | `{ "action": "scroll", "sessionId": "s1", "direction": "down", "amount": 300 }` | Scroll page: `up`/`down`/`left`/`right` by pixel amount |
| `drag` | `{ "action": "drag", "sessionId": "s1", "fromX": 0, "fromY": 0, "toX": 100, "toY": 100 }` | Drag from one coordinate to another (viewport-relative) |

## Troubleshooting

**"Playwright is not installed"**
Install it: `npm install playwright && npx playwright install chromium`

**"Session already exists"**
Use a different sessionId or close the existing session first.

**"No active browser session"**
You must call `{ "action": "open" }` before any other action.

**Screenshots not loading**
Check that the client supports `image` content type in MCP tool results. Claude Code supports this natively.
6 changes: 6 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export default [
globals: {
console: 'readonly',
process: 'readonly',
Buffer: 'readonly',
setTimeout: 'readonly',
clearTimeout: 'readonly',
setInterval: 'readonly',
clearInterval: 'readonly',
setImmediate: 'readonly',
},
},
plugins: {
Expand Down
1 change: 1 addition & 0 deletions jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export default {
'**/__tests__/**/*.test.ts',
'**/?(*.)+(spec|test).ts',
],
testPathIgnorePatterns: ['/node_modules/', '/trash/'],
};
50 changes: 50 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,8 @@
"ts-jest": "^29.4.1",
"tsx": "^4.20.4",
"typescript": "^5.9.2"
},
"peerDependencies": {
"playwright": "^1.59.1"
}
}
Loading
Loading