task-mcp
Agent-safe task runner MCP server backed by just.
Exposes predefined justfile recipes as MCP tools, with access control via the [allow-agent] group attribute.
Tools
| Tool | Description | Annotations |
|---|---|---|
session_start |
Set the working directory for this session. Must be called before run or list (unless list is given an explicit justfile path). |
destructive |
list |
List available tasks from justfile. Returns names, descriptions, parameters, and groups. Requires session_start when no justfile parameter is given. |
read-only, idempotent |
run |
Execute a predefined task. Only tasks visible in list can be run. Requires session_start. |
destructive |
logs |
Retrieve execution logs of recent runs. Returns summary list or full output by task ID. | read-only, idempotent |
info |
Show current session state: active workdir, resolved justfile path, and task mode. | read-only, idempotent |
Installation
Requires just to be installed and available on PATH.
Usage
Start as MCP server (stdio transport):
Claude Code integration
Add to your Claude Code MCP configuration:
Configuration
Configuration is loaded from .task-mcp.env in the current directory (if present), then from environment variables.
| Variable | Default | Description |
|---|---|---|
TASK_MCP_MODE |
agent-only |
agent-only: only [allow-agent] tagged recipes; all: all non-private recipes |
TASK_MCP_JUSTFILE |
auto-detect | Path to justfile (relative or absolute) |
TASK_MCP_ALLOWED_DIRS |
(any) | Comma-separated list of directories allowed as session working directories. If unset, any directory is accepted. Paths are canonicalized on parse. |
.task-mcp.env example:
TASK_MCP_MODE=agent-only
TASK_MCP_JUSTFILE=./justfile
TASK_MCP_ALLOWED_DIRS=/home/user/projects/my-project,/home/user/projects/other-project
Justfile setup
Mark recipes as agent-safe using the [group('agent')] attribute:
# Build the project
[group('agent')]
build:
cargo build --release
# Run tests
[group('agent')]
test filter="":
cargo test {{filter}}
# Deploy to production — NOT exposed to agent
deploy:
./scripts/deploy.sh
In agent-only mode (default), only build and test are returned by list and executable via run. The deploy recipe is hidden.
In all mode, all non-private recipes are exposed.
Workflow
The typical agent workflow is:
- Call
session_startwith the project directory to establish the working context. - Call
listto discover available tasks. - Call
runto execute a task. - Call
logsto inspect output of a past run. - Call
infoat any point to confirm the current session state.
list can also be called without a prior session_start when an explicit justfile path is provided — this is useful for exploration before committing to a working directory.
Tool details
session_start
workdir: absolute path to the project directory; must be accessible and, ifTASK_MCP_ALLOWED_DIRSis set, must fall within one of the allowed directories- Returns a confirmation message with the resolved path on success
info
No parameters required. Returns:
workdir: active working directory (ornullifsession_starthas not been called)justfile: resolved justfile path (ornullif not resolvable from the current session state)mode: current task mode (agent-onlyorall)
list
filter: optional group name to narrow resultsjustfile: optional path override
run
task_name: must appear inlistoutputargs: named arguments matching recipe parameter namestimeout_secs: default 60
Returns a TaskExecution object with id, exit_code, stdout, stderr, duration_ms, and truncated fields.
logs
task_id: omit to get summary of the 10 most recent executions; provide to get full outputtail: restrict stdout to the last N lines (only whentask_idis provided)
In-memory only; logs are lost on server restart.
Output truncation
stdout and stderr are capped at 100 KB per execution. When truncated, the truncated field is true and the head and tail of the output are preserved. Use logs with tail to retrieve specific portions.
Security
- Only recipes whitelisted by
listcan be executed viarun session_startvalidates the requested directory againstTASK_MCP_ALLOWED_DIRSusing canonicalizedPath::starts_with; symlinks are resolved before comparison to prevent traversal attacks- Argument values are validated to reject shell metacharacters
- Execution timeout is enforced (default: 60 s)
open_world_hint = falseon all tools: no external network calls
License
MIT OR Apache-2.0