Problem
Named @sessions are persistent: each keeps a bridge (and, for stdio, the MCP server child process) alive until the session is explicitly closed. This is useful for repeated calls, but it can leave one idle MCP process running for every consumer context.
One concrete use case is Codex skills that invoke an MCP server on demand through mcpc. Calls often arrive in short bursts, so keeping the connection warm briefly is useful; keeping one MCP process alive indefinitely for every Codex thread is not.
The existing --timeout is a per-request timeout, so this should use distinct terminology.
Proposed interface
mcpc connect <server> @session --idle-timeout 600
--idle-timeout is expressed in seconds and is persisted with the named session, like other connection settings that survive bridge restart/reconnect.
- Omission or
--idle-timeout 0: preserve the current unlimited lifetime.
- A positive value: after that many seconds without user-issued MCP activity, gracefully close the MCP transport and any stdio server child process, then exit the bridge.
- Retain the named session and its configuration after idle shutdown. Mark it as intentionally idle/stopped rather than crashed so background crash recovery does not immediately restart it; the next user operation should start its bridge on demand.
Activity semantics
- Count user-issued MCP operations as activity, including an explicit user
ping.
- Do not count internal keepalive/health pings, passive server notifications, notification-triggered cache refreshes or resource sync, or other housekeeping traffic.
- Never expire while one or more user operations are in flight. Once the last active operation completes, start a fresh idle period.
This likely needs a user-activity timestamp separate from lastSeenAt, because lastSeenAt currently records successful keepalive pings as well as commands.
Flag placement
connect seems like the natural public entry point because it creates/configures a named session, and the timeout belongs to that persisted session configuration. Restart and automatic reconnect should reuse the saved value without requiring the flag again. If there is a better internal configuration boundary, the important behavior is that the value is set when creating/configuring the named session and persists with it.
Suggested acceptance matrix
| Case |
Expected result |
| Flag omitted |
Existing unlimited-lifetime behavior |
--idle-timeout 0 |
Same unlimited-lifetime behavior |
| Positive timeout, no user activity |
Transport and child process close gracefully after the timeout; named session remains available for on-demand reuse |
| User operation before deadline |
Idle deadline resets after the operation completes |
| Operation runs past deadline |
Session stays alive until the operation completes, then receives a fresh full idle period |
| Concurrent operations |
Session cannot expire until all user operations have completed |
| Internal keepalive ping |
Does not reset the idle deadline |
| Passive notification / housekeeping refresh |
Does not reset the idle deadline |
Explicit user ping |
Does reset the idle deadline |
| Bridge restart/reconnect |
Persisted timeout is retained |
| Next command after idle shutdown |
Bridge/transport starts on demand and the command succeeds |
| HTTP and stdio transports |
HTTP closes cleanly; stdio also terminates its server child process |
Drafted by Codex (GPT 5.6 Sol Medium) at my request, and reviewed by me before posting
Problem
Named
@sessions are persistent: each keeps a bridge (and, for stdio, the MCP server child process) alive until the session is explicitly closed. This is useful for repeated calls, but it can leave one idle MCP process running for every consumer context.One concrete use case is Codex skills that invoke an MCP server on demand through
mcpc. Calls often arrive in short bursts, so keeping the connection warm briefly is useful; keeping one MCP process alive indefinitely for every Codex thread is not.The existing
--timeoutis a per-request timeout, so this should use distinct terminology.Proposed interface
--idle-timeoutis expressed in seconds and is persisted with the named session, like other connection settings that survive bridge restart/reconnect.--idle-timeout 0: preserve the current unlimited lifetime.Activity semantics
ping.This likely needs a user-activity timestamp separate from
lastSeenAt, becauselastSeenAtcurrently records successful keepalive pings as well as commands.Flag placement
connectseems like the natural public entry point because it creates/configures a named session, and the timeout belongs to that persisted session configuration. Restart and automatic reconnect should reuse the saved value without requiring the flag again. If there is a better internal configuration boundary, the important behavior is that the value is set when creating/configuring the named session and persists with it.Suggested acceptance matrix
--idle-timeout 0pingDrafted by Codex (GPT 5.6 Sol Medium) at my request, and reviewed by me before posting