Skip to content
Merged
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
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
MIT License

Copyright (c) 2026 codex-with-chatgpt contributors
Copyright (c) 2026 Claude to Codex contributors
Copyright (c) 2026 Chat to Codex contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
16 changes: 8 additions & 8 deletions README.id.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Claude to Codex (C2C)
# Chat to Codex (C2C)

[English](README.md) | **Bahasa Indonesia** | [简体中文](README.zh-CN.md)

Expand Down Expand Up @@ -42,8 +42,8 @@ Semua capability yang tersedia untuk Claude bersifat read-only. Workspace didaft
Persyaratan: Node.js ≥ 20, `git`, `cloudflared`, dan Claude Web dengan dukungan custom connector.

```bash
git clone https://github.com/willio/claude-to-codex.git
cd claude-to-codex
git clone https://github.com/willio/chat-to-codex.git
cd chat-to-codex
pnpm install
pnpm build
node bin/c2c.js install # systemwide install: ~/.c2c (app + state + launcher)
Expand All @@ -52,8 +52,8 @@ node bin/c2c.js install # systemwide install: ~/.c2c (app + state + launcher)
Install Codex skill:

```bash
mkdir -p ~/.codex/skills/claude-to-codex
cp skill/SKILL.md ~/.codex/skills/claude-to-codex/
mkdir -p ~/.codex/skills/chat-to-codex
cp skill/SKILL.md ~/.codex/skills/chat-to-codex/
```

### Hubungkan Claude
Expand Down Expand Up @@ -178,7 +178,7 @@ Untuk kompatibilitas, `doctor --json` menggunakan `connectorRepair` sebagai fiel

## Kompatibilitas

Claude to Codex berawal dari ide dan arsitektur `codex-with-chatgpt`, kemudian berkembang menjadi implementasi independen.
Chat to Codex berawal dari ide dan arsitektur `codex-with-chatgpt`, kemudian berkembang menjadi implementasi independen.

Arsitektur saat ini menggunakan satu connector Claude pada level instalasi untuk melayani banyak workspace Codex yang didaftarkan secara lokal.

Expand Down Expand Up @@ -215,11 +215,11 @@ docs/ architecture, protocol, security and migration

## Credits

Claude to Codex dibangun di atas ide dan arsitektur dari [codex-with-chatgpt](https://github.com/XiaoDuoYa/codex-with-chatgpt) karya [@XiaoDuoYa](https://github.com/XiaoDuoYa).
Chat to Codex dibangun di atas ide dan arsitektur dari [codex-with-chatgpt](https://github.com/XiaoDuoYa/codex-with-chatgpt) karya [@XiaoDuoYa](https://github.com/XiaoDuoYa).

Project ini kemudian berkembang menjadi implementasi independen untuk Claude Web, dengan tetap menjaga atribusi untuk karya upstream dan copyright MIT-nya di [LICENSE](LICENSE).

Claude to Codex adalah project komunitas dan tidak terafiliasi atau didukung oleh Anthropic maupun OpenAI.
Chat to Codex adalah project komunitas dan tidak terafiliasi atau didukung oleh Anthropic maupun OpenAI.

## License

Expand Down
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Claude to Codex (C2C)
# Chat to Codex (C2C)

**English** | [Bahasa Indonesia](README.id.md) | [简体中文](README.zh-CN.md)

Use Claude Web to plan, reason, and review. Let Codex execute — connected through a secure, read-only MCP bridge.
Bring your AI chat sessions to Codex. Claude Web, ChatGPT, or any chat that speaks remote MCP plans, reasons, and reviews — Codex executes, connected through a secure, read-only MCP bridge.

**No Claude API key. No reverse proxy.** Claude connects to an OAuth-protected remote MCP endpoint and reads only the workspace data it needs.

Expand All @@ -13,6 +13,14 @@ Use Claude Web to plan, reason, and review. Let Codex execute — connected thro

Based on [codex-with-chatgpt](https://github.com/XiaoDuoYa/codex-with-chatgpt).

## Multiple chat brains

One installation serves several AI chats at once. Connect Claude Web,
ChatGPT (Plus — Developer mode → Connectors → Create → paste the `/mcp`
URL → OAuth → pairing code), or both: each holds its own token against
the installation and reads the same registered workspaces. None of them
can write, execute, or commit — Codex stays the only hands.

## How it works

```text
Expand Down Expand Up @@ -42,8 +50,8 @@ Every Claude-facing capability is read-only. Workspaces are registered locally b
Requirements: Node.js ≥ 20, `git`, `cloudflared`, and Claude Web with custom connector support.

```bash
git clone https://github.com/willio/claude-to-codex.git
cd claude-to-codex
git clone https://github.com/willio/chat-to-codex.git
cd chat-to-codex
pnpm install
pnpm build
node bin/c2c.js install # systemwide install: ~/.c2c (app + state + launcher)
Expand All @@ -52,8 +60,8 @@ node bin/c2c.js install # systemwide install: ~/.c2c (app + state + launcher)
Install the Codex skill:

```bash
mkdir -p ~/.codex/skills/claude-to-codex
cp skill/SKILL.md ~/.codex/skills/claude-to-codex/
mkdir -p ~/.codex/skills/chat-to-codex
cp skill/SKILL.md ~/.codex/skills/chat-to-codex/
```

### Connect Claude — once
Expand Down Expand Up @@ -103,6 +111,8 @@ c2c broker tunnel choose --mode named --zone <domain>

A stable endpoint is recommended for the single connector you keep in Claude. Quick Tunnels remain useful for development and temporary testing.

Advanced: failover profiles. `--profile <name>` runs an isolated installation (own state, identity, connector) under `~/.c2c/profiles/<name>/` — e.g. a second Claude account on `c2c --profile backup broker start --tunnel`.

## The loop

```text
Expand Down Expand Up @@ -182,7 +192,7 @@ For compatibility, `doctor --json` exposes the canonical `connectorRepair` field

## Compatibility

Claude to Codex began from the ideas and architecture of `codex-with-chatgpt` and has since evolved into an independent implementation.
Chat to Codex began from the ideas and architecture of `codex-with-chatgpt` and has since evolved into an independent implementation.

The current architecture uses one installation-level Claude connector serving multiple locally registered Codex workspaces.

Expand Down Expand Up @@ -219,11 +229,11 @@ docs/ architecture, protocol, security and migration

## Credits

Claude to Codex builds on the original idea and architecture of [codex-with-chatgpt](https://github.com/XiaoDuoYa/codex-with-chatgpt) by [@XiaoDuoYa](https://github.com/XiaoDuoYa).
Chat to Codex builds on the original idea and architecture of [codex-with-chatgpt](https://github.com/XiaoDuoYa/codex-with-chatgpt) by [@XiaoDuoYa](https://github.com/XiaoDuoYa).

The project has since diverged into an independent Claude Web implementation, while preserving attribution to the upstream work and its MIT copyright in [LICENSE](LICENSE).

Claude to Codex is an unofficial community project and is not affiliated with or endorsed by Anthropic or OpenAI.
Chat to Codex is an unofficial community project and is not affiliated with or endorsed by Anthropic or OpenAI.

## License

Expand Down
8 changes: 4 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Claude to Codex (C2C)
# Chat to Codex (C2C)

[English](README.md) | [Bahasa Indonesia](README.id.md) | **简体中文**

> Claude 负责思考,Codex 负责执行。
> 把你的 AI 聊天会话带到 Codex。

## 这是什么

Expand Down Expand Up @@ -30,8 +30,8 @@ Claude 不会获得写文件、删除文件、执行任意命令或提交代码
## 安装

```bash
git clone https://github.com/willio/claude-to-codex.git ~/claude-to-codex
cd ~/claude-to-codex
git clone https://github.com/willio/chat-to-codex.git ~/chat-to-codex
cd ~/chat-to-codex
corepack pnpm install
corepack pnpm build
```
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

## Principles

- **Claude thinks. Codex works.** The bridge never re-implements a coding harness.
- **Bring your AI chat sessions to Codex.** The bridge never re-implements a coding harness.
- **Conversation = control plane**: tiny `[C2C]` state messages (< 1 KB).
- **MCP = data plane**: Claude pulls files/diffs/search results itself.
- **Read-only by design**: no write/exec tools exist in V1 at all.
Expand Down
4 changes: 2 additions & 2 deletions docs/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ GOAL:
Implement dark mode.

INSTRUCTION:
Inspect the connected workspace through Claude to Codex MCP.
Inspect the connected workspace through Chat to Codex MCP.
Create an implementation plan for Codex.
```

Expand Down Expand Up @@ -171,7 +171,7 @@ Codex owns execution.
You own high-level reasoning, planning and review.

You have access to the current local workspace through the
"Claude to Codex" MCP connector.
"Chat to Codex" MCP connector.

Rules:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "claude-to-codex",
"name": "chat-to-codex",
"version": "0.1.0",
"description": "Claude thinks. Codex works. Use Claude Web as the planning and review brain while keeping the Codex harness.",
"type": "module",
Expand Down
10 changes: 5 additions & 5 deletions skill/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
name: claude-to-codex
name: chat-to-codex
description: >
Use Claude Web as the planning and review brain for Codex coding sessions while Codex keeps execution ownership.
Bring your AI chat sessions (Claude Web, ChatGPT) to Codex as the planning and review brain while Codex keeps execution ownership.
---

# Claude to Codex
# Chat to Codex

Claude thinks. Codex works.
Bring your AI chat sessions to Codex.

## Core boundary

- Claude may read the current workspace only through the C2C MCP connector.
- The chat brain (Claude Web, ChatGPT) may read the current workspace only through the C2C MCP connector.
- Codex owns file edits, shell commands, git operations, tests, recovery, and all other mutation.
- Never add a general-purpose write or command-execution MCP tool.
- Never paste file contents, diffs, or long logs into Claude when Claude can retrieve them through MCP.
Expand Down
2 changes: 1 addition & 1 deletion src/broker/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import { WorkspaceRegistry, RegistryError } from "../workspaces/registry.js";
import { SessionRegistry } from "../workspaces/sessions.js";

export const CONNECTOR_DISPLAY_NAME = "Claude to Codex";
export const CONNECTOR_DISPLAY_NAME = "Chat to Codex";

export interface BrokerOptions {
/** Defaults to the standard C2C state dir. */
Expand Down
6 changes: 3 additions & 3 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ async function ensureBridgeAndTunnel(

program
.name("c2c")
.description(`${PRODUCT_NAME} — Claude thinks. Codex works.`)
.description(`${PRODUCT_NAME} — Bring your AI chat sessions to Codex.`)
.version(VERSION, "-v, --version")
.option("--profile <name>", "operate an isolated installation (~/.c2c/profiles/<name>)")
.hook("preAction", () => {
Expand Down Expand Up @@ -1162,7 +1162,7 @@ planCmd

program
.command("install")
.description("Install Claude to Codex systemwide under ~/.c2c: app, state migration, launcher, skill")
.description("Install Chat to Codex systemwide under ~/.c2c: app, state migration, launcher, skill")
.option("--json", "machine-readable output", false)
.action(async (opts: { json: boolean }) => {
try {
Expand Down Expand Up @@ -1214,7 +1214,7 @@ program
}

// 4. Codex skill
const skillDir = path.join(os.homedir(), ".codex", "skills", "claude-to-codex");
const skillDir = path.join(os.homedir(), ".codex", "skills", "chat-to-codex");
fs.mkdirSync(skillDir, { recursive: true, mode: 0o755 });
fs.copyFileSync(path.join(appRoot, "skill", "SKILL.md"), path.join(skillDir, "SKILL.md"));

Expand Down
2 changes: 1 addition & 1 deletion src/config/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const CHATGPT_PLUGINS_URL = CONNECTOR_SETTINGS_URL;
/** @deprecated Use CREATE_CONNECTOR_URL. */
export const CHATGPT_CREATE_CONNECTOR_URL = CREATE_CONNECTOR_URL;

export const DEFAULT_CONNECTOR_NAME = "Claude to Codex";
export const DEFAULT_CONNECTOR_NAME = "Chat to Codex";

export interface LastEndpoint {
workspaceId: string;
Expand Down
2 changes: 1 addition & 1 deletion src/config/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import os from "node:os";
import path from "node:path";
import fs from "node:fs";

// The directory name predates the product rename to "Claude to Codex (C2C)"
// The directory name predates the product rename to "Chat to Codex (C2C)"
// and is kept as an identifier so existing installations keep their state.
export const STATE_DIR_NAME = "codex-with-claude";
export const LEGACY_STATE_DIR_NAME = "codex-with-chatgpt";
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const VERSION = "0.1.0";
export const SERVICE_NAME = "c2c-bridge";
export const PRODUCT_NAME = "Claude to Codex";
export const PRODUCT_NAME = "Chat to Codex";
8 changes: 4 additions & 4 deletions tests/endpoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ describe("connectorAction", () => {

it("updates when the old address was reclaimed", () => {
expect(connectorAction("https://old.trycloudflare.com/mcp", "https://new.trycloudflare.com/mcp")).toBe("update");
expect(reclaimUserMessage("Claude to Codex")).toContain("Claude");
expect(reclaimUserMessage("Claude to Codex")).toContain("remove");
expect(reclaimUserMessage("Chat to Codex")).toContain("Claude");
expect(reclaimUserMessage("Chat to Codex")).toContain("remove");
});

it("does nothing without a next URL", () => {
Expand All @@ -40,7 +40,7 @@ describe("connectorNameFor", () => {
connectorNameFor({
workspaceName: "EchoMind",
workspaceId: "abc123abc123",
previousName: "Claude to Codex",
previousName: "Chat to Codex",
hadEndpointBefore: true,
})
).toBe(DEFAULT_CONNECTOR_NAME);
Expand All @@ -63,7 +63,7 @@ describe("connectorNameFor", () => {
workspaceId: "def456def456",
hadEndpointBefore: false,
})
).toBe("Claude to Codex · Landing");
).toBe("Chat to Codex · Landing");
});

it("points connector management at Claude Web", () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function git(dir: string, ...args: string[]): string {

export function makeGitRepo(dir: string): void {
git(dir, "init", "-b", "main");
write(dir, "hello.txt", "Hello from Claude to Codex!\n");
write(dir, "hello.txt", "Hello from Chat to Codex!\n");
write(dir, "src/index.ts", "export const answer = 42;\n");
git(dir, "add", ".");
git(dir, "commit", "-m", "initial commit");
Expand Down
2 changes: 1 addition & 1 deletion tests/mcp-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe("MCP tools over Streamable HTTP", () => {
it("read_file returns hello.txt", async () => {
const result = await client.callTool({ name: "read_file", arguments: { path: "hello.txt" } });
const file = jsonOf<{ content: string; totalLines: number }>(result);
expect(file.content).toContain("Hello from Claude to Codex!");
expect(file.content).toContain("Hello from Chat to Codex!");
});

it("read_file denies .env with ACCESS_DENIED_SENSITIVE_FILE and no content", async () => {
Expand Down
Loading