Skip to main content
Glama

codex_reply

Continue code conversations using thread IDs for follow-up questions, iterative refinement, or multi-step workflows that build on prior context.

Instructions

Continue a previous codex conversation by thread ID. Use this for follow-up questions, iterative refinement, or multi-step workflows that build on prior context.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
thread_idYesThread ID from a prior codex response
promptYesFollow-up instruction or question
cwdNoWorking directory override
modelNoModel override

Implementation Reference

  • The tool "[toolName]_reply" (e.g., codex_reply) is dynamically registered in `registerQueryTools`. It uses `runQuery` to continue a thread.
    if (baseConfig.persistSession !== false) {
      server.registerTool(replyToolName, {
        description: [
          `Continue a previous ${toolName} conversation by thread ID.`,
          "Use this for follow-up questions, iterative refinement,",
          "or multi-step workflows that build on prior context.",
        ].join(" "),
        inputSchema: z.object({
          thread_id: z.string().describe(`Thread ID from a prior ${toolName} response`),
          prompt: z.string().describe("Follow-up instruction or question"),
          cwd: z.string().optional().describe("Working directory override"),
          model: z.string().optional().describe("Model override"),
        }),
      }, async ({ thread_id, prompt, cwd, model }) => {
        try {
          const result = await runQuery(prompt, {
            cwd, model, resumeThreadId: thread_id,
          }, baseConfig, apiKey);
          return formatResult(result);
        } catch (error) {
          return formatError(error);
        }
      });
    }
  • The `runQuery` function handles the execution for both initial queries and reply/follow-up calls by checking `overrides.resumeThreadId`.
    async function runQuery(
      prompt: string,
      overrides: InvocationOverrides,
      baseConfig: ThreadConfig,
      apiKey?: string
    ): Promise<RunResult> {
      const codex = new Codex({
        ...(apiKey ? { apiKey } : {}),
      });
    
      const threadOptions: Record<string, unknown> = {};
    
      // Model
      const model = overrides.model || baseConfig.model;
      if (model) threadOptions.model = model;
    
      // Working directory — accept any path, preserve agent's base access
      let cwd = baseConfig.cwd || process.cwd();
      if (overrides.cwd) {
        const resolvedCwd = resolve(cwd, overrides.cwd);
        if (resolvedCwd !== cwd) {
          const dirs = new Set(baseConfig.additionalDirectories || []);
          dirs.add(cwd);
          threadOptions.additionalDirectories = [...dirs];
          cwd = resolvedCwd;
        }
      }
      threadOptions.workingDirectory = cwd;
    
      // Per-invocation additionalDirs — unions with server-level + auto-added dirs
      if (overrides.additionalDirs?.length) {
        const existing = (threadOptions.additionalDirectories as string[]) || baseConfig.additionalDirectories || [];
        const dirs = new Set(existing);
        for (const dir of overrides.additionalDirs) {
          dirs.add(dir);
        }
        threadOptions.additionalDirectories = [...dirs];
      } else if (baseConfig.additionalDirectories && !threadOptions.additionalDirectories) {
        threadOptions.additionalDirectories = baseConfig.additionalDirectories;
      }
    
      // Sandbox mode — can only tighten
      const baseSandbox = baseConfig.sandboxMode || "read-only";
      if (overrides.sandboxMode) {
        threadOptions.sandboxMode = narrowSandboxMode(baseSandbox, overrides.sandboxMode);
      } else {
        threadOptions.sandboxMode = baseSandbox;
      }
    
      // Approval policy — can only tighten
      const baseApproval = baseConfig.approvalPolicy || "on-failure";
      if (overrides.approvalPolicy) {
        threadOptions.approvalPolicy = narrowApprovalPolicy(baseApproval, overrides.approvalPolicy);
      } else {
        threadOptions.approvalPolicy = baseApproval;
      }
    
      // Effort
      const effort = overrides.effort || baseConfig.effort;
      if (effort) threadOptions.modelReasoningEffort = effort;
    
      // Network access
      if (overrides.networkAccess !== undefined) {
        threadOptions.networkAccessEnabled = overrides.networkAccess;
      } else if (baseConfig.networkAccess !== undefined) {
        threadOptions.networkAccessEnabled = baseConfig.networkAccess;
      }
    
      // Web search
      const webSearch = overrides.webSearchMode || baseConfig.webSearchMode;
      if (webSearch) threadOptions.webSearchMode = webSearch;
    
      // Start or resume thread
      const thread = overrides.resumeThreadId
        ? codex.resumeThread(overrides.resumeThreadId, threadOptions)
        : codex.startThread(threadOptions);
    
      // Build prompt with instructions
      let fullPrompt = prompt;
      if (!overrides.resumeThreadId) {
        const instructions = overrides.instructions || baseConfig.instructions;
        const appendInstructions = baseConfig.appendInstructions;
        if (instructions) {
          fullPrompt = `${instructions}\n\n${prompt}`;
        } else if (appendInstructions) {
          fullPrompt = `${appendInstructions}\n\n${prompt}`;
        }
      }
    
      const turn = await thread.run(fullPrompt);
    
      return {
        threadId: thread.id || "",
        response: turn.finalResponse || "",
        usage: turn.usage || { input_tokens: 0, cached_input_tokens: 0, output_tokens: 0 },
        isError: false,
      };
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It successfully conveys stateful behavior ('build on prior context') but lacks disclosure of error handling (invalid thread_id), side effects, output format, or rate limit behaviors expected for a conversational tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. First sentence front-loads the core action; second provides usage context. Every word earns its place with no redundancy or tautology.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 100% schema coverage and no output schema, the description adequately covers the tool's purpose and differentiation from siblings. Minor gap: no mention of error scenarios (e.g., expired threads) or what constitutes a valid thread_id format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, establishing baseline 3. The description does not redundantly explain parameters already well-documented in schema (thread_id, prompt), nor does it mention optional parameters (cwd, model), but no additional semantic clarification is required given complete schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the action ('Continue'), resource ('codex conversation'), and mechanism ('by thread ID'), clearly distinguishing it from the sibling 'codex' tool which likely initiates new conversations. The scope is precise and specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance ('Use this for follow-up questions, iterative refinement, or multi-step workflows') that implies continuation versus new conversation. Could be strengthened by explicitly contrasting when NOT to use it versus the sibling 'codex' tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/xiaolai/codex-octopus'

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