Skip to main content
Glama
kodaimaehata

Cursor Reviewer MCP

by kodaimaehata

codex.review

Review code files using GPT-5 via Cursor CLI to generate structured JSON feedback with audit logging.

Instructions

Review deliverables via Codex CLI and return review JSON only.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
targetsYesレビュー対象ファイル一覧(表示名とパス)
previous_reviewsNo前回レビュー結果JSON(must_fixes/チェックリスト等)への参照一覧
referenceYesレビューで参照すべきドキュメント一覧(表示名とパス)
review_requestYesレビューワへの依頼文(自然文)
timeout_msNo外部レビュー実行のタイムアウト(ミリ秒)
policyNo将来予約(LGTM基準等)。初期バージョンは null 固定・不使用

Implementation Reference

  • Main execution handler for the 'codex.review' tool. Builds a prompt from input, calls the Codex CLI (with retry on failure), and returns the parsed review JSON.
    export async function runCodexReview(input: ReviewInput): Promise<any> {
      const prompt = buildPrompt(input);
      const timeout = input.timeout_ms ?? 1_800_000; // 30m default
    
      try {
        return await callCodexAndParse(prompt, timeout);
      } catch (_) {
        const retryPrompt = `${prompt}\n\n重要: 必ずJSONのみを返し、説明文やコードフェンスは含めないこと。`;
        return await callCodexAndParse(retryPrompt, timeout);
      }
    }
  • Helper function that invokes the 'codex' CLI binary with the prompt, handles execution timeout, extracts JSON from output, parses it, and persists the review.
    async function callCodexAndParse(prompt: string, timeoutMs: number): Promise<any> {
      const allowPlainFallback = process.env.REVIEWER_MCP_ALLOW_PLAINTEXT_FALLBACK === '1' ||
        process.env.REVIEWER_MCP_ALLOW_PLAINTEXT_FALLBACK === 'true';
      const bin = process.env.REVIEWER_MCP_CODEX_BIN || 'codex';
      const flags = parseFlags(process.env.REVIEWER_MCP_CODEX_FLAGS || '');
      const args = ['exec', ...flags, prompt];
    
      let stdout: string;
      try {
        ({ stdout } = await execWithTimeout(bin, args, timeoutMs));
      } catch (e: any) {
        if (e && (e.code === 'ENOENT' || /ENOENT/.test(e.message))) {
          throw new Error(`Codex CLI not found: set REVIEWER_MCP_CODEX_BIN or install 'codex'.`);
        }
        throw e;
      }
    
      try {
        const extracted = extractJsonString(stdout);
        if (!extracted) {
          if (allowPlainFallback) {
            return stdout.trim();
          }
          throw new Error('Could not locate JSON in Codex output');
        }
        const reviewObj = JSON.parse(extracted);
        persistReview(reviewObj);
        return reviewObj;
      } catch (e) {
        if (allowPlainFallback) {
          return stdout.trim();
        }
        throw new Error(`Review JSON parse failed: ${(e as Error).message}`);
      }
    }
  • src/server.ts:72-77 (registration)
    Registration of the 'codex.review' tool in the MCP server's listTools response, including name, title, description, and input schema reference.
    {
      name: 'codex.review',
      title: 'Run review via Codex CLI',
      description: 'Review deliverables via Codex CLI and return review JSON only.',
      inputSchema: codexInputSchema
    }
  • TypeScript type definitions for ReviewInput, Target, and Reference, which define the structure for the tool's input schema.
    export type Target = { file: string; path: string };
    export type Reference = { file: string; path: string };
    
    export type ReviewInput = {
      targets: Target[];
      reference: Reference[];
      previous_reviews?: Reference[];
      review_request: string;
      timeout_ms?: number;
      policy?: string | null;
    };
  • Helper function to build the review prompt by loading a template and interpolating targets, references, previous reviews, and instructions.
    export function buildPrompt(input: ReviewInput): string {
      const tmplPathOverride = process.env.REVIEWER_MCP_TEMPLATE_PATH;
      const tmplPath = tmplPathOverride ?? fileURLToPath(new URL('./prompt/template.txt', import.meta.url));
      const tmpl = readFileSync(tmplPath, 'utf8');
      const targets_json = JSON.stringify(input.targets, null, 2);
      const reference_json = JSON.stringify(input.reference, null, 2);
      const prevList = input.previous_reviews ?? [];
      const previous_reviews_objects: any[] = [];
      for (const p of prevList) {
        try {
          const raw = readFileSync(p.path, 'utf8');
          const obj = JSON.parse(raw);
          previous_reviews_objects.push({ file: p.file, path: p.path, review: obj });
        } catch {
          previous_reviews_objects.push({ file: p.file, path: p.path, review: null, error: 'unreadable_or_invalid_json' });
        }
      }
      const previous_reviews_json = JSON.stringify(previous_reviews_objects, null, 2);
      const follow_up_instructions = prevList.length > 0
        ? '前回レビュー(must_fixes と acceptance_checklist)に基づき、各指摘が解消済みかを厳密に確認し、未解消の場合は理由と改善指示を明確に示してください。新規の懸念点があれば suggestions に含めてください。出力はJSONのみです。'
        : '';
      return tmpl
        .replace('{{review_request}}', input.review_request)
        .replace('{{targets_json}}', targets_json)
        .replace('{{reference_json}}', reference_json)
        .replace('{{previous_reviews_json}}', previous_reviews_json)
        .replace('{{follow_up_instructions}}', follow_up_instructions);
    }
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kodaimaehata/reviewer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server