Skip to main content
Glama
README.md
**๐ŸŒ Language: ํ•œ๊ตญ์–ด | [English](README.en.md)**

# codex-gemini-mcp

AI ์—์ด์ „ํŠธ(Claude, Cursor ๋“ฑ)๊ฐ€ **OpenAI Codex CLI**์™€ **Google Gemini CLI**๋ฅผ MCP ๋„๊ตฌ๋กœ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”„๋ก์‹œ ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.

## ์ฃผ์š” ๊ธฐ๋Šฅ

- **`ask_codex`** โ€” ์—์ด์ „ํŠธ๊ฐ€ Codex์—๊ฒŒ ์ฝ”๋“œ ์ƒ์„ฑยท๋ฆฌํŒฉํ„ฐ๋งยท๋””๋ฒ„๊น…์„ ์š”์ฒญ
- **`ask_gemini`** โ€” ์—์ด์ „ํŠธ๊ฐ€ Gemini์—๊ฒŒ ๋ถ„์„ยท์š”์•ฝยท์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ์š”์ฒญ
- **๋ฐฑ๊ทธ๋ผ์šด๋“œ ์‹คํ–‰** โ€” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ๋Œ๋ฆฌ๊ณ , ์ƒํƒœ ํ™•์ธ(`check_job_status`)ยท๋Œ€๊ธฐ(`wait_for_job`)ยท์ค‘๋‹จ(`kill_job`)ยท๋ชฉ๋ก ์กฐํšŒ(`list_jobs`)๋กœ ๊ด€๋ฆฌ
- **๋ฉ€ํ‹ฐ๋ชจ๋ธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜** โ€” ํ•˜๋‚˜์˜ ์—์ด์ „ํŠธ๊ฐ€ Codex์™€ Gemini๋ฅผ ๋™์‹œ์— ํ™œ์šฉํ•˜์—ฌ ์ž‘์—… ๋ถ„๋‹ด ๊ฐ€๋Šฅ

ํ•˜๋‚˜์˜ ํŒจํ‚ค์ง€์—์„œ `codex-mcp`์™€ `gemini-mcp` ๋‘ ๊ฐœ์˜ MCP ์„œ๋ฒ„ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, stdio transport ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.


## Requirements

- Node.js 20+
- `codex` CLI ์„ค์น˜ (`npm i -g @openai/codex`)
- `gemini` CLI ์„ค์น˜ (`npm i -g @google/gemini-cli`)

MCP ์„œ๋ฒ„๋Š” ๊ฐ๊ฐ์˜ CLI๋ฅผ ๊ทธ๋Œ€๋กœ ์‹คํ–‰ํ•˜๋ฏ€๋กœ, ๋จผ์ € ๋กœ์ปฌ ํ„ฐ๋ฏธ๋„์—์„œ ๋กœ๊ทธ์ธ/์ธ์ฆ์ด ์™„๋ฃŒ๋˜์–ด `codex` / `gemini` CLI๋ฅผ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”.

## Install

npm์—์„œ ์„ค์น˜(๋ฐฐํฌ๋œ ๊ฒฝ์šฐ):

```bash
npm i -g @donghae0414/codex-gemini-mcp
```

์ „์—ญ ์„ค์น˜ ์—†์ด npx ์‚ฌ์šฉ:

```bash
npx -y -p @donghae0414/codex-gemini-mcp codex-mcp
npx -y -p @donghae0414/codex-gemini-mcp gemini-mcp
```

์†Œ์Šค์—์„œ ์„ค์น˜(๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ):

```bash
npm install
npm run build
npm link
```

## ํด๋ผ์ด์–ธํŠธ๋ณ„ MCP ์„ค์ • ์˜ˆ์‹œ

์ „์—ญ ์„ค์น˜ ๊ธฐ์ค€:

```json
{
  "mcpServers": {
    "codex-mcp": {
      "command": "codex-mcp",
      "args": []
    },
    "gemini-mcp": {
      "command": "gemini-mcp",
      "args": []
    }
  }
}
```

์ „์—ญ ์„ค์น˜ ์—†์ด npx ๊ธฐ์ค€:

```json
{
  "mcpServers": {
    "codex-mcp": {
      "command": "npx",
      "args": ["-y", "-p", "@donghae0414/codex-gemini-mcp", "codex-mcp"]
    },
    "gemini-mcp": {
      "command": "npx",
      "args": ["-y", "-p", "@donghae0414/codex-gemini-mcp", "gemini-mcp"]
    }
  }
}
```

opencode (`opencode.json`):

```json
{
  "mcp": {
    "codex-mcp": {
      "type": "local",
      "command": ["npx", "-y", "-p", "@donghae0414/codex-gemini-mcp", "codex-mcp"]
    },
    "gemini-mcp": {
      "type": "local",
      "command": ["npx", "-y", "-p", "@donghae0414/codex-gemini-mcp", "gemini-mcp"]
    }
  }
}
```

ํด๋ผ์ด์–ธํŠธ๋ณ„ ์„ค์ • ํŒŒ์ผ ์œ„์น˜(์ฐธ๊ณ ):

- Claude Code: ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ `.mcp.json` (ํ”„๋กœ์ ํŠธ๋ณ„) ๋˜๋Š” `~/.claude.json` (์ „์—ญ)
- Claude Desktop (macOS): `~/Library/Application Support/Claude/claude_desktop_config.json`
- Claude Desktop (Windows): `%APPDATA%\Claude\claude_desktop_config.json`
- Claude Desktop (Linux): `~/.config/Claude/claude_desktop_config.json`
- opencode: `~/.config/opencode/opencode.json`

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” ์…ธ ํ”„๋กœํ•„(`.zshrc` ๋“ฑ)์—์„œ ์ž๋™์œผ๋กœ ์ฃผ์ž…๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๊ฐ€๋Šฅํ•˜๋ฉด ์„ค์ • ํŒŒ์ผ์˜ `env` ๋ธ”๋ก์œผ๋กœ ์ „๋‹ฌํ•˜์„ธ์š”.

## Default Models

๊ธฐ๋ณธ ๋ชจ๋ธ์€ `src/config.ts`์— ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ overrideํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

| Provider | ๊ธฐ๋ณธ ๋ชจ๋ธ | ํ™˜๊ฒฝ ๋ณ€์ˆ˜ override |
|----------|-----------|-------------------|
| codex | `gpt-5.3-codex` | `MCP_CODEX_DEFAULT_MODEL` |
| gemini | `gemini-3-pro-preview` | `MCP_GEMINI_DEFAULT_MODEL` |

๋ชจ๋ธ ์„ ํƒ ์šฐ์„ ์ˆœ์œ„: **์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ `model`** > **ํ™˜๊ฒฝ ๋ณ€์ˆ˜** > **ํ•˜๋“œ์ฝ”๋”ฉ ๊ธฐ๋ณธ๊ฐ’**

## Local development

```bash
npm install
npm run build
npm run start:codex
npm run start:gemini
```

๊ฐœ๋ฐœ ๋ชจ๋“œ:

```bash
npm run dev:codex
npm run dev:gemini
```

## Runtime Files

- ๊ธฐ๋ณธ ๋Ÿฐํƒ€์ž„ ๋””๋ ‰ํ† ๋ฆฌ: `<cwd>/.codex-gemini-mcp/`
  - background job ์ƒํƒœ: `jobs/`
  - background job ์ž…์ถœ๋ ฅ(content): `prompts/`
  - ๊ตฌ์กฐํ™” ๋กœ๊น…(JSONL): `logs/`
- ๋Ÿฐํƒ€์ž„ ๊ฒฝ๋กœ override:
  - `MCP_RUNTIME_DIR`: ๋Ÿฐํƒ€์ž„ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ
  - `MCP_LOG_DIR`: ๋กœ๊ทธ ๋””๋ ‰ํ† ๋ฆฌ

์ •๋ฆฌ(๊ธฐ๋ณธ ๊ฒฝ๋กœ ์‚ฌ์šฉ ์‹œ):

```bash
rm -rf .codex-gemini-mcp
```

## Security / Privacy Notes

- `background: true`(๊ธฐ๋ณธ๊ฐ’) ์š”์ฒญ์€ `.codex-gemini-mcp/prompts/*content*.json`์— prompt/response๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
- ํ”„๋กฌํ”„ํŠธ์— ์‹œํฌ๋ฆฟ(ํ† ํฐ, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๊ฐœ์ธ ์ •๋ณด ๋“ฑ)์„ ๋„ฃ์œผ๋ฉด ๋กœ์ปฌ ํŒŒ์ผ์— ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ๋กœ๊น…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณธ๋ฌธ ๋ฏธ์ €์žฅ์ด์ง€๋งŒ, ์•„๋ž˜ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ผœ๋ฉด ๋กœ๊ทธ์— ํ…์ŠคํŠธ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
  - `MCP_LOG_PREVIEW=1`
  - `MCP_LOG_FULL_TEXT=1`

## Tool Schemas

### ask_codex

- `prompt` (string, required)
- `model` (string, optional)
- `model`์€ `[A-Za-z0-9][A-Za-z0-9._:-]*` ํŒจํ„ด(์ตœ๋Œ€ 128์ž)๋งŒ ํ—ˆ์šฉ
- `working_directory` (string, optional): CLI ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰ ๋””๋ ‰ํ† ๋ฆฌ(cwd)
- `background` (boolean, optional, default `true`)
- `reasoning_effort` (string, optional: `minimal` | `low` | `medium` | `high` | `xhigh`)

### ask_gemini

- `prompt` (string, required)
- `model` (string, optional)
- `model`์€ `[A-Za-z0-9][A-Za-z0-9._:-]*` ํŒจํ„ด(์ตœ๋Œ€ 128์ž)๋งŒ ํ—ˆ์šฉ
- `working_directory` (string, optional): CLI ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰ ๋””๋ ‰ํ† ๋ฆฌ(cwd)
- `background` (boolean, optional, default `true`)

### wait_for_job

- `job_id` (string, required, 8์ž๋ฆฌ hex)
- `timeout_ms` (number, optional, default 3600000, max 3600000; 3600000 ์ดˆ๊ณผ ๊ฐ’์€ 3600000์œผ๋กœ cap)

### check_job_status

- `job_id` (string, required, 8์ž๋ฆฌ hex)

### kill_job

- `job_id` (string, required, 8์ž๋ฆฌ hex)
- `signal` (string, optional: `SIGTERM` | `SIGINT`, default `SIGTERM`)

### list_jobs

- `status_filter` (string, optional: `active`(spawned/running) | `completed` | `failed`(failed/timeout) | `all`, default `active`)
- `limit` (number, optional, default `50`)

## Runtime Notes

- `ask_codex`: `codex exec --ephemeral` ํ˜ธ์ถœ (`reasoning_effort` ์ง€์ • ์‹œ `-c model_reasoning_effort=...` ์ถ”๊ฐ€)
- `ask_gemini`: `gemini --prompt <text>` ํ˜ธ์ถœ
- `ask_*`๋Š” `background` ๋ฏธ์ง€์ • ์‹œ ๊ธฐ๋ณธ `true`๋กœ ์‹คํ–‰
- `background: true` ํ˜ธ์ถœ ์‹œ `.codex-gemini-mcp/jobs`, `.codex-gemini-mcp/prompts`์— ์ƒํƒœ/์ž…์ถœ๋ ฅ(content) ํŒŒ์ผ ์ €์žฅ
- ๊ตฌ์กฐํ™” ๋กœ๊น…(JSONL): `.codex-gemini-mcp/logs/mcp-YYYY-MM-DD.jsonl`
  - ๊ธฐ๋ณธ: ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ์ €์žฅ (๋ณธ๋ฌธ ๋ฏธ์ €์žฅ)
  - `MCP_LOG_PREVIEW=1`: preview ์ €์žฅ
  - `MCP_LOG_FULL_TEXT=1`: full text ์ €์žฅ
  - ๋กœ๊ทธ ์ด๋ฒคํŠธ๋Š” JSONL ํŒŒ์ผ ์ €์žฅ๊ณผ ํ•จ๊ป˜ `stderr`์—๋„ ๋ฏธ๋Ÿฌ๋ง๋จ
- ๋ชจ๋ธ ์„ ํƒ ์šฐ์„ ์ˆœ์œ„: `request.model > env default > hardcoded default`
  - codex env: `MCP_CODEX_DEFAULT_MODEL` (๊ธฐ๋ณธ๊ฐ’: `gpt-5.3-codex`)
  - gemini env: `MCP_GEMINI_DEFAULT_MODEL` (๊ธฐ๋ณธ๊ฐ’: `gemini-3-pro-preview`)
- CLI timeout ๊ธฐ๋ณธ๊ฐ’์€ `MCP_CLI_TIMEOUT_MS` ๋˜๋Š” 3600000ms(60๋ถ„)
- `stdout + stderr` ํ•ฉ์‚ฐ ์ถœ๋ ฅ์ด `MCP_MAX_OUTPUT_BYTES`๋ฅผ ๋„˜์œผ๋ฉด `CLI_OUTPUT_LIMIT_EXCEEDED`๋กœ ์ข…๋ฃŒ
- ์ถœ๋ ฅ์€ ์•ˆ์ •์ ์ธ ํ…์ŠคํŠธ ํŒŒ์ดํ”„๋ฅผ ์œ„ํ•ด ์ƒ‰์ƒ/TTY๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค (`NO_COLOR=1`, `FORCE_COLOR=0`, `TERM=dumb`)

## Logging by `background`

- ๊ณตํ†ต(`background` true/false ๋ชจ๋‘): JSONL์— `request` ์ด๋ฒคํŠธ์™€ terminal(`response` ๋˜๋Š” `error`) ์ด๋ฒคํŠธ๊ฐ€ ๊ธฐ๋ก๋˜๊ณ , `request_id`๋กœ 1์ฐจ ์ถ”์  ๊ฐ€๋Šฅ
- `background: false` (foreground): ๋กœ๊ทธ ์ด๋ฒคํŠธ์— `job_id`๊ฐ€ ์—†์Œ. `jobs/`, `prompts/` ํŒŒ์ผ์€ ์ƒ์„ฑ๋˜์ง€ ์•Š์Œ
- `background: true` (background):
  - MCP ์‘๋‹ต์— `jobId`, `contentFile`, `statusFile` ๋ฐ˜ํ™˜
  - JSONL `response`/`error` ์ด๋ฒคํŠธ์— `job_id` ๊ธฐ๋ก
  - `jobs/*status*.json`, `prompts/*content*.json`์— `requestId` ์ €์žฅ
  - ๋”ฐ๋ผ์„œ `request_id` <-> `job_id`๋ฅผ ๋กœ๊ทธ/์ƒํƒœํŒŒ์ผ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋งคํ•‘ ๊ฐ€๋Šฅ

## Environment Variables

- `MCP_CODEX_DEFAULT_MODEL`: codex ๊ธฐ๋ณธ ๋ชจ๋ธ
- `MCP_GEMINI_DEFAULT_MODEL`: gemini ๊ธฐ๋ณธ ๋ชจ๋ธ
- `MCP_CLI_TIMEOUT_MS`: ๊ธฐ๋ณธ CLI timeout(ms)
- `MCP_MAX_OUTPUT_BYTES`: ์ตœ๋Œ€ ์ถœ๋ ฅ ๋ฐ”์ดํŠธ(cap, ๊ธฐ๋ณธ 1048576 = 1MiB)
- `MCP_RUNTIME_DIR`: ๋Ÿฐํƒ€์ž„ ํŒŒ์ผ ๊ธฐ๋ณธ ๋ฃจํŠธ(`.codex-gemini-mcp`)
- `MCP_LOG_DIR`: ๋กœ๊ทธ ๊ฒฝ๋กœ override
- `MCP_LOG_PREVIEW`: ๋กœ๊ทธ preview ์ €์žฅ ์—ฌ๋ถ€ (`1`์ด๋ฉด ํ™œ์„ฑํ™”)
- `MCP_LOG_FULL_TEXT`: ์ „์ฒด ํ…์ŠคํŠธ ๋กœ๊ทธ ์—ฌ๋ถ€ (`1`์ด๋ฉด ํ™œ์„ฑํ™”)

## Current Status

- ๋ฐ”์ด๋„ˆ๋ฆฌ ์—”ํŠธ๋ฆฌ: `codex-mcp`, `gemini-mcp`
- ๊ฒ€์ฆ ์™„๋ฃŒ: `ask_codex`, `ask_gemini` foreground/background ์‹คํ˜ธ์ถœ ์„ฑ๊ณต
- ๊ฒ€์ฆ ์™„๋ฃŒ: `wait_for_job`, `check_job_status`, `kill_job`, `list_jobs` ์‹คํ˜ธ์ถœ ์„ฑ๊ณต
- ๊ตฌํ˜„ ์™„๋ฃŒ: ๊ตฌ์กฐํ™” ๋กœ๊น…(Phase D)
- ๊ตฌํ˜„ ์™„๋ฃŒ: output cap ๊ฐ•์ œ + model regex validation

## Scope (deliberately minimal)

์ด ์ƒ˜ํ”Œ์—๋Š” ์•„๋ž˜ ๊ธฐ๋Šฅ์ด ์—†์Šต๋‹ˆ๋‹ค:

- ๋ชจ๋ธ fallback chain
- standalone bridge ๋ฒˆ๋“ค๋ง

## Troubleshooting

- `CLI_NOT_FOUND`:
  - `codex` ๋˜๋Š” `gemini` CLI๊ฐ€ PATH์— ์—†์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  - `npm i -g @openai/codex` / `npm i -g @google/gemini-cli` ์„ค์น˜ ํ›„ ์žฌ์‹œ๋„ํ•˜์„ธ์š”.
- output์ด ์ž˜๋ฆผ(`CLI_OUTPUT_LIMIT_EXCEEDED`):
  - `MCP_MAX_OUTPUT_BYTES`๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜, ํ”„๋กฌํ”„ํŠธ/์ถœ๋ ฅ์„ ์ค„์ด์„ธ์š”.
- background ํŒŒ์ผ์ด ๋„ˆ๋ฌด ์Œ“์ž„:
  - ํ•„์š” ์‹œ `.codex-gemini-mcp/`๋ฅผ ์ง์ ‘ ์ •๋ฆฌํ•˜์„ธ์š”.

## Acknowledgements

์ด ํ”„๋กœ์ ํŠธ๋Š” [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode)์— ๊ตฌํ˜„๋œ Codex/Gemini MCP ์„œ๋ฒ„๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์žฌ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

## License

[MIT](LICENSE)

TDQS

B3/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of ambiguity or overlap between tools. The tool's purpose is clearly defined as sending prompts to a local Codex CLI, making it impossible for an agent to misselect between non-existent alternatives.

Naming Consistency5/5

A single tool inherently exhibits perfect naming consistency, as there are no other tools to compare it against. The name 'ask_codex' follows a clear verb_noun pattern and stands alone without any conflicting conventions.

Tool Count2/5

One tool is too few for a server named 'Codex Gemini MCP', which suggests a broader scope or multiple functionalities. A single tool feels thin and limited, failing to provide a comprehensive surface for interacting with a Codex CLI beyond basic prompting.

Completeness2/5

The tool surface is severely incomplete for the implied domain of a Codex CLI interface. While 'ask_codex' covers basic prompting, there are obvious gaps such as configuration management, session handling, or advanced querying capabilities that would be expected in a more robust integration.

Maintenance

ActivityInactive
ResponsivenessNo issues