Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 44 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# Claude Ask

Claude Ask is an open-source Codex plugin that asks a locally authenticated
Claude Code model for an independent second opinion.
Claude Ask is an open-source Codex plugin that runs a locally authenticated
Claude Code Sonnet 5, Fable, or Opus model as an independent second opinion or
full autonomous coding agent.

It provides three MCP tools:
It provides five persistent asynchronous MCP tools:

- `ask` starts a persistent asynchronous Claude Fable or Opus job;
- `ask_status` reports progress and returns the final answer;
- `cancel_ask` explicitly cancels a job.
- `ask` starts a new advisory or workspace-agent job;
- `ask_followup` resumes a completed Claude session and forks a new branch;
- `ask_status` waits for progress or returns the final result;
- `list_jobs` lists recent jobs and recovers lost IDs;
- `cancel_ask` explicitly cancels a job and its process tree.

For repository reviews, `ask` accepts an explicit absolute `workspace`. Claude
runs from that directory with only the built-in `Read`, `Glob`, and `Grep`
tools. It cannot run shell commands or edit files. Without `workspace`, Claude
receives no tools.
Jobs support a human-readable name, `medium | high | xhigh | max` effort
(`high` by default), and an optional `max_budget_usd` ceiling.

## Install in Codex

Expand All @@ -23,38 +24,55 @@ codex plugin marketplace add AbsoluteMode/claude-ask
codex plugin add claude-ask@absolutmode
```

Start a new Codex thread after installation so the new skill and MCP tool
schema are loaded.
Start a new Codex task after installing or updating so the skill and MCP tool
schemas are reloaded.

## Requirements

- Codex with plugin support;
- Node.js 22 or newer;
- Claude Code installed at `~/.local/bin/claude`, or `CLAUDE_ASK_CLI` set to
another executable;
- Claude Code on `PATH` or at `~/.local/bin/claude`;
- an authenticated Claude Code session.

## Security model
## Access modes

- The prompt is transferred over stdin, never argv or environment variables.
- Job directories use mode `0700`; job files use `0600`.
- Workspace access is explicit per job and canonicalized before launch.
- Workspace jobs expose only `Read`, `Glob`, and `Grep`.
- There is no automatic elapsed-time or idle timeout.
- Jobs survive an MCP server restart and are retained for 24 hours by default.
- At most four jobs run concurrently by default.
Without `workspace`, Claude receives only the supplied question and runs in
safe mode with no tools.

See [the plugin documentation](plugins/claude-ask/README.md) for protocol and
configuration details.
With an explicit absolute `workspace`, Claude runs as a full-access coding
agent. Its default tools, shell, file editing, user/project instructions and
hooks, network access, and configured MCP servers, skills, and plugins remain
available. Interactive permission checks are bypassed because the detached
process cannot answer prompts.

The workspace is Claude's working directory and intended task scope, not a
hard operating-system sandbox. Only pass trusted workspaces and prompts.

## Reliability and privacy

- Prompts travel over stdin, never argv, environment variables, state, or logs.
- Job directories use mode `0700`; private files use mode `0600`.
- Jobs survive MCP server restarts and remain discoverable through `list_jobs`.
- Boot-aware recovery avoids trusting reused PIDs after a machine restart.
- Cancellation terminates Claude's POSIX process group with
`SIGTERM → SIGKILL`.
- Stderr is capped at 1 MiB; failures expose at most a 4 KiB diagnostic tail.
- There is no automatic elapsed-time or idle-time cancellation.
- Completed plugin job data is retained for 24 hours by default; resumable
Claude sessions use Claude Code's normal session storage.

See [the plugin documentation](plugins/claude-ask/README.md) for the complete
protocol and configuration reference.

## Development

```bash
npm test
npm run check
```

The default test uses a fake Claude executable and consumes no model usage. An
explicit live smoke test is available after Claude authentication:
The default suite uses a fake Claude executable and consumes no model usage.
An authenticated paid/limited-usage smoke test is explicit:

```bash
npm run test:live
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "claude-ask-marketplace",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"description": "Codex marketplace for the Claude Ask plugin.",
"type": "module",
"scripts": {
"test": "node plugins/claude-ask/scripts/test-server.mjs",
"test:live": "CLAUDE_ASK_LIVE=1 node plugins/claude-ask/scripts/test-server.mjs",
"check": "node --check plugins/claude-ask/scripts/server.mjs && node --check plugins/claude-ask/scripts/job-runner.mjs && node --check plugins/claude-ask/scripts/test-server.mjs"
"check": "node --check plugins/claude-ask/scripts/lib.mjs && node --check plugins/claude-ask/scripts/server.mjs && node --check plugins/claude-ask/scripts/job-runner.mjs && node --check plugins/claude-ask/scripts/fixtures/fake-claude.mjs && node --check plugins/claude-ask/scripts/test-server.mjs"
},
"engines": {
"node": ">=22"
Expand Down
18 changes: 11 additions & 7 deletions plugins/claude-ask/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
{
"name": "claude-ask",
"version": "0.1.0+codex.20260716120619",
"description": "Ask local Claude Code Fable or Opus models from Codex.",
"version": "0.2.0",
"description": "Use local Claude Code as a persistent full-access coding agent or independent second opinion from Codex.",
"author": {
"name": "max"
},
"license": "MIT",
"keywords": [
"claude-code",
"sonnet",
"fable",
"opus",
"consultation"
"coding-agent"
],
"skills": "./skills/",
"mcpServers": "./.mcp.json",
"interface": {
"displayName": "Claude Ask",
"shortDescription": "Ask Claude Fable or Opus from Codex.",
"longDescription": "Adds persistent asynchronous consultation tools backed by the locally installed and authenticated Claude Code CLI.",
"shortDescription": "Run persistent Claude Code agents and follow-ups.",
"longDescription": "Adds persistent asynchronous Claude Code jobs with full-access workspace agents, resumable follow-ups, configurable effort and budgets, progress telemetry, job discovery, and structured diagnostics.",
"developerName": "max",
"category": "Productivity",
"capabilities": [
"Read",
"Write",
"Interactive"
],
"defaultPrompt": [
"Ask Claude for a second opinion.",
"Ask Opus to challenge this approach."
"Ask Sonnet for a quick independent opinion without repository tools.",
"Ask Claude to investigate and fix this issue, then run the tests.",
"Ask Opus for an independent review of this implementation.",
"Continue the previous Claude job with a focused follow-up."
]
}
}
104 changes: 52 additions & 52 deletions plugins/claude-ask/README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
# Claude Ask

A personal Codex plugin exposing asynchronous MCP tools backed by the local
Claude Code CLI.

The caller supplies the complete prompt and chooses `fable` or `opus`. For
ordinary consultations Claude runs with `--safe-mode` and no tools. For a code
review, the caller may pass an explicit absolute `workspace`; Claude then runs
with that directory as its real working directory and receives only the
built-in `Read`, `Glob`, and `Grep` tools. It cannot edit files or run shell
commands.

`ask` starts a detached background job and immediately returns a `job_id`.
Claude uses streaming JSON with partial messages and writes model output to a
private progress file. Poll `ask_status` until the file-backed job completes;
each response reports byte growth plus recent stream-event, partial-text, and
partial-thinking counters. There is no elapsed-time or idle-time deadline. An
unchanged file is a waiting job, never an automatic cancellation signal.

This asynchronous contract keeps every MCP `tools/call` short. The detached
runner survives an MCP server restart and the same `job_id` remains queryable.
A machine reboot or runner crash is reported explicitly as an interrupted job;
it is never presented as a model answer. Only explicit `cancel_ask`, the output
safety limit, Claude/runner failure, or operating-system termination ends work.

Job directories are mode 0700 and every state, result, cancel, and stream file
is mode 0600. The prompt is never put in argv, environment variables, state, or
diagnostic logs: it goes directly to the runner and Claude over stdin. Claude's
private output stream and completed result are retained for 24 hours, then
removed. At most four jobs run concurrently by default.

## Requirements

- Claude Code available at `~/.local/bin/claude`, or set `CLAUDE_ASK_CLI`.
- A working Claude Code login (`claude auth status`).
A personal Codex plugin that exposes local Claude Code Sonnet 5, Fable, and Opus as persistent asynchronous MCP jobs.

## Test
Sonnet with `high` effort is the default. Each job can select `medium`, `high`, `xhigh`, or `max` effort, set a human-readable name, and enforce a `max_budget_usd` ceiling.

```bash
node scripts/test-server.mjs
```
## Tools

| Tool | Purpose |
|---|---|
| `ask` | Start a new advisory or workspace-agent job |
| `ask_followup` | Resume a completed job's Claude session and fork an independent branch |
| `ask_status` | Wait for progress or retrieve the terminal result |
| `list_jobs` | List recent jobs and recover lost IDs |
| `cancel_ask` | Explicitly cancel a running job and its process tree |

`ask` returns a `job_id` immediately. Poll `ask_status` until the status is `completed`, `error`, or `cancelled`. There is no elapsed-time or idle-time deadline; unchanged output means the job is still waiting. Progress includes output bytes, estimated thinking tokens, tool-call count, elapsed time, and the last event type.

The test uses a fake Claude executable and does not consume model usage.
Completed sessions remain resumable in Claude Code's normal session storage, outside the plugin job directory and its 24-hour cleanup. `ask_followup` inherits the parent model, workspace, mode, and effort unless effort is overridden. It uses Claude Code resume-and-fork semantics, so the parent remains unchanged. A budget applies only to the new call.

After authenticating Claude Code, an explicit paid/limited-usage smoke test is available with `CLAUDE_ASK_LIVE=1 node scripts/test-server.mjs`.
## Access modes

Optional controls are `CLAUDE_ASK_JOB_DIR`,
`CLAUDE_ASK_MAX_CONCURRENT_JOBS`, `CLAUDE_ASK_MAX_OUTPUT_BYTES`, and
`CLAUDE_ASK_COMPLETED_RETENTION_MS`. None of them is a wall-clock or idle
deadline.
Without `workspace`, Claude runs in advisory safe mode with no tools and receives only the supplied question.

## Workspace reviews
With an explicit absolute `workspace`, Claude runs as a full autonomous coding agent. Its normal default tools, shell, file editing, user/project instructions and hooks, network access, and configured MCP servers, skills, and plugins remain available. Interactive permission prompts are bypassed because a detached job cannot answer them.

The `ask` input accepts:
The workspace is Claude's actual working directory and intended task scope, not a hard operating-system sandbox. Claude runs as the current user and can technically access other paths and the network. Only pass trusted workspaces and prompts.

Example:

```json
{
"question": "Review the current implementation and report blockers.",
"model": "fable",
"workspace": "/absolute/path/to/repository"
"question": "Investigate the failure, implement a fix, run the relevant tests, and summarize the result.",
"model": "sonnet",
"workspace": "/absolute/path/to/repository",
"name": "fix flaky integration test",
"effort": "high",
"max_budget_usd": 5
}
```

The workspace must already exist and be an absolute directory. It is
canonicalized before the job starts, recorded in private job state for audit,
and returned by `ask_status`. Workspace access is opt-in per job; no global
working-directory environment variable is used.
## Persistence and diagnostics

Jobs survive MCP server restarts and remain queryable by ID. Boot-aware recovery distinguishes a live detached runner from an interrupted job. Cancellation signals Claude's whole process group on POSIX systems, with a direct-child fallback on Windows.

Errors return structured `error_code`, `next_action`, `stderr_tail`, and `stderr_truncated` fields. Claude stderr is stored privately up to 1 MiB; only a bounded 4 KiB tail is returned. Output-limit errors warn that workspace changes may already exist.

Job directories use mode 0700; state, result, stream, stderr, and cancellation files use mode 0600. Prompts never appear in argv, environment variables, state, or diagnostic logs: they travel over stdin. Completed data is retained for 24 hours by default. Up to four jobs run concurrently.

## Requirements and tests

- Claude Code on `PATH` or at `~/.local/bin/claude`; alternatively set `CLAUDE_ASK_CLI`.
- A working Claude Code login (`claude auth status`).

Run the no-usage test suite:

```bash
node scripts/test-server.mjs
```

An authenticated paid/limited-usage smoke test is opt-in:

```bash
CLAUDE_ASK_LIVE=1 node scripts/test-server.mjs
```

Optional controls are `CLAUDE_ASK_JOB_DIR`, `CLAUDE_ASK_MAX_CONCURRENT_JOBS`, `CLAUDE_ASK_MAX_OUTPUT_BYTES`, and `CLAUDE_ASK_COMPLETED_RETENTION_MS`. None sets a wall-clock or idle deadline.
Loading
Loading