@cpujia/codex-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +24 -0
- package/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/codex-client.d.ts +15 -0
- package/dist/codex-client.js +139 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +181 -0
- package/dist/tools.d.ts +131 -0
- package/dist/tools.js +112 -0
- package/package.json +57 -0
package/.env.example
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Codex API Configuration
|
|
2
|
+
CODEX_API_BASE_URL=https://your-codex-service.com/v1
|
|
3
|
+
CODEX_API_KEY=your-api-key-here
|
|
4
|
+
|
|
5
|
+
# Model Configuration
|
|
6
|
+
# Available models:
|
|
7
|
+
# - gpt-5.3-codex (最强,推荐)
|
|
8
|
+
# - gpt-5.3-codex-spark (超快速,实时编码)
|
|
9
|
+
# - gpt-5.2-codex (稳定版)
|
|
10
|
+
CODEX_MODEL=gpt-5.3-codex
|
|
11
|
+
|
|
12
|
+
# Reasoning Effort (推理强度)
|
|
13
|
+
# Available values: none, minimal, low, medium, high, xhigh
|
|
14
|
+
# - xhigh: 最强推理能力,适合复杂算法和架构设计
|
|
15
|
+
# - high: 高推理能力,适合一般复杂任务
|
|
16
|
+
# - medium: 中等推理,平衡速度和质量
|
|
17
|
+
# - low: 快速响应,简单任务
|
|
18
|
+
CODEX_REASONING_EFFORT=xhigh
|
|
19
|
+
|
|
20
|
+
# Optional: Timeout settings (milliseconds)
|
|
21
|
+
CODEX_TIMEOUT=60000
|
|
22
|
+
|
|
23
|
+
# Optional: Max tokens
|
|
24
|
+
CODEX_MAX_TOKENS=4096
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CPU-JIA
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Codex MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
MCP Server for integrating OpenAI Codex `/v1/responses` API with Claude Code. Enables Claude Code to leverage GPT-5.3-Codex's powerful code generation capabilities.
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
- 🚀 **GPT-5.3-Codex Support**: Latest and most powerful Codex model
|
|
12
|
+
- 🧠 **Reasoning Control**: Configurable reasoning effort (xhigh, high, medium, low)
|
|
13
|
+
- 🛠️ **5 Professional Tools**: Generate, edit, explain, fix, and refactor code
|
|
14
|
+
- 📡 **Native `/v1/responses` API**: Full protocol support with streaming
|
|
15
|
+
- 🔒 **Type-Safe**: Complete TypeScript type definitions
|
|
16
|
+
- ⚡ **Production-Ready**: Error handling, timeouts, and retry mechanisms
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
### Option A: Install via npm (Recommended)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Global installation
|
|
24
|
+
npm install -g @cpujia/codex-mcp-server
|
|
25
|
+
|
|
26
|
+
# Add to Claude Code
|
|
27
|
+
claude mcp add --scope user codex -- codex-mcp
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Option B: Install from source
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Clone the repository
|
|
34
|
+
git clone https://github.com/CPU-JIA/codex-mcp-server.git
|
|
35
|
+
cd codex-mcp-server
|
|
36
|
+
|
|
37
|
+
# Install dependencies
|
|
38
|
+
npm install
|
|
39
|
+
|
|
40
|
+
# Configure environment
|
|
41
|
+
cp .env.example .env
|
|
42
|
+
# Edit .env with your Codex API credentials
|
|
43
|
+
|
|
44
|
+
# Build
|
|
45
|
+
npm run build
|
|
46
|
+
|
|
47
|
+
# Add to Claude Code
|
|
48
|
+
claude mcp add --scope user codex -- node /absolute/path/to/codex-mcp-server/dist/index.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Option C: Use with npx (No installation required)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Add to Claude Code using npx
|
|
55
|
+
claude mcp add --scope user codex -- npx @cpujia/codex-mcp-server
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Detailed Installation
|
|
59
|
+
|
|
60
|
+
See [QUICKSTART.md](QUICKSTART.md) for step-by-step instructions.
|
|
61
|
+
|
|
62
|
+
## 🔧 Configuration
|
|
63
|
+
|
|
64
|
+
### Environment Variables
|
|
65
|
+
|
|
66
|
+
```env
|
|
67
|
+
CODEX_API_BASE_URL=https://your-codex-service.com/v1
|
|
68
|
+
CODEX_API_KEY=your-api-key-here
|
|
69
|
+
CODEX_MODEL=gpt-5.3-codex
|
|
70
|
+
CODEX_REASONING_EFFORT=xhigh
|
|
71
|
+
CODEX_TIMEOUT=60000
|
|
72
|
+
CODEX_MAX_TOKENS=4096
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Claude Code Integration
|
|
76
|
+
|
|
77
|
+
**Option A: Command Line (Recommended)**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
claude mcp add --scope user codex -- node /path/to/codex-mcp-server/dist/index.js
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Option B: Manual Configuration**
|
|
84
|
+
|
|
85
|
+
Edit `%APPDATA%\Claude\mcp.json` (Windows) or `~/.config/claude/mcp.json` (Linux/Mac):
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"codex": {
|
|
91
|
+
"command": "node",
|
|
92
|
+
"args": ["/absolute/path/to/codex-mcp-server/dist/index.js"],
|
|
93
|
+
"env": {
|
|
94
|
+
"CODEX_API_BASE_URL": "https://your-codex-service.com/v1",
|
|
95
|
+
"CODEX_API_KEY": "your-api-key-here",
|
|
96
|
+
"CODEX_MODEL": "gpt-5.3-codex",
|
|
97
|
+
"CODEX_REASONING_EFFORT": "xhigh"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
See [CLAUDE_CODE_CONFIG.md](CLAUDE_CODE_CONFIG.md) for detailed configuration options.
|
|
105
|
+
|
|
106
|
+
## 🛠️ Available Tools
|
|
107
|
+
|
|
108
|
+
| Tool | Description | Use Case |
|
|
109
|
+
| ---------------- | ------------------------------------------ | ---------------------------------------- |
|
|
110
|
+
| `codex_generate` | Generate new code from natural language | Create functions, components, algorithms |
|
|
111
|
+
| `codex_edit` | Modify existing code based on instructions | Add features, refactor, optimize |
|
|
112
|
+
| `codex_explain` | Explain code logic and complexity | Understand algorithms, review code |
|
|
113
|
+
| `codex_fix` | Fix bugs based on error messages | Debug, resolve issues |
|
|
114
|
+
| `codex_refactor` | Improve code quality and structure | Simplify logic, enhance readability |
|
|
115
|
+
|
|
116
|
+
### Example Usage
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
Claude, use codex_generate to create a TypeScript function that implements a binary search tree
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
See [EXAMPLES.md](EXAMPLES.md) for more detailed examples.
|
|
123
|
+
|
|
124
|
+
## 🎯 Reasoning Effort Levels
|
|
125
|
+
|
|
126
|
+
| Level | Speed | Quality | Best For |
|
|
127
|
+
| -------- | ------- | ------- | --------------------------------------- |
|
|
128
|
+
| `xhigh` | Slowest | Highest | Complex algorithms, architecture design |
|
|
129
|
+
| `high` | Slow | High | General complex tasks, refactoring |
|
|
130
|
+
| `medium` | Medium | Medium | Daily development, balanced use |
|
|
131
|
+
| `low` | Fast | Basic | Simple tasks, code completion |
|
|
132
|
+
|
|
133
|
+
See [GPT-5.3-CODEX-CONFIG.md](GPT-5.3-CODEX-CONFIG.md) for detailed reasoning configuration.
|
|
134
|
+
|
|
135
|
+
## 📚 Documentation
|
|
136
|
+
|
|
137
|
+
- [QUICKSTART.md](QUICKSTART.md) - Quick installation guide
|
|
138
|
+
- [EXAMPLES.md](EXAMPLES.md) - Detailed usage examples
|
|
139
|
+
- [CLAUDE_CODE_CONFIG.md](CLAUDE_CODE_CONFIG.md) - Claude Code integration
|
|
140
|
+
- [GPT-5.3-CODEX-CONFIG.md](GPT-5.3-CODEX-CONFIG.md) - GPT-5.3-Codex configuration
|
|
141
|
+
|
|
142
|
+
## 🏗️ Architecture
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Claude Code (Orchestrator)
|
|
146
|
+
↓
|
|
147
|
+
MCP Server (Protocol Bridge)
|
|
148
|
+
↓
|
|
149
|
+
Codex API (/v1/responses)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Separation of Concerns:**
|
|
153
|
+
|
|
154
|
+
- **Claude Code**: Requirement understanding, file operations, command execution, tool orchestration
|
|
155
|
+
- **Codex**: Code generation, editing, analysis (with powerful reasoning)
|
|
156
|
+
|
|
157
|
+
## 🔍 Troubleshooting
|
|
158
|
+
|
|
159
|
+
### "Cannot find module"
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
cd /path/to/codex-mcp-server
|
|
163
|
+
npm run build
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### "CODEX_API_BASE_URL must be set"
|
|
167
|
+
|
|
168
|
+
Check your `.env` file or Claude Code configuration `env` fields.
|
|
169
|
+
|
|
170
|
+
### Claude Code doesn't see the tools
|
|
171
|
+
|
|
172
|
+
1. Verify the configuration file path is correct
|
|
173
|
+
2. Restart Claude Code
|
|
174
|
+
3. Check Claude Code logs for errors
|
|
175
|
+
|
|
176
|
+
### API call failures
|
|
177
|
+
|
|
178
|
+
1. Test your Codex API endpoint:
|
|
179
|
+
```bash
|
|
180
|
+
curl -X POST https://your-codex-service.com/v1/responses \
|
|
181
|
+
-H "Authorization: Bearer your-api-key" \
|
|
182
|
+
-H "Content-Type: application/json" \
|
|
183
|
+
-d '{"model":"gpt-5.3-codex","input":[{"role":"user","content":"test"}]}'
|
|
184
|
+
```
|
|
185
|
+
2. Verify API key is valid
|
|
186
|
+
3. Check network connectivity
|
|
187
|
+
|
|
188
|
+
## 🤝 Contributing
|
|
189
|
+
|
|
190
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
191
|
+
|
|
192
|
+
## 📄 License
|
|
193
|
+
|
|
194
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
195
|
+
|
|
196
|
+
## 🙏 Acknowledgments
|
|
197
|
+
|
|
198
|
+
- [Anthropic](https://www.anthropic.com/) for Claude Code and MCP
|
|
199
|
+
- [OpenAI](https://openai.com/) for GPT-5.3-Codex
|
|
200
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) community
|
|
201
|
+
|
|
202
|
+
## 📞 Support
|
|
203
|
+
|
|
204
|
+
- **Issues**: [GitHub Issues](https://github.com/CPU-JIA/codex-mcp-server/issues)
|
|
205
|
+
- **Documentation**: See docs in this repository
|
|
206
|
+
- **Community**: [MCP Discord](https://discord.gg/modelcontextprotocol)
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
**Enjoy the powerful combination of Claude + Codex!** 🚀
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface CodexClientConfig {
|
|
2
|
+
baseURL: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
model: string;
|
|
5
|
+
timeout: number;
|
|
6
|
+
maxTokens: number;
|
|
7
|
+
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
8
|
+
}
|
|
9
|
+
export declare class CodexClient {
|
|
10
|
+
private config;
|
|
11
|
+
constructor(config: CodexClientConfig);
|
|
12
|
+
generate(input: string): Promise<string>;
|
|
13
|
+
generateStream(input: string, onChunk: (text: string) => void): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export class CodexClient {
|
|
2
|
+
config;
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.config = config;
|
|
5
|
+
}
|
|
6
|
+
async generate(input) {
|
|
7
|
+
const controller = new AbortController();
|
|
8
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
9
|
+
try {
|
|
10
|
+
const requestBody = {
|
|
11
|
+
model: this.config.model,
|
|
12
|
+
input: [
|
|
13
|
+
{
|
|
14
|
+
role: "user",
|
|
15
|
+
content: input,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
max_output_tokens: this.config.maxTokens,
|
|
19
|
+
};
|
|
20
|
+
if (this.config.reasoningEffort) {
|
|
21
|
+
requestBody.reasoning = {
|
|
22
|
+
effort: this.config.reasoningEffort,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const response = await fetch(`${this.config.baseURL}/responses`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(requestBody),
|
|
32
|
+
signal: controller.signal,
|
|
33
|
+
});
|
|
34
|
+
clearTimeout(timeoutId);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const errorText = await response.text();
|
|
37
|
+
throw new Error(`Codex API error (${response.status}): ${errorText}`);
|
|
38
|
+
}
|
|
39
|
+
const data = (await response.json());
|
|
40
|
+
if (data.status !== "completed") {
|
|
41
|
+
throw new Error(`Unexpected response status: ${data.status}`);
|
|
42
|
+
}
|
|
43
|
+
const textContent = data.content.find((c) => c.type === "output_text");
|
|
44
|
+
if (!textContent?.text) {
|
|
45
|
+
throw new Error("No text content in response");
|
|
46
|
+
}
|
|
47
|
+
return textContent.text;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
clearTimeout(timeoutId);
|
|
51
|
+
if (error instanceof Error) {
|
|
52
|
+
if (error.name === "AbortError") {
|
|
53
|
+
throw new Error(`Request timeout after ${this.config.timeout}ms`);
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`Unknown error: ${String(error)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async generateStream(input, onChunk) {
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
63
|
+
try {
|
|
64
|
+
const requestBody = {
|
|
65
|
+
model: this.config.model,
|
|
66
|
+
input: [
|
|
67
|
+
{
|
|
68
|
+
role: "user",
|
|
69
|
+
content: input,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
max_output_tokens: this.config.maxTokens,
|
|
73
|
+
stream: true,
|
|
74
|
+
};
|
|
75
|
+
if (this.config.reasoningEffort) {
|
|
76
|
+
requestBody.reasoning = {
|
|
77
|
+
effort: this.config.reasoningEffort,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const response = await fetch(`${this.config.baseURL}/responses`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: {
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(requestBody),
|
|
87
|
+
signal: controller.signal,
|
|
88
|
+
});
|
|
89
|
+
clearTimeout(timeoutId);
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const errorText = await response.text();
|
|
92
|
+
throw new Error(`Codex API error (${response.status}): ${errorText}`);
|
|
93
|
+
}
|
|
94
|
+
if (!response.body) {
|
|
95
|
+
throw new Error("No response body");
|
|
96
|
+
}
|
|
97
|
+
const reader = response.body.getReader();
|
|
98
|
+
const decoder = new TextDecoder();
|
|
99
|
+
let buffer = "";
|
|
100
|
+
while (true) {
|
|
101
|
+
const { done, value } = await reader.read();
|
|
102
|
+
if (done)
|
|
103
|
+
break;
|
|
104
|
+
buffer += decoder.decode(value, { stream: true });
|
|
105
|
+
const lines = buffer.split("\n");
|
|
106
|
+
buffer = lines.pop() || "";
|
|
107
|
+
for (const line of lines) {
|
|
108
|
+
if (!line.trim() || line.startsWith(":"))
|
|
109
|
+
continue;
|
|
110
|
+
if (line.startsWith("data: ")) {
|
|
111
|
+
const data = line.slice(6);
|
|
112
|
+
if (data === "[DONE]") {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const parsed = JSON.parse(data);
|
|
117
|
+
if (parsed.type === "response.output_text.delta") {
|
|
118
|
+
onChunk(parsed.delta || "");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error("Failed to parse SSE data:", e);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
clearTimeout(timeoutId);
|
|
130
|
+
if (error instanceof Error) {
|
|
131
|
+
if (error.name === "AbortError") {
|
|
132
|
+
throw new Error(`Request timeout after ${this.config.timeout}ms`);
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
throw new Error(`Unknown error: ${String(error)}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { CodexClient } from "./codex-client.js";
|
|
6
|
+
import { tools } from "./tools.js";
|
|
7
|
+
const CODEX_API_BASE_URL = process.env.CODEX_API_BASE_URL;
|
|
8
|
+
const CODEX_API_KEY = process.env.CODEX_API_KEY;
|
|
9
|
+
const CODEX_MODEL = process.env.CODEX_MODEL || "gpt-5.3-codex";
|
|
10
|
+
const CODEX_REASONING_EFFORT = process.env.CODEX_REASONING_EFFORT;
|
|
11
|
+
if (!CODEX_API_BASE_URL || !CODEX_API_KEY) {
|
|
12
|
+
console.error("Error: CODEX_API_BASE_URL and CODEX_API_KEY must be set");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const codexClient = new CodexClient({
|
|
16
|
+
baseURL: CODEX_API_BASE_URL,
|
|
17
|
+
apiKey: CODEX_API_KEY,
|
|
18
|
+
model: CODEX_MODEL,
|
|
19
|
+
timeout: parseInt(process.env.CODEX_TIMEOUT || "60000"),
|
|
20
|
+
maxTokens: parseInt(process.env.CODEX_MAX_TOKENS || "4096"),
|
|
21
|
+
reasoningEffort: CODEX_REASONING_EFFORT,
|
|
22
|
+
});
|
|
23
|
+
const server = new Server({
|
|
24
|
+
name: "codex-mcp-server",
|
|
25
|
+
version: "1.0.0",
|
|
26
|
+
}, {
|
|
27
|
+
capabilities: {
|
|
28
|
+
tools: {},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
32
|
+
return { tools };
|
|
33
|
+
});
|
|
34
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
35
|
+
const { name, arguments: args } = request.params;
|
|
36
|
+
try {
|
|
37
|
+
switch (name) {
|
|
38
|
+
case "codex_generate": {
|
|
39
|
+
const { prompt, language, context } = args;
|
|
40
|
+
const input = buildGenerateInput(prompt, language, context);
|
|
41
|
+
const result = await codexClient.generate(input);
|
|
42
|
+
return {
|
|
43
|
+
content: [
|
|
44
|
+
{
|
|
45
|
+
type: "text",
|
|
46
|
+
text: result,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
case "codex_edit": {
|
|
52
|
+
const { code, instruction, language } = args;
|
|
53
|
+
const input = buildEditInput(code, instruction, language);
|
|
54
|
+
const result = await codexClient.generate(input);
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: result,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
case "codex_explain": {
|
|
65
|
+
const { code, language, focus } = args;
|
|
66
|
+
const input = buildExplainInput(code, language, focus);
|
|
67
|
+
const result = await codexClient.generate(input);
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: "text",
|
|
72
|
+
text: result,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
case "codex_fix": {
|
|
78
|
+
const { code, error, language } = args;
|
|
79
|
+
const input = buildFixInput(code, error, language);
|
|
80
|
+
const result = await codexClient.generate(input);
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: result,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
case "codex_refactor": {
|
|
91
|
+
const { code, goal, language } = args;
|
|
92
|
+
const input = buildRefactorInput(code, goal, language);
|
|
93
|
+
const result = await codexClient.generate(input);
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: result,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
default:
|
|
104
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
109
|
+
return {
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: "text",
|
|
113
|
+
text: `Error: ${errorMessage}`,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
function buildGenerateInput(prompt, language, context) {
|
|
121
|
+
let input = "";
|
|
122
|
+
if (language) {
|
|
123
|
+
input += `Language: ${language}\n\n`;
|
|
124
|
+
}
|
|
125
|
+
if (context) {
|
|
126
|
+
input += `Context:\n${context}\n\n`;
|
|
127
|
+
}
|
|
128
|
+
input += `Task: ${prompt}\n\nGenerate the code:`;
|
|
129
|
+
return input;
|
|
130
|
+
}
|
|
131
|
+
function buildEditInput(code, instruction, language) {
|
|
132
|
+
let input = "";
|
|
133
|
+
if (language) {
|
|
134
|
+
input += `Language: ${language}\n\n`;
|
|
135
|
+
}
|
|
136
|
+
input += `Original code:\n\`\`\`\n${code}\n\`\`\`\n\n`;
|
|
137
|
+
input += `Instruction: ${instruction}\n\n`;
|
|
138
|
+
input += `Modified code:`;
|
|
139
|
+
return input;
|
|
140
|
+
}
|
|
141
|
+
function buildExplainInput(code, language, focus) {
|
|
142
|
+
let input = "";
|
|
143
|
+
if (language) {
|
|
144
|
+
input += `Language: ${language}\n\n`;
|
|
145
|
+
}
|
|
146
|
+
input += `Code:\n\`\`\`\n${code}\n\`\`\`\n\n`;
|
|
147
|
+
if (focus) {
|
|
148
|
+
input += `Focus on: ${focus}\n\n`;
|
|
149
|
+
}
|
|
150
|
+
input += `Explain this code:`;
|
|
151
|
+
return input;
|
|
152
|
+
}
|
|
153
|
+
function buildFixInput(code, error, language) {
|
|
154
|
+
let input = "";
|
|
155
|
+
if (language) {
|
|
156
|
+
input += `Language: ${language}\n\n`;
|
|
157
|
+
}
|
|
158
|
+
input += `Code with error:\n\`\`\`\n${code}\n\`\`\`\n\n`;
|
|
159
|
+
input += `Error message:\n${error}\n\n`;
|
|
160
|
+
input += `Fixed code:`;
|
|
161
|
+
return input;
|
|
162
|
+
}
|
|
163
|
+
function buildRefactorInput(code, goal, language) {
|
|
164
|
+
let input = "";
|
|
165
|
+
if (language) {
|
|
166
|
+
input += `Language: ${language}\n\n`;
|
|
167
|
+
}
|
|
168
|
+
input += `Original code:\n\`\`\`\n${code}\n\`\`\`\n\n`;
|
|
169
|
+
input += `Refactoring goal: ${goal}\n\n`;
|
|
170
|
+
input += `Refactored code:`;
|
|
171
|
+
return input;
|
|
172
|
+
}
|
|
173
|
+
async function main() {
|
|
174
|
+
const transport = new StdioServerTransport();
|
|
175
|
+
await server.connect(transport);
|
|
176
|
+
console.error("Codex MCP Server running on stdio");
|
|
177
|
+
}
|
|
178
|
+
main().catch((error) => {
|
|
179
|
+
console.error("Fatal error:", error);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export declare const tools: ({
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: string;
|
|
6
|
+
properties: {
|
|
7
|
+
prompt: {
|
|
8
|
+
type: string;
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
language: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
context: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
code?: undefined;
|
|
20
|
+
instruction?: undefined;
|
|
21
|
+
focus?: undefined;
|
|
22
|
+
error?: undefined;
|
|
23
|
+
goal?: undefined;
|
|
24
|
+
};
|
|
25
|
+
required: string[];
|
|
26
|
+
};
|
|
27
|
+
} | {
|
|
28
|
+
name: string;
|
|
29
|
+
description: string;
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: string;
|
|
32
|
+
properties: {
|
|
33
|
+
code: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
instruction: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
language: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
prompt?: undefined;
|
|
46
|
+
context?: undefined;
|
|
47
|
+
focus?: undefined;
|
|
48
|
+
error?: undefined;
|
|
49
|
+
goal?: undefined;
|
|
50
|
+
};
|
|
51
|
+
required: string[];
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: string;
|
|
58
|
+
properties: {
|
|
59
|
+
code: {
|
|
60
|
+
type: string;
|
|
61
|
+
description: string;
|
|
62
|
+
};
|
|
63
|
+
language: {
|
|
64
|
+
type: string;
|
|
65
|
+
description: string;
|
|
66
|
+
};
|
|
67
|
+
focus: {
|
|
68
|
+
type: string;
|
|
69
|
+
description: string;
|
|
70
|
+
};
|
|
71
|
+
prompt?: undefined;
|
|
72
|
+
context?: undefined;
|
|
73
|
+
instruction?: undefined;
|
|
74
|
+
error?: undefined;
|
|
75
|
+
goal?: undefined;
|
|
76
|
+
};
|
|
77
|
+
required: string[];
|
|
78
|
+
};
|
|
79
|
+
} | {
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: string;
|
|
84
|
+
properties: {
|
|
85
|
+
code: {
|
|
86
|
+
type: string;
|
|
87
|
+
description: string;
|
|
88
|
+
};
|
|
89
|
+
error: {
|
|
90
|
+
type: string;
|
|
91
|
+
description: string;
|
|
92
|
+
};
|
|
93
|
+
language: {
|
|
94
|
+
type: string;
|
|
95
|
+
description: string;
|
|
96
|
+
};
|
|
97
|
+
prompt?: undefined;
|
|
98
|
+
context?: undefined;
|
|
99
|
+
instruction?: undefined;
|
|
100
|
+
focus?: undefined;
|
|
101
|
+
goal?: undefined;
|
|
102
|
+
};
|
|
103
|
+
required: string[];
|
|
104
|
+
};
|
|
105
|
+
} | {
|
|
106
|
+
name: string;
|
|
107
|
+
description: string;
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: string;
|
|
110
|
+
properties: {
|
|
111
|
+
code: {
|
|
112
|
+
type: string;
|
|
113
|
+
description: string;
|
|
114
|
+
};
|
|
115
|
+
goal: {
|
|
116
|
+
type: string;
|
|
117
|
+
description: string;
|
|
118
|
+
};
|
|
119
|
+
language: {
|
|
120
|
+
type: string;
|
|
121
|
+
description: string;
|
|
122
|
+
};
|
|
123
|
+
prompt?: undefined;
|
|
124
|
+
context?: undefined;
|
|
125
|
+
instruction?: undefined;
|
|
126
|
+
focus?: undefined;
|
|
127
|
+
error?: undefined;
|
|
128
|
+
};
|
|
129
|
+
required: string[];
|
|
130
|
+
};
|
|
131
|
+
})[];
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export const tools = [
|
|
2
|
+
{
|
|
3
|
+
name: "codex_generate",
|
|
4
|
+
description: "Generate code based on a natural language prompt. Use this for creating new code from scratch, implementing features, or writing functions.",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
prompt: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Natural language description of what code to generate",
|
|
11
|
+
},
|
|
12
|
+
language: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Programming language (e.g., typescript, python, rust)",
|
|
15
|
+
},
|
|
16
|
+
context: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Additional context like existing code, dependencies, or requirements",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
required: ["prompt"],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "codex_edit",
|
|
26
|
+
description: "Edit existing code based on instructions. Use this for modifying, updating, or improving existing code.",
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
code: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "The existing code to edit",
|
|
33
|
+
},
|
|
34
|
+
instruction: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "What changes to make to the code",
|
|
37
|
+
},
|
|
38
|
+
language: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Programming language of the code",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
required: ["code", "instruction"],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "codex_explain",
|
|
48
|
+
description: "Explain how code works. Use this for understanding complex code, algorithms, or logic.",
|
|
49
|
+
inputSchema: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
code: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "The code to explain",
|
|
55
|
+
},
|
|
56
|
+
language: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "Programming language of the code",
|
|
59
|
+
},
|
|
60
|
+
focus: {
|
|
61
|
+
type: "string",
|
|
62
|
+
description: "Specific aspect to focus on (e.g., 'performance', 'security', 'algorithm')",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ["code"],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "codex_fix",
|
|
70
|
+
description: "Fix buggy code based on error messages. Use this for debugging and fixing runtime or compilation errors.",
|
|
71
|
+
inputSchema: {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
code: {
|
|
75
|
+
type: "string",
|
|
76
|
+
description: "The code with the bug",
|
|
77
|
+
},
|
|
78
|
+
error: {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "The error message or description of the bug",
|
|
81
|
+
},
|
|
82
|
+
language: {
|
|
83
|
+
type: "string",
|
|
84
|
+
description: "Programming language of the code",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
required: ["code", "error"],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "codex_refactor",
|
|
92
|
+
description: "Refactor code to improve quality, readability, or performance. Use this for code cleanup and optimization.",
|
|
93
|
+
inputSchema: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {
|
|
96
|
+
code: {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: "The code to refactor",
|
|
99
|
+
},
|
|
100
|
+
goal: {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Refactoring goal (e.g., 'improve readability', 'optimize performance', 'reduce complexity')",
|
|
103
|
+
},
|
|
104
|
+
language: {
|
|
105
|
+
type: "string",
|
|
106
|
+
description: "Programming language of the code",
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
required: ["code", "goal"],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cpujia/codex-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP Server for OpenAI Codex /v1/responses API integration with Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"codex-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
".env.example"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"start": "node dist/index.js",
|
|
21
|
+
"prepare": "npm run build",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"mcp",
|
|
26
|
+
"codex",
|
|
27
|
+
"openai",
|
|
28
|
+
"gpt-5.3-codex",
|
|
29
|
+
"code-generation",
|
|
30
|
+
"claude-code",
|
|
31
|
+
"model-context-protocol",
|
|
32
|
+
"ai",
|
|
33
|
+
"code-assistant",
|
|
34
|
+
"typescript"
|
|
35
|
+
],
|
|
36
|
+
"author": "CPU-JIA <jia202520@gmail.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/CPU-JIA/codex-mcp-server.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/CPU-JIA/codex-mcp-server/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/CPU-JIA/codex-mcp-server#readme",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
48
|
+
"zod": "^3.23.8"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.10.2",
|
|
52
|
+
"typescript": "^5.7.2"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
}
|
|
57
|
+
}
|