codex-mcp-longrun
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@codex-mcp-longrunRuncargo testand wait for the final result."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Codex MCP Longrun
Codex MCP Longrun is a local STDIO MCP server for bounded, non-interactive
command jobs. Its asynchronous workflow returns a job ID promptly so Codex
does not need to keep a blocking tool call alive through model-visible wait
loops. The experimental codex-longrun launcher can pause a durable Goal while
the command runs and reactivate that exact Goal once terminal metadata exists.
It is intended for builds, test suites, packaging jobs, and similar trusted foreground commands. The local server validates the request, supervises the process group, captures bounded output, and persists terminal metadata.
Codex calls longrun.start_job once through codex-longrun
|
v
The local MCP server starts the command,
returns a job ID, and the bridge pauses the Goal
|
v
Codex ends the turn; the command runs without model polling
|
v
Terminal event -> idle check -> Goal reactivated onceThe project is currently a Linux/WSL pilot, not a production release.
This README describes theexperimental branch and package version
0.4.0a7. Its recommended Goal workflow is codex-longrun plus
start_job(wake_policy="goal"). The manual Goal and blocking workflows are
compatibility fallbacks and must not be combined with automatic wakeup.
Why use it
Repeatedly checking a long build with model-visible polling tools consumes
context and may require additional model turns even when nothing changed.
start_job avoids keeping the original tool call pending. It does not make the
initial submission or resumed result turn token-free. In an ordinary codex
process it cannot wake an idle thread; the opt-in launcher adds that client-side
capability through the official experimental App Server protocol.
Current Codex clients may turn a blocking MCP call into an outer executor cell
and ask the model to wait for that cell repeatedly. run_and_wait remains a
compatibility tool, but the installer exposes it so a Goal can require the
verified one-call workflow explicitly. Prefer start_job unless the current
client has been verified to keep the original MCP call pending.
While a legacy blocking call remains pending, the server can emit a short MCP progress heartbeat. Heartbeats are disabled by default because they do not prevent an outer Codex executor from yielding. When explicitly enabled, a heartbeat contains only elapsed time, time since the last output, and the number of captured bytes; it never contains command output.
The MCP and Codex documentation does not define a billing or model-token guarantee for progress notifications. Keep them disabled unless a specific client has been verified to render progress without re-entering the model.
Related MCP server: mcp-stdio
Tools
Tool | Purpose |
| Report the version, state paths, allowed roots, and active guardrails |
| Start one command and optionally arm a durable Goal wake lease |
| Read one bounded status or terminal result for a known job ID |
| Request process-group cancellation for one exact job ID |
| Legacy blocking compatibility mode; exposed for explicit one-call workflows |
| Read a bounded tail for a known job ID |
Do not repeatedly call get_job in the same turn. Automatic Goal wakeup is
available only when Codex was started through codex-longrun and the returned
status says automatic_wakeup = true.
One-time secret stdin
Never put a password in argv, an MCP argument, an environment variable, a
prompt, or a shell command line.
When a suitable encrypted test-only asset exists in Project Memory, Codex should stage it directly without revealing the value or asking the user to type it again:
project_memory_stage_test_asset_for_longrun(
project="Product/lab",
record_id="TEST_ASSET_ID",
secret_field="password"
)
-> stdin_secret_id="ONE_TIME_HANDLE"
longrun.start_job(
argv=[...],
cwd="/absolute/enrolled/root",
stdin_secret_id="ONE_TIME_HANDLE",
wake_policy="goal"
)Project Memory decrypts locally and returns only the random handle. The model
never receives the plaintext. This works in ordinary codex too; use
wake_policy="none" there because automatic Goal wakeup requires the
codex-longrun launcher.
Only when no suitable encrypted asset is enrolled, stage one finite password or token outside Codex in a second terminal:
~/.local/share/codex-longrun-mcp/.venv/bin/codex-longrun-secret --confirmThe fallback prompt uses getpass; typed characters are not echoed. Stdout
contains only a random 32-character one-time handle. Copy that handle—not the
password—into the Codex request:
Run the reviewed command with longrun.start_job, the normal argv and cwd,
stdin_secret_id="ONE_TIME_HANDLE", and wake_policy="goal". Never place the
secret value itself in any tool argument.The handle expires after five minutes by default and is consumed once. The
server validates the backing file's owner, 0600 mode, link count, type, age,
and size with O_NOFOLLOW; it opens and immediately unlinks the file, then
passes only the open descriptor to the supervised command's stdin. The handle
and secret content are not stored in job metadata.
Secret-stdin jobs always suppress stdout and stderr capture. Their log and
tail remain empty even if the command accidentally echoes the password.
Consequently, success_contains and failure_contains are rejected for these
jobs; use the exit code and non-secret result artifacts instead. A command can
still write the password into its own files or send it over the network, so
review the command itself and its artifact paths before using this feature.
This is a single finite stdin payload for a non-interactive program. Commands that require a TTY, repeated prompts, conversational input, or privilege elevation remain unsupported.
This mechanism prevents the value from entering Codex transcripts, MCP
arguments, process argv/environment, and Longrun output storage. Before it is
consumed, the value exists briefly in a local 0600 file. It does not defend
against root, another compromised process running as the same OS user, memory
inspection, or filesystem forensics. Use an external secret broker or run the
command manually when that stronger boundary is required.
Requirements
Linux or WSL;
Codex CLI with App Server Unix transport and Goal APIs (tested with Codex CLI
0.147.0);uv;a trusted project directory for
LONGRUN_ALLOWED_ROOTS.
The dependency lock currently installs Python MCP SDK 2.0.0 in an isolated
virtual environment.
Install from scratch
Clone the repository and install the locked runtime:
git clone https://github.com/woffko/codex-mcp-longrun.git
cd codex-mcp-longrun
git switch experimental
./scripts/install-runtime.shThe default runtime location is:
~/.local/share/codex-longrun-mcp/.venvRegister the server in Codex and replace /absolute/path/to/project with one
trusted project root:
./scripts/configure-codex.py \
--config "$HOME/.codex/config.toml" \
--command "$HOME/.local/share/codex-longrun-mcp/.venv/bin/codex-mcp-longrun" \
--server-cwd "$HOME/.local/share/codex-longrun-mcp" \
--state-dir "$HOME/.local/state/codex-longrun" \
--allowed-root /absolute/path/to/projectThe configuration script:
refuses to overwrite an existing
mcp_servers.longrunentry;creates a timestamped private backup under
~/.codex/backups;keeps the MCP optional with
required = false;allows only
health,start_job,get_job,cancel_job,run_and_wait, andread_log_tail;forwards
LONGRUN_BRIDGE_SOCKETonly when the opt-in launcher sets it;configures command start, cancellation, and log reads to require approval;
keeps bounded metadata-only
get_jobreads automatic;disables shell and privilege-elevation executables;
disables progress heartbeats by default;
limits all live jobs across local Codex sessions to four by default;
keeps one-time stdin handles for 300 seconds and limits their payload to 64 KiB by default;
gives Codex a tool timeout slightly longer than the server's 12-hour limit.
Start a new Codex process after configuration. Existing on-screen processes do
not hot-load new MCP servers. Use the codex-longrun commands in the next
section for event-driven Goal wakeup. Ordinary Codex can still resume the same
saved session in manual fallback mode:
cd /absolute/path/to/project
codex resume SESSION_IDChanging the shell directory first is important for project-scoped
.codex/config.toml discovery. Do not assume that a later Codex -C option
retroactively changes which configuration layers were loaded.
Verify registration:
codex mcp get longrun
codex mcp listFor an existing installation, apply the guarded config upgrade before
reinstalling. It adds the bridge socket passthrough and keeps run_and_wait
available without changing allowed roots or unrelated Codex settings:
./scripts/upgrade-codex.py --config "$HOME/.codex/config.toml" --dry-run
./scripts/upgrade-codex.py --config "$HOME/.codex/config.toml"
./scripts/install-runtime.shEvent-driven Goal launcher
Use codex-longrun instead of codex for sessions that should suspend a Goal
without model-visible polling. This is the recommended workflow on the
experimental branch:
~/.local/share/codex-longrun-mcp/.venv/bin/codex-longrun \
-C /absolute/path/to/project
~/.local/share/codex-longrun-mcp/.venv/bin/codex-longrun \
resume -C /absolute/path/to/project SESSION_IDThe launcher starts the unmodified official codex app-server, a same-user
Goal bridge, a bounded TUI compatibility proxy on private Unix sockets, and the
official TUI in --remote mode. It does not build or replace Codex. Ordinary
codex commands retain the manual two-turn behavior.
The launcher resolves Codex -C/--cd before starting App Server and starts
both App Server and the remote TUI with that real process working directory.
This ensures that project-scoped .codex/config.toml is loaded even when
codex-longrun itself was invoked from another directory.
On Linux/WSL, App Server, the Goal bridge, and the TUI proxy run below isolated
supervisors. Each supervisor combines kernel parent-death delivery with a
launcher-owned pipe, then terminates the daemon's complete process group with
SIGTERM and bounded SIGKILL escalation. The interactive TUI keeps its
controlling terminal and uses a lighter exec guard. Every guard rechecks PPID
after arming to close the fork-to-arm race. This prevents a Node shim or native
App Server from surviving its launcher and retaining a thread-store writer
lock; normal exits still use the launcher's graceful finally cleanup first.
Large Legacy session compatibility
Codex App Server defines thread/read(includeTurns=true) as a full-history
operation. A very large Legacy JSONL session can therefore produce a single
WebSocket response larger than the official TUI's receive limit. The launcher
now routes only TUI traffic through a local compatibility proxy:
official TUI -> tui.sock proxy -> official App Server
^
|
Goal bridge stays directThe default auto mode forwards normal traffic unchanged. For a Legacy rollout
at least 64 MiB in size, or when its local size cannot be determined safely, it
replaces only the TUI's full thread/read response with the latest five turns
obtained through experimental thread/turns/list(itemsView="full"). If that
bounded tail is unavailable or exceeds 16 MiB, the TUI receives the thread
summary with an empty visible turn list instead of an oversized frame.
This affects visible scrollback only. thread/resume, live events, approvals,
server requests, and all other JSON-RPC messages remain transparent, so App
Server still loads the original session as the model-visible thread context.
The proxy never edits, migrates, truncates, or rewrites a session JSONL file.
The tested Codex 0.147.0 TUI resumes with excludeTurns=true and then hydrates
Legacy scrollback through thread/read, which is the request the proxy bounds.
Legacy pagination may still require App Server to scan the complete JSONL file once, so the first bounded tail can take time even though its returned frame is small. The result is a compatibility guard, not a session-file migration.
Launcher controls are consumed locally and are not passed to Codex:
# Default: protect large Legacy sessions and show a five-turn tail.
codex-longrun --longrun-legacy-history auto resume -C /project SESSION_ID
# Fastest safe fallback: show no old turns for any Legacy session.
codex-longrun --longrun-legacy-history omit resume -C /project SESSION_ID
# Disable the compatibility guard. Large sessions may fail in the TUI.
codex-longrun --longrun-legacy-history off resume -C /project SESSION_IDAdvanced bounds can be changed with
--longrun-history-threshold-mib, --longrun-history-tail-turns, and
--longrun-history-timeout-sec. Use codex-longrun --bridge-help for the
accepted ranges. The implementation follows the official
Codex App Server protocol;
both the remote TUI transport and turn pagination are experimental upstream.
Do not combine this workflow with manual /goal pause, manual /goal resume,
or run_and_wait for the same job. The bridge owns the Goal status transition,
and an unexpected manual transition deliberately abandons its wake lease.
For an active durable Goal, call start_job with wake_policy="goal". The MCP
server takes the thread identity from Codex request metadata, not from a
model-controlled argument. Before the command starts, the bridge verifies the
active Goal and changes it to paused. After terminal metadata is committed,
the bridge waits for the current turn to become idle and changes the same Goal
to active. That status transition starts the next Goal turn; the bridge does
not also call turn/start.
Only one automatic wake lease may be active for a Goal. Clearing, completing, blocking, editing, or manually resuming that Goal abandons the lease rather than overriding the user. An ambiguous activation failure is never retried automatically; resume the Goal manually in that case.
Copy-paste automatic Goal contract
Replace the placeholders and start Codex through codex-longrun first:
/goal Complete [OBJECTIVE] without stopping until [VERIFIABLE END STATE]. For every reviewed, trusted, non-interactive command expected to run longer than about 30 seconds, call longrun.start_job exactly once with argv as an array, an absolute cwd, sufficient hard and no-output timeouts, and wake_policy="goal". Require automatic_wakeup=true in the returned status. After start_job returns, report the job ID and state, end the current turn, and do not call get_job, run_and_wait, a generic wait tool, write_stdin, log-tail checks, or any polling loop in that turn. Do not manually pause or resume this Goal; the local bridge owns those transitions, will pause this Goal while the command runs, and will reactivate this exact Goal only after terminal metadata is committed. In the automatically resumed turn, call longrun.get_job exactly once for the recorded job ID, analyze that terminal result, and continue the Goal. If automatic_wakeup is false or Goal wakeup setup fails, stop and report the failure instead of polling. Never put a secret value in argv, MCP arguments, prompts, or environment. If one reviewed command needs one finite secret stdin payload, prefer project_memory_stage_test_asset_for_longrun for an enrolled encrypted test asset and pass only its handle as stdin_secret_id; use codex-longrun-secret only when no suitable asset exists; secret-stdin output is intentionally suppressed.Waiting inside the bridge does not invoke the model. The initial submission and the automatically resumed turn still use model context and tokens; this is not a universal billing guarantee.
collaboration.wait_agent waits for delegated model agents; it has no
relationship to a Longrun process and must never be used to wait for a Longrun
job. The same prohibition applies to generic wait tools, write_stdin, log
tails, and status loops in the submission turn.
If the Goal never pauses
Inspect the start_job result. A bridge-enabled submission must have all of:
wake_policy = "goal"
automatic_wakeup = true
wake_delivery = "armed"wake_policy="none" deliberately bypasses the bridge, so the Goal remains
active and native Goal continuation may immediately start another model turn.
Do not wait in that turn. If a codex-longrun session returns
automatic_wakeup=false, stop and report the setup failure instead of falling
back to collaboration.wait_agent or polling. Use none only for ordinary
Codex or an explicitly requested manual fallback.
Enroll additional projects
The global server is visible to new Codex processes, but command tools accept working directories only under exact trusted roots. Add another project with the idempotent enrollment command:
./scripts/enroll-project.py \
--config "$HOME/.codex/config.toml" \
--allowed-root /absolute/path/to/another-project \
--dry-run
./scripts/enroll-project.py \
--config "$HOME/.codex/config.toml" \
--allowed-root /absolute/path/to/another-projectThe script creates a private backup, preserves unrelated TOML data, validates
the complete update, and refuses / or the current user's home directory.
Start a new Codex process after enrollment.
Codex agents performing a session or project integration should follow the Codex Agent Integration Runbook.
Fallback and compatibility workflows
The automatic Goal contract above is the primary experimental workflow. Use
the alternatives in this section only when the session was started with
ordinary codex, automatic wakeup setup failed before command start, or a
specific client has already been verified for one blocking MCP call. Do not
mix contracts for the same job.
The job supports:
a hard timeout;
an optional no-output timeout;
expected success and failure substrings;
a bounded result tail;
graceful termination followed by forced process-group cleanup.
Keep the originating interactive Codex process open while the job runs. A
one-shot codex exec client exits after its response and closes its MCP server;
the supervisor then terminates the command by design. This parent-death rule
prevents detached work from outliving the client that started it.
Manual fallback with ordinary Codex
An ordinary codex process has no bridge socket and cannot wake an idle Goal.
Use wake_policy="none" to make that manual behavior explicit:
Use longrun.start_job exactly once for ["cargo", "test"], with an absolute cwd
and wake_policy="none". Report the job ID and end the turn without polling.Later, request one bounded status read:
Call longrun.get_job once for JOB_ID. If it is still running, report the state
and do not poll again in this turn.For a durable Goal, the user must pause it before waiting and resume it for the agreed result check. The MCP server alone cannot control a Goal; only the opt-in App Server bridge can do so.
Copy-paste manual Goal contract
An ordinary Codex process does not wake a paused Goal automatically. Put the no-polling contract directly in the Goal objective, then pause and resume the Goal from the Codex CLI as shown below.
Replace the bracketed placeholders and paste this as one command:
/goal Complete [OBJECTIVE] without stopping until [VERIFIABLE END STATE]. For every reviewed, trusted, non-interactive command expected to run longer than about 30 seconds, call longrun.start_job exactly once with argv as an array, an absolute cwd, sufficient hard and no-output timeouts, and wake_policy="none". After start_job returns, report the job ID and state, end the turn, and do not call get_job, run_and_wait, a generic wait tool, write_stdin, log-tail checks, or any polling loop in that turn. Do not claim automatic wakeup. When I later resume this Goal and provide the job ID, call longrun.get_job exactly once. If the job is still running, report that state and end the turn without polling. Continue the Goal only after a terminal result. Never put a secret value in argv, MCP arguments, prompts, or environment. If one reviewed command needs one finite secret stdin payload, prefer project_memory_stage_test_asset_for_longrun for an enrolled encrypted test asset and pass only its handle as stdin_secret_id; use codex-longrun-secret only when no suitable asset exists; secret-stdin output is intentionally suppressed.After Codex reports the job ID, pause the Goal before another autonomous turn starts:
/goal pauseWhen you are ready to read the result, resume the Goal and provide the exact job ID in the next message:
/goal resume
Call longrun.get_job exactly once for JOB_ID. If it is terminal, continue the Goal from that result. If it is still running, report the state and do not poll again in this turn.This manual pause/resume step is only a fallback for ordinary codex; do not
perform it after start_job has returned automatic_wakeup=true under
codex-longrun. Starting a job alone is not proof that the Goal will wake when
the process exits.
Legacy uninterrupted Goal contract
Use this variant only when longrun.run_and_wait is explicitly exposed in the
current Codex session and that client has been verified to keep one MCP tool
call pending without re-entering the model. The Goal stays active: the command
runs inside the current turn, and Codex continues only after the same tool call
returns its terminal result.
Replace the bracketed placeholders and paste this as one command:
/goal Complete [OBJECTIVE] without stopping until [VERIFIABLE END STATE]. For every reviewed, trusted, non-interactive command expected to run longer than about 30 seconds, call longrun.run_and_wait exactly once with argv as an array, an absolute cwd, and sufficient hard and no-output timeouts. Remain in that single MCP call until it returns a terminal result. Do not use longrun.start_job, longrun.get_job, a generic wait tool, write_stdin, log-tail checks, status polling, repeated tool calls, or periodic model commentary while the call is pending. Treat MCP progress notifications as UI-only progress and do not respond to them with another model turn. Continue this Goal only after the original run_and_wait call returns. Never put a secret value in argv, MCP arguments, prompts, or environment. If one reviewed command needs one finite secret stdin payload, prefer project_memory_stage_test_asset_for_longrun for an enrolled encrypted test asset and pass only its handle as stdin_secret_id; use codex-longrun-secret only when no suitable asset exists; secret-stdin output is intentionally suppressed.This pattern avoids deliberate model-visible polling and does not require
pausing the Goal. It is not a universal billing guarantee: a Codex client that
converts a pending MCP call into repeated model turns can still consume tokens.
Use the event-driven codex-longrun contract on an unverified client.
Progress heartbeats
Heartbeat timing is server-wide and can be changed in the
[mcp_servers.longrun.env] section of the Codex configuration:
Environment variable | Default | Meaning |
|
| Delay before the first notification; |
|
| Interval between later notifications |
|
| Maximum live jobs across local Codex MCP server processes |
|
| Maximum age of an unconsumed one-time stdin handle |
|
| Maximum staged secret stdin payload |
longrun.health reports the effective values. The server silently disables
heartbeats for the current job if notification delivery fails; the command
continues running and still returns its terminal result. Clients that do not
request progress simply receive no heartbeat.
Job logs and metadata are private local files under:
~/.local/state/codex-longrun/jobsLogs are capped at 128 MiB by the default installer configuration. The result returns only a bounded tail and the local paths.
Security boundary
This server runs commands with the operating-system permissions of the account running Codex. It is not a security sandbox.
LONGRUN_ALLOWED_ROOTS validates the resolved working directory, but a launched
program can still access any files, networks, and processes available to the
same user. Treat the allowed-root check as a routing guard, not an authorization
boundary.
Additional safeguards include:
shell and privilege-elevation executable rejection by default;
no tool parameter for injecting environment variables;
a small allowlist of inherited environment names;
no raw argument array in job metadata, only a redacted display and digest;
private one-time stdin handles whose values never enter MCP, argv, environment, metadata, logs, or tails;
mandatory output suppression whenever secret stdin is used;
private state directories and files;
bounded logs and result tails;
a Linux supervisor that terminates the full command process group on normal completion, timeout, cancellation, or abrupt MCP-parent death;
startup recovery for incomplete metadata left by an interrupted server.
Never pass passwords, tokens, API keys, private keys, cookies, or other secret values in arguments, MCP fields, prompts, or environment. Use the one-time stdin workflow only for a reviewed command that accepts one finite stdin payload. Normal command output is written to the local job log; secret-stdin jobs are the exception and suppress all captured output. Redaction remains best-effort metadata hygiene, not general secret detection.
Do not use the server for interactive programs, REPLs, TUI applications, TTY-dependent or repeated password prompts, indefinite servers, daemons, detached jobs, untrusted repositories, or unreviewed commands.
Test
Create the development environment and run the integration suite:
uv sync --frozen --no-dev
.venv/bin/python -m unittest discover -s tests -vThe suite covers the STDIO handshake, asynchronous submission and later terminal reads, cross-session visibility and cancellation, active-job limits, protocol-level progress delivery, environment isolation, allowed-root and shell rejection, successful and failed commands, hard and inactivity timeouts, log truncation, cancellation, descendant cleanup, abrupt parent death, metadata recovery, safe config enrollment and upgrades, backup permissions, idempotency, broad-root rejection, sanitized session-polling audits, and one-time secret stdin with mandatory output suppression and no metadata/log/tail disclosure.
Upgrade and rollback
After pulling a reviewed update, preview and apply the guarded configuration upgrade, then reinstall the isolated runtime:
./scripts/upgrade-codex.py --config "$HOME/.codex/config.toml" --dry-run
./scripts/upgrade-codex.py --config "$HOME/.codex/config.toml"./scripts/install-runtime.shThe upgrade creates a private timestamped backup, preserves unrelated TOML and
explicit heartbeat policy, enables the asynchronous tool allowlist, and is
idempotent. Use --reset-heartbeat only when an existing nonzero heartbeat
should be changed to zero.
To disable the server without deleting local state:
codex mcp remove longrunAlternatively, restore the timestamped config.toml.before-longrun-* backup
created under ~/.codex/backups. Start a new Codex process after changing the
configuration.
The runtime and state directories are independent of the project repository. Removing the MCP configuration does not remove either directory automatically.
References
Available Tools
3 toolshealthCheck longrun MCP healthARead-only
Return server paths, versions, and configured guardrails.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| state_dir | Yes | |
| allow_shell | Yes | |
| mcp_version | Yes | |
| allowed_roots | Yes | |
| max_log_bytes | Yes | |
| python_version | Yes | |
| server_version | Yes | |
| max_timeout_sec | Yes | |
| forwarded_env_names | Yes | |
| heartbeat_initial_sec | Yes | |
| recovered_orphan_jobs | Yes | |
| heartbeat_interval_sec | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already provide readOnlyHint=true, establishing this as a safe read operation. The description adds useful specifics about the returned data (paths, versions, guardrails) without contradicting the annotations. It does not disclose potential side effects, but none are expected given the read-only nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that conveys all necessary information. There is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters, includes an output schema, and is annotated as read-only, the description is fully adequate. It states what the tool returns, and the output schema handles the rest. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, and the description rightly omits parameter details. Since there are no parameters to document, the baseline of 4 for a zero-parameter tool is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Return' and enumerates the exact resources (server paths, versions, guardrails), making the tool's purpose unmistakable. It is clearly distinct from siblings run_and_wait and read_log_tail, which involve execution and log reading respectively.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given for when to use this tool versus alternatives. However, the name 'health' and description imply it is for status checks, which serves as a weak implicit usage signal. No alternatives are mentioned or exclusions stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_log_tailRead a bounded tail from a longrun jobARead-only
Read only the bounded tail stored for a known job ID.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| tail_bytes | No | ||
| tail_lines | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tail | Yes | |
| job_id | Yes | |
| source_path | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, so the description's 'Read only' adds no new safety info. It does add that the tail is 'stored' and 'bounded', which hints at behavior (not live streaming, limited size), but lacks details on error handling or response structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no redundancy. It front-loads the core action and resource without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is relatively simple with an output schema (so return values are covered), but the description lacks parameter semantics and usage guidance. It is not fully complete for a 3-parameter tool with zero schema description coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate by explaining parameters. It only mentions 'known job ID' and 'bounded tail', but does not explain tail_bytes or tail_lines, their defaults, or how they interact. The agent must rely on schema names/types alone, which is insufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Read only') and resource ('bounded tail stored for a known job ID'), distinguishing it from siblings like health (status) and run_and_wait (execution). The title reinforces the longrun job context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'known job ID' implies this tool is used after a job has been created (likely via run_and_wait), but no explicit when/when-not guidance or alternatives are mentioned. Usage context is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_and_waitRun a long command and wait locallyADestructive
Run one approved non-interactive process and return one bounded terminal result.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | Yes | Absolute working directory inside LONGRUN_ALLOWED_ROOTS. | |
| argv | Yes | Command and arguments as an array. Shell and privilege-elevation commands are disabled. | |
| tail_bytes | No | ||
| tail_lines | No | ||
| timeout_sec | No | ||
| failure_contains | No | ||
| grace_period_sec | No | ||
| success_contains | No | ||
| no_output_timeout_sec | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| cwd | Yes | |
| tail | No | |
| error | No | |
| state | Yes | |
| job_id | Yes | |
| log_path | Yes | |
| exit_code | Yes | |
| duration_sec | Yes | |
| failure_match | No | |
| log_truncated | Yes | |
| metadata_path | Yes | |
| success_match | No | |
| started_at_utc | Yes | |
| command_display | Yes | |
| finished_at_utc | Yes | |
| output_bytes_seen | Yes | |
| output_bytes_logged | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive behavior, but the description adds valuable context: the process must be 'approved' and 'non-interactive', and the result is 'bounded'. This goes beyond annotations by conveying safety and output-limitation constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero wasted words. Every term ('approved', 'non-interactive', 'bounded') carries meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists and annotations provide a safety baseline, the description fails to mention critical operational details such as waiting behavior, timeouts, output truncation, or success/failure matching. Given the tool's nine parameters, this is insufficient for a new agent to use it effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 22% schema description coverage and no parameter details in the description, the agent receives no help understanding the seven undocumented parameters (tail_bytes, timeout_sec, success_contains, etc.). The description adds no parameter semantics beyond what the schema already provides for cwd and argv.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Run') and resource ('one approved non-interactive process') and clearly distinguishes this tool from siblings health and read_log_tail, which are about reading logs/state rather than executing commands. The phrase 'bounded terminal result' further clarifies the scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for running approved non-interactive commands and implies it waits for a result, but it does not explicitly state when to prefer this tool over alternatives or when not to use it. No exclusions or sibling comparisons are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a distinct role: health checks server status, run_and_wait executes a process and returns a result, and read_log_tail retrieves logs for a specific job. There is no overlap or ambiguity between them.
Tool names are inconsistent in style: 'health' is a simple noun, 'run_and_wait' is a verb phrase, and 'read_log_tail' is a verb-noun-noun compound. No uniform pattern (e.g., verb_noun) is followed.
Three tools is a minimal set, but it covers the core needs of a long-run execution server: health check, run a command, and read logs. It feels slightly thin but is not unreasonably sparse for a focused utility.
The surface covers the basic workflow of running a process and checking its logs, but lacks obvious lifecycle management tools like cancel, list jobs, or check status. The domain is narrow, yet significant gaps remain for robust long-running job handling.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Superserve sandboxes: create, exec, and manage Firecracker microVMs
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Hosted MCP server for task-first delegation to remote workstations and workers.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceProvides a secure, token-authenticated command execution tool over MCP Streamable HTTP, with a default-deny allowlist and shell metacharacter rejection.16Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA minimal, zero-dependency MCP server that enables defining and running tools over stdio transport, without extra features like HTTP or resources.151MIT
- FlicenseBqualityAmaintenancemcp-agent-ops is a local stdio MCP server for deterministic agent-development operations that otherwise cause repeated shell and generated Python calls.25
- AlicenseBqualityBmaintenanceA local, evidence-driven MCP runtime and control plane for open-source maintainers that provides workspace-bounded tools including controlled file operations, command execution, validation primitives, durable execution records, and human review workflows via stdio and Streamable HTTP transports.33MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/woffko/codex-mcp-longrun'
If you have feedback or need assistance with the MCP directory API, please join our Discord server