@cpujia/codex-mcp-server 1.0.0 → 2.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/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Codex MCP Server
2
2
 
3
+ [![npm version](https://badge.fury.io/js/%40cpujia%2Fcodex-mcp-server.svg)](https://www.npmjs.com/package/@cpujia/codex-mcp-server)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@cpujia/codex-mcp-server.svg)](https://www.npmjs.com/package/@cpujia/codex-mcp-server)
3
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
6
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
5
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org/)
8
+ [![GitHub stars](https://img.shields.io/github/stars/CPU-JIA/codex-mcp-server.svg)](https://github.com/CPU-JIA/codex-mcp-server/stargazers)
6
9
 
7
10
  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
11
 
@@ -1,15 +1,26 @@
1
+ type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
1
2
  interface CodexClientConfig {
2
3
  baseURL: string;
3
4
  apiKey: string;
4
5
  model: string;
5
6
  timeout: number;
6
7
  maxTokens: number;
7
- reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
8
+ reasoningEffort?: ReasoningEffort;
9
+ }
10
+ interface JsonSchemaFormat {
11
+ name: string;
12
+ schema: Record<string, unknown>;
13
+ }
14
+ interface CodexRequestOptions {
15
+ instructions: string;
16
+ input: string;
17
+ jsonSchema?: JsonSchemaFormat;
18
+ reasoningEffort?: ReasoningEffort;
19
+ maxTokens?: number;
8
20
  }
9
21
  export declare class CodexClient {
10
22
  private config;
11
23
  constructor(config: CodexClientConfig);
12
- generate(input: string): Promise<string>;
13
- generateStream(input: string, onChunk: (text: string) => void): Promise<void>;
24
+ request(options: CodexRequestOptions): Promise<string>;
14
25
  }
15
- export {};
26
+ export type { CodexClientConfig, CodexRequestOptions, JsonSchemaFormat, ReasoningEffort, };
@@ -3,23 +3,30 @@ export class CodexClient {
3
3
  constructor(config) {
4
4
  this.config = config;
5
5
  }
6
- async generate(input) {
6
+ async request(options) {
7
7
  const controller = new AbortController();
8
8
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
9
9
  try {
10
+ const effort = options.reasoningEffort ?? this.config.reasoningEffort;
11
+ const maxTokens = options.maxTokens ?? this.config.maxTokens;
10
12
  const requestBody = {
11
13
  model: this.config.model,
12
- input: [
13
- {
14
- role: "user",
15
- content: input,
16
- },
17
- ],
18
- max_output_tokens: this.config.maxTokens,
14
+ instructions: options.instructions,
15
+ input: [{ role: "user", content: options.input }],
16
+ max_output_tokens: maxTokens,
17
+ store: false,
19
18
  };
20
- if (this.config.reasoningEffort) {
21
- requestBody.reasoning = {
22
- effort: this.config.reasoningEffort,
19
+ if (effort) {
20
+ requestBody.reasoning = { effort };
21
+ }
22
+ if (options.jsonSchema) {
23
+ requestBody.text = {
24
+ format: {
25
+ type: "json_schema",
26
+ name: options.jsonSchema.name,
27
+ strict: true,
28
+ schema: options.jsonSchema.schema,
29
+ },
23
30
  };
24
31
  }
25
32
  const response = await fetch(`${this.config.baseURL}/responses`, {
@@ -40,7 +47,9 @@ export class CodexClient {
40
47
  if (data.status !== "completed") {
41
48
  throw new Error(`Unexpected response status: ${data.status}`);
42
49
  }
43
- const textContent = data.content.find((c) => c.type === "output_text");
50
+ const textContent = data.output
51
+ ?.flatMap((item) => item.content ?? [])
52
+ .find((c) => c.type === "output_text");
44
53
  if (!textContent?.text) {
45
54
  throw new Error("No text content in response");
46
55
  }
@@ -57,83 +66,4 @@ export class CodexClient {
57
66
  throw new Error(`Unknown error: ${String(error)}`);
58
67
  }
59
68
  }
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
69
  }
package/dist/index.js CHANGED
@@ -4,10 +4,12 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
5
  import { CodexClient } from "./codex-client.js";
6
6
  import { tools } from "./tools.js";
7
+ // --- 配置 ---
7
8
  const CODEX_API_BASE_URL = process.env.CODEX_API_BASE_URL;
8
9
  const CODEX_API_KEY = process.env.CODEX_API_KEY;
9
10
  const CODEX_MODEL = process.env.CODEX_MODEL || "gpt-5.3-codex";
10
- const CODEX_REASONING_EFFORT = process.env.CODEX_REASONING_EFFORT;
11
+ const CODEX_REASONING_EFFORT = (process.env.CODEX_REASONING_EFFORT ||
12
+ "high");
11
13
  if (!CODEX_API_BASE_URL || !CODEX_API_KEY) {
12
14
  console.error("Error: CODEX_API_BASE_URL and CODEX_API_KEY must be set");
13
15
  process.exit(1);
@@ -16,18 +18,201 @@ const codexClient = new CodexClient({
16
18
  baseURL: CODEX_API_BASE_URL,
17
19
  apiKey: CODEX_API_KEY,
18
20
  model: CODEX_MODEL,
19
- timeout: parseInt(process.env.CODEX_TIMEOUT || "60000"),
20
- maxTokens: parseInt(process.env.CODEX_MAX_TOKENS || "4096"),
21
+ timeout: parseInt(process.env.CODEX_TIMEOUT || "120000"),
22
+ maxTokens: parseInt(process.env.CODEX_MAX_TOKENS || "16384"),
21
23
  reasoningEffort: CODEX_REASONING_EFFORT,
22
24
  });
23
- const server = new Server({
24
- name: "codex-mcp-server",
25
- version: "1.0.0",
26
- }, {
27
- capabilities: {
28
- tools: {},
25
+ // --- JSON Schemas(强制结构化输出) ---
26
+ const GENERATE_SCHEMA = {
27
+ name: "generate_result",
28
+ schema: {
29
+ type: "object",
30
+ properties: {
31
+ code: { type: "string", description: "Generated code" },
32
+ language: { type: "string", description: "Programming language" },
33
+ explanation: {
34
+ type: "string",
35
+ description: "Brief explanation of approach and key decisions",
36
+ },
37
+ dependencies: {
38
+ type: "array",
39
+ items: { type: "string" },
40
+ description: "Required packages or imports",
41
+ },
42
+ },
43
+ required: ["code", "language", "explanation", "dependencies"],
44
+ additionalProperties: false,
29
45
  },
30
- });
46
+ };
47
+ const REVIEW_SCHEMA = {
48
+ name: "review_result",
49
+ schema: {
50
+ type: "object",
51
+ properties: {
52
+ findings: {
53
+ type: "array",
54
+ items: {
55
+ type: "object",
56
+ properties: {
57
+ severity: {
58
+ type: "string",
59
+ enum: ["critical", "high", "medium", "low", "info"],
60
+ },
61
+ category: {
62
+ type: "string",
63
+ enum: [
64
+ "security",
65
+ "performance",
66
+ "best-practice",
67
+ "bug",
68
+ "maintainability",
69
+ ],
70
+ },
71
+ location: {
72
+ type: "string",
73
+ description: "Line number or code section",
74
+ },
75
+ issue: {
76
+ type: "string",
77
+ description: "Description of the problem",
78
+ },
79
+ suggestion: {
80
+ type: "string",
81
+ description: "Concrete fix or improvement",
82
+ },
83
+ },
84
+ required: ["severity", "category", "location", "issue", "suggestion"],
85
+ additionalProperties: false,
86
+ },
87
+ },
88
+ summary: { type: "string", description: "Overall assessment" },
89
+ score: { type: "number", description: "Quality score 0-100" },
90
+ },
91
+ required: ["findings", "summary", "score"],
92
+ additionalProperties: false,
93
+ },
94
+ };
95
+ const TEST_SCHEMA = {
96
+ name: "test_result",
97
+ schema: {
98
+ type: "object",
99
+ properties: {
100
+ test_code: {
101
+ type: "string",
102
+ description: "Complete test file content",
103
+ },
104
+ language: { type: "string", description: "Programming language" },
105
+ framework: { type: "string", description: "Test framework used" },
106
+ test_cases: {
107
+ type: "array",
108
+ items: {
109
+ type: "object",
110
+ properties: {
111
+ name: { type: "string", description: "Test name" },
112
+ description: {
113
+ type: "string",
114
+ description: "What this test verifies",
115
+ },
116
+ type: {
117
+ type: "string",
118
+ enum: ["unit", "integration", "edge-case", "error-handling"],
119
+ },
120
+ },
121
+ required: ["name", "description", "type"],
122
+ additionalProperties: false,
123
+ },
124
+ },
125
+ coverage_notes: {
126
+ type: "string",
127
+ description: "What is covered and gaps remaining",
128
+ },
129
+ },
130
+ required: [
131
+ "test_code",
132
+ "language",
133
+ "framework",
134
+ "test_cases",
135
+ "coverage_notes",
136
+ ],
137
+ additionalProperties: false,
138
+ },
139
+ };
140
+ // --- Developer 指令(per-tool) ---
141
+ const INSTRUCTIONS = {
142
+ generate: [
143
+ "You are a senior software engineer. Generate production-quality code.",
144
+ "",
145
+ "Rules:",
146
+ "- Write complete, runnable code — no placeholders, no TODOs",
147
+ "- Include necessary imports and type definitions",
148
+ "- Follow language-specific conventions and idioms",
149
+ "- If project context is provided, follow its conventions strictly",
150
+ "- Optimize for readability first, performance second",
151
+ ].join("\n"),
152
+ review: [
153
+ "You are a security-focused code reviewer. Provide independent, critical analysis.",
154
+ "",
155
+ "Rules:",
156
+ "- Reference exact locations in the code (line numbers or function names)",
157
+ "- Prioritize: critical > high > medium > low > info",
158
+ "- For each finding, provide a concrete, actionable fix",
159
+ "- Score fairly: 90+ excellent, 70-89 good, 50-69 needs work, <50 concerning",
160
+ "- Be honest — don't inflate scores. Empty findings array is fine for clean code",
161
+ ].join("\n"),
162
+ test: [
163
+ "You are a testing expert. Write comprehensive test suites that catch real bugs.",
164
+ "",
165
+ "Rules:",
166
+ "- Generate a complete, runnable test file",
167
+ "- Cover: happy path, edge cases, error handling, boundary conditions",
168
+ "- Use the specified framework's idioms and best practices",
169
+ "- Include descriptive test names explaining expected behavior",
170
+ "- Mock external dependencies appropriately",
171
+ "- Think about what would break in production and test that",
172
+ ].join("\n"),
173
+ };
174
+ // --- 输入构建 ---
175
+ function buildInput(sections) {
176
+ const parts = [];
177
+ for (const [label, content] of Object.entries(sections)) {
178
+ if (content?.trim()) {
179
+ parts.push(`## ${label}\n${content.trim()}`);
180
+ }
181
+ }
182
+ return parts.join("\n\n");
183
+ }
184
+ // --- 安全 JSON 解析(带 fallback) ---
185
+ function safeJsonParse(raw) {
186
+ try {
187
+ return JSON.parse(raw);
188
+ }
189
+ catch {
190
+ // API 可能不支持 text.format,返回了非 JSON
191
+ return null;
192
+ }
193
+ }
194
+ function formatGenerateOutput(parsed) {
195
+ let text = `\`\`\`${parsed.language}\n${parsed.code}\n\`\`\``;
196
+ text += `\n\n**Explanation:** ${parsed.explanation}`;
197
+ if (parsed.dependencies.length > 0) {
198
+ text += `\n\n**Dependencies:** ${parsed.dependencies.join(", ")}`;
199
+ }
200
+ return text;
201
+ }
202
+ function formatReviewOutput(parsed) {
203
+ const findings = parsed.findings
204
+ .map((f, i) => `${i + 1}. **[${f.severity.toUpperCase()}]** ${f.category} — \`${f.location}\`\n Issue: ${f.issue}\n Fix: ${f.suggestion}`)
205
+ .join("\n\n");
206
+ return `**Score: ${parsed.score}/100**\n\n${parsed.summary}\n\n---\n\n${findings || "No issues found."}`;
207
+ }
208
+ function formatTestOutput(parsed) {
209
+ const cases = parsed.test_cases
210
+ .map((tc) => `- [${tc.type}] **${tc.name}**: ${tc.description}`)
211
+ .join("\n");
212
+ return `\`\`\`${parsed.language}\n${parsed.test_code}\n\`\`\`\n\n**Framework:** ${parsed.framework}\n**Test Cases (${parsed.test_cases.length}):**\n${cases}\n\n**Coverage:** ${parsed.coverage_notes}`;
213
+ }
214
+ // --- MCP Server ---
215
+ const server = new Server({ name: "codex-mcp-server", version: "2.0.0" }, { capabilities: { tools: {} } });
31
216
  server.setRequestHandler(ListToolsRequestSchema, async () => {
32
217
  return { tools };
33
218
  });
@@ -36,69 +221,88 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
36
221
  try {
37
222
  switch (name) {
38
223
  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
- };
224
+ const { prompt, language, project_context, files, conversation_context, } = args;
225
+ const input = buildInput({
226
+ Task: prompt,
227
+ Language: language,
228
+ "Project Context": project_context,
229
+ "Reference Files": files,
230
+ "Conversation Context": conversation_context,
231
+ });
232
+ const raw = await codexClient.request({
233
+ instructions: INSTRUCTIONS.generate,
234
+ input,
235
+ jsonSchema: GENERATE_SCHEMA,
236
+ });
237
+ const parsed = safeJsonParse(raw);
238
+ if (parsed && typeof parsed.code === "string") {
239
+ return {
240
+ content: [
241
+ {
242
+ type: "text",
243
+ text: formatGenerateOutput(parsed),
244
+ },
245
+ ],
246
+ };
247
+ }
248
+ // Fallback:API 不支持结构化输出时直接返回原文
249
+ return { content: [{ type: "text", text: raw }] };
63
250
  }
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
- };
251
+ case "codex_review": {
252
+ const { code, language, focus, project_context, conversation_context } = args;
253
+ const input = buildInput({
254
+ "Code to Review": `\`\`\`${language ?? ""}\n${code}\n\`\`\``,
255
+ Language: language,
256
+ "Focus Area": focus ?? "all",
257
+ "Project Context": project_context,
258
+ "Review Context": conversation_context,
259
+ });
260
+ const raw = await codexClient.request({
261
+ instructions: INSTRUCTIONS.review,
262
+ input,
263
+ jsonSchema: REVIEW_SCHEMA,
264
+ reasoningEffort: "high",
265
+ });
266
+ const parsed = safeJsonParse(raw);
267
+ if (parsed && Array.isArray(parsed.findings)) {
268
+ return {
269
+ content: [
270
+ {
271
+ type: "text",
272
+ text: formatReviewOutput(parsed),
273
+ },
274
+ ],
275
+ };
276
+ }
277
+ return { content: [{ type: "text", text: raw }] };
76
278
  }
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
- };
279
+ case "codex_test": {
280
+ const { code, language, framework, project_context, conversation_context, } = args;
281
+ const input = buildInput({
282
+ "Code to Test": `\`\`\`${language ?? ""}\n${code}\n\`\`\``,
283
+ Language: language,
284
+ "Test Framework": framework,
285
+ "Project Context": project_context,
286
+ Context: conversation_context,
287
+ });
288
+ const raw = await codexClient.request({
289
+ instructions: INSTRUCTIONS.test,
290
+ input,
291
+ jsonSchema: TEST_SCHEMA,
292
+ reasoningEffort: "high",
293
+ });
294
+ const parsed = safeJsonParse(raw);
295
+ if (parsed && typeof parsed.test_code === "string") {
296
+ return {
297
+ content: [
298
+ {
299
+ type: "text",
300
+ text: formatTestOutput(parsed),
301
+ },
302
+ ],
303
+ };
304
+ }
305
+ return { content: [{ type: "text", text: raw }] };
102
306
  }
103
307
  default:
104
308
  throw new Error(`Unknown tool: ${name}`);
@@ -107,73 +311,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
107
311
  catch (error) {
108
312
  const errorMessage = error instanceof Error ? error.message : String(error);
109
313
  return {
110
- content: [
111
- {
112
- type: "text",
113
- text: `Error: ${errorMessage}`,
114
- },
115
- ],
314
+ content: [{ type: "text", text: `Error: ${errorMessage}` }],
116
315
  isError: true,
117
316
  };
118
317
  }
119
318
  });
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
- }
319
+ // --- 启动 ---
173
320
  async function main() {
174
321
  const transport = new StdioServerTransport();
175
322
  await server.connect(transport);
176
- console.error("Codex MCP Server running on stdio");
323
+ console.error("Codex MCP Server v2.0.0 running on stdio");
177
324
  }
178
325
  main().catch((error) => {
179
326
  console.error("Fatal error:", error);
package/dist/tools.d.ts CHANGED
@@ -2,7 +2,7 @@ export declare const tools: ({
2
2
  name: string;
3
3
  description: string;
4
4
  inputSchema: {
5
- type: string;
5
+ type: "object";
6
6
  properties: {
7
7
  prompt: {
8
8
  type: string;
@@ -12,41 +12,21 @@ export declare const tools: ({
12
12
  type: string;
13
13
  description: string;
14
14
  };
15
- context: {
15
+ project_context: {
16
16
  type: string;
17
17
  description: string;
18
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: {
19
+ files: {
34
20
  type: string;
35
21
  description: string;
36
22
  };
37
- instruction: {
38
- type: string;
39
- description: string;
40
- };
41
- language: {
23
+ conversation_context: {
42
24
  type: string;
43
25
  description: string;
44
26
  };
45
- prompt?: undefined;
46
- context?: undefined;
27
+ code?: undefined;
47
28
  focus?: undefined;
48
- error?: undefined;
49
- goal?: undefined;
29
+ framework?: undefined;
50
30
  };
51
31
  required: string[];
52
32
  };
@@ -54,7 +34,7 @@ export declare const tools: ({
54
34
  name: string;
55
35
  description: string;
56
36
  inputSchema: {
57
- type: string;
37
+ type: "object";
58
38
  properties: {
59
39
  code: {
60
40
  type: string;
@@ -65,14 +45,21 @@ export declare const tools: ({
65
45
  description: string;
66
46
  };
67
47
  focus: {
48
+ type: string;
49
+ enum: string[];
50
+ description: string;
51
+ };
52
+ project_context: {
53
+ type: string;
54
+ description: string;
55
+ };
56
+ conversation_context: {
68
57
  type: string;
69
58
  description: string;
70
59
  };
71
60
  prompt?: undefined;
72
- context?: undefined;
73
- instruction?: undefined;
74
- error?: undefined;
75
- goal?: undefined;
61
+ files?: undefined;
62
+ framework?: undefined;
76
63
  };
77
64
  required: string[];
78
65
  };
@@ -80,51 +67,31 @@ export declare const tools: ({
80
67
  name: string;
81
68
  description: string;
82
69
  inputSchema: {
83
- type: string;
70
+ type: "object";
84
71
  properties: {
85
72
  code: {
86
73
  type: string;
87
74
  description: string;
88
75
  };
89
- error: {
90
- type: string;
91
- description: string;
92
- };
93
76
  language: {
94
77
  type: string;
95
78
  description: string;
96
79
  };
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: {
80
+ framework: {
112
81
  type: string;
113
82
  description: string;
114
83
  };
115
- goal: {
84
+ project_context: {
116
85
  type: string;
117
86
  description: string;
118
87
  };
119
- language: {
88
+ conversation_context: {
120
89
  type: string;
121
90
  description: string;
122
91
  };
123
92
  prompt?: undefined;
124
- context?: undefined;
125
- instruction?: undefined;
93
+ files?: undefined;
126
94
  focus?: undefined;
127
- error?: undefined;
128
95
  };
129
96
  required: string[];
130
97
  };
package/dist/tools.js CHANGED
@@ -1,112 +1,130 @@
1
1
  export const tools = [
2
2
  {
3
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.",
4
+ description: [
5
+ "Generate code using Codex deep reasoning. Use for complex tasks where a second expert perspective adds value.",
6
+ "",
7
+ "Returns structured JSON: { code, language, explanation, dependencies }",
8
+ "",
9
+ "When to use:",
10
+ "- Complex algorithms, data structures, state machines",
11
+ "- Performance-critical code requiring deep optimization",
12
+ "- System design implementations (interpreters, compilers, protocols)",
13
+ "- When you want a different model's approach to a hard problem",
14
+ "",
15
+ "Do NOT use for simple code generation — handle that natively.",
16
+ ].join("\n"),
5
17
  inputSchema: {
6
18
  type: "object",
7
19
  properties: {
8
20
  prompt: {
9
21
  type: "string",
10
- description: "Natural language description of what code to generate",
22
+ description: "What to generate. Be specific: requirements, constraints, expected behavior.",
11
23
  },
12
24
  language: {
13
25
  type: "string",
14
- description: "Programming language (e.g., typescript, python, rust)",
26
+ description: "Target language (e.g., typescript, python, rust, go).",
15
27
  },
16
- context: {
28
+ project_context: {
17
29
  type: "string",
18
- description: "Additional context like existing code, dependencies, or requirements",
30
+ description: "Project info: tech stack, conventions, architecture. Pass CLAUDE.md or relevant standards.",
19
31
  },
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: {
32
+ files: {
35
33
  type: "string",
36
- description: "What changes to make to the code",
34
+ description: "Related source files. Include types, interfaces, imports the generated code should reference.",
37
35
  },
38
- language: {
36
+ conversation_context: {
39
37
  type: "string",
40
- description: "Programming language of the code",
38
+ description: "Recent conversation summary: what was discussed, decided, or attempted.",
41
39
  },
42
40
  },
43
- required: ["code", "instruction"],
41
+ required: ["prompt"],
44
42
  },
45
43
  },
46
44
  {
47
- name: "codex_explain",
48
- description: "Explain how code works. Use this for understanding complex code, algorithms, or logic.",
45
+ name: "codex_review",
46
+ description: [
47
+ "Independent code review from a second AI. Analyzes security, performance, and best practices that the primary AI might miss.",
48
+ "",
49
+ "Returns structured JSON: { findings: [{ severity, category, location, issue, suggestion }], summary, score }",
50
+ "",
51
+ "When to use:",
52
+ "- Before committing security-sensitive code (auth, crypto, input validation)",
53
+ "- Performance-critical paths that need independent analysis",
54
+ "- When you want a second opinion on code quality",
55
+ "- PR review where an independent perspective matters",
56
+ "",
57
+ "Severity levels: critical, high, medium, low, info",
58
+ "Score range: 0-100 (90+ excellent, 70-89 good, 50-69 needs work, <50 concerning)",
59
+ ].join("\n"),
49
60
  inputSchema: {
50
61
  type: "object",
51
62
  properties: {
52
63
  code: {
53
64
  type: "string",
54
- description: "The code to explain",
65
+ description: "Code to review.",
55
66
  },
56
67
  language: {
57
68
  type: "string",
58
- description: "Programming language of the code",
69
+ description: "Programming language of the code.",
59
70
  },
60
71
  focus: {
61
72
  type: "string",
62
- description: "Specific aspect to focus on (e.g., 'performance', 'security', 'algorithm')",
73
+ enum: ["security", "performance", "best-practices", "all"],
74
+ description: "Review focus area. Default: all.",
75
+ },
76
+ project_context: {
77
+ type: "string",
78
+ description: "Project conventions, lint rules, architectural guidelines.",
79
+ },
80
+ conversation_context: {
81
+ type: "string",
82
+ description: "Why this review is needed: what changed, what concerns exist.",
63
83
  },
64
84
  },
65
85
  required: ["code"],
66
86
  },
67
87
  },
68
88
  {
69
- name: "codex_fix",
70
- description: "Fix buggy code based on error messages. Use this for debugging and fixing runtime or compilation errors.",
89
+ name: "codex_test",
90
+ description: [
91
+ "Generate comprehensive test suites with deep reasoning for edge case coverage.",
92
+ "",
93
+ "Returns structured JSON: { test_code, language, framework, test_cases: [{ name, description, type }], coverage_notes }",
94
+ "",
95
+ "When to use:",
96
+ "- Complex business logic needing thorough edge case coverage",
97
+ "- Functions with many branches, error paths, or boundary conditions",
98
+ "- When test quality directly impacts reliability",
99
+ "- Integration tests requiring careful mock setup",
100
+ "",
101
+ "Test case types: unit, integration, edge-case, error-handling",
102
+ ].join("\n"),
71
103
  inputSchema: {
72
104
  type: "object",
73
105
  properties: {
74
106
  code: {
75
107
  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",
108
+ description: "Code to generate tests for.",
81
109
  },
82
110
  language: {
83
111
  type: "string",
84
- description: "Programming language of the code",
112
+ description: "Programming language (e.g., typescript, python).",
85
113
  },
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: {
114
+ framework: {
97
115
  type: "string",
98
- description: "The code to refactor",
116
+ description: "Test framework (e.g., jest, vitest, pytest, go test).",
99
117
  },
100
- goal: {
118
+ project_context: {
101
119
  type: "string",
102
- description: "Refactoring goal (e.g., 'improve readability', 'optimize performance', 'reduce complexity')",
120
+ description: "Project test conventions: existing patterns, mock strategies, test directory structure.",
103
121
  },
104
- language: {
122
+ conversation_context: {
105
123
  type: "string",
106
- description: "Programming language of the code",
124
+ description: "Context about the code: known issues, requirements, what needs coverage.",
107
125
  },
108
126
  },
109
- required: ["code", "goal"],
127
+ required: ["code"],
110
128
  },
111
129
  },
112
130
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cpujia/codex-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "MCP Server for OpenAI Codex /v1/responses API integration with Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",