Skip to content

Codex voice mcp fix#2351

Open
troibe wants to merge 13 commits into
getpaseo:mainfrom
troibe:martin/codex-voice-mcp-fix
Open

Codex voice mcp fix#2351
troibe wants to merge 13 commits into
getpaseo:mainfrom
troibe:martin/codex-voice-mcp-fix

Conversation

@troibe

@troibe troibe commented Jul 23, 2026

Copy link
Copy Markdown

Linked issue

Closes #119

Type of change

  • Bug fix
  • New feature (with prior issue + design alignment)
  • Refactor / code improvement
  • Docs

What does this PR do

Problem

Codex voice-mode sessions use the runtime-injected paseo MCP server, but Paseo was not forwarding Codex-native MCP approval settings for that server into the Codex app-server configuration.

As a result, the speak tool could fall back to Codex's default MCP approval behavior and be rejected before Paseo's voice permission handling could allow it.

Fix

For Codex voice mode, Paseo now adds provider-specific MCP policy metadata under:

extra.codex.mcpServerPolicies.paseo

The policy uses Codex's native MCP configuration shape directly:

  • enabled_tools
  • default_tools_approval_mode
  • tools.<tool>.approval_mode

The voice-mode policy configures the runtime-injected paseo MCP server with:

{
  enabled_tools: ["speak"],
  default_tools_approval_mode: "prompt",
  tools: {
    speak: {
      approval_mode: "approve",
    },
  },
}

This keeps speak explicitly approved for Codex voice mode while leaving other Paseo tools subject to the normal prompt behavior.

The provider-specific metadata is consumed by the Codex adapter and omitted from the final native Codex config after being applied to mcp_servers.paseo.

How did you verify it

Manual testing in the app (with screenshots)

  1. Build or restart the Paseo server from this branch.
  2. Start a fresh Codex voice conversation.
  3. Speak a short prompt.
  4. Confirm that Codex calls the speak MCP tool and audio plays without a manual approval prompt.
IMG_3011

Automatic tests

  • npm run test:unit --workspace=@getpaseo/server -- src/server/session/voice/voice-session.test.ts
  • npm run test:unit --workspace=@getpaseo/server -- src/server/agent/agent-manager.test.ts -t "Codex voice MCP sessions"
  • npm run test:unit --workspace=@getpaseo/server -- src/server/agent/providers/codex-app-server-agent.test.ts -t "includes native MCP approval settings"
  • npm run typecheck
  • npm run lint
  • npm run format

Checklist

  • One focused change. Unrelated cleanups split out.
  • npm run typecheck passes
  • npm run lint passes
  • npm run format ran
  • UI changes include screenshots or video for every affected platform
  • Tests added or updated where it made sense

@troibe troibe changed the title Martin/codex voice mcp fix Codex voice mcp fix Jul 23, 2026
@troibe
troibe force-pushed the martin/codex-voice-mcp-fix branch from 91f226f to 953f7c3 Compare July 23, 2026 10:16
@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR forwards native Codex MCP approval policies for voice-mode sessions.

  • Adds typed Codex MCP policy metadata and maps it into the native app-server configuration.
  • Injects and restores the paseo.speak voice policy during voice-mode transitions.
  • Adds focused provider, session, and agent-manager tests plus operational documentation.

Confidence Score: 4/5

The PR is not yet safe to merge because valid Codex-derived custom providers can still reload voice mode without the required speak approval policy.

Provider ancestry is inferred from an arbitrary custom ID substring, so a provider declared with extends: "codex" but named without codex skips the policy and retains the original voice failure.

packages/server/src/server/session/voice/voice-session.ts

Important Files Changed

Filename Overview
packages/server/src/server/session/voice/voice-session.ts Adds voice-policy injection and restoration, but identifies Codex-derived custom providers through a non-authoritative substring check.
packages/server/src/server/agent/providers/codex-app-server-agent.ts Maps provider-specific MCP policies into each native Codex MCP server configuration and removes the transport-only metadata afterward.
packages/server/src/server/agent/agent-sdk-types.ts Defines the Codex-native MCP approval policy types carried in provider-specific session metadata.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  V[Enable voice mode] --> P{Provider identified as Codex}
  P -->|yes| O[Add paseo speak approval policy]
  O --> R[Reload agent session]
  R --> C[Codex native mcp_servers.paseo config]
  P -->|custom Codex ID lacks codex substring| M[Policy omitted]
Loading

Reviews (2): Last reviewed commit: "Address review comments for Codex voice ..." | Re-trigger Greptile

Comment thread packages/server/src/server/session/voice/voice-session.ts Outdated
private buildCodexVoiceModeOverrides(
existingConfig: AgentSessionConfig,
): Partial<AgentSessionConfig> | null {
if (!existingConfig.provider.toLowerCase().includes("codex")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Codex-derived providers skip policy

When a custom provider extends Codex but has a valid user-chosen ID without the codex substring, this check returns early and omits extra.codex.mcpServerPolicies.paseo, causing Codex to prompt for or reject the voice-mode speak call.

Knowledge Base Used: Agent Orchestration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Codex agent can't see the speak tool call in voice mode

1 participant