artaxnetwork-dev/artax-terminal
If you are the rightful owner of artax-terminal and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
artax-terminal is a Model Context Protocol (MCP) server that provides secure and auditable terminal capabilities to AI agents.
artax-terminal
A Model Context Protocol (MCP) tool and server that grants safe, auditable terminal capabilities to AI agents. artax-terminal exposes an HTTP API and a real-time socket stream so AI clients can run allowed shell commands, receive live stdout/stderr, and operate within strict security and resource limits.
Overview
- MCP Server hosted with Laravel ("Laravel MCP")
- Exposes tools to AI via HTTP API and WebSocket streaming
- Enforces command allowlists, working directory boundaries, timeouts, and output limits
- Authenticated access with full audit logging and request tracing
artax-terminal focuses on the single most useful capability for operator-style AIs: safely running terminal commands, with optional read-only filesystem helpers. The system is designed to be composable and easy to integrate into MCP-compatible clients.
What is MCP?
MCP (Model Context Protocol) is a pattern for connecting AI systems to external tools and data. An MCP server declares one or more "tools" (operations) with input/output schemas. AI clients call these tools over HTTP/WebSocket (or JSON-RPC-like flows), optionally with streaming for long-running tasks.
Features
- Terminal execution (
run_command) with:- Command allowlist and argument validation
- CWD restrictions to a configured base directory
- Timeouts, max output size, and resource limits
- Streaming stdout/stderr via WebSocket or SSE
- Optional read-only file helpers:
list_dir,read_file(disabled by default) - Structured audit logs of every invocation
- Token-based authentication for API and socket
- Clear MCP tool schemas for easy client adoption
Architecture
- Laravel application hosts the MCP server endpoints
- HTTP API for non-streaming or batched responses
- Real-time socket (WebSocket or SSE) for streaming output from running commands
- Background executor service wraps shell commands with safety policies
- Audit and trace context attached to each request/session
Typical flow:
- Client authenticates and calls
run_commandover HTTP or JSON-RPC. - Server validates command against allowlist, spawns an executor in a controlled environment.
- Output streams over a socket channel; final result (exit code, summarized output) is returned.
Security Model
- Allowlist-only commands; no wildcard execution
- Restrict to
ARTAX_BASE_DIRfor CWD and file access - Per-command
timeout_msandmax_output_kbcaps - Non-root user recommended; container/sandbox strongly encouraged
- Full request/response logging; optional redact patterns for secrets
Important: Never deploy with unrestricted commands. Always scope paths, users, and resources.
Quick Start
Prerequisites
- PHP 8.2+ and Composer
- Laravel 10+ (or 11+) installed in the project
- Optional: Laravel Reverb (WebSocket) or SSE for streaming
Setup
- Clone this repo.
- Install dependencies:
composer install - Copy env:
cp .env.example .env(or create.env) - Configure core variables:
ARTAX_ALLOWED_COMMANDS="ls,cat,pwd,git"
ARTAX_BASE_DIR="/path/to/safe/workspace"
ARTAX_TIMEOUT_MS=30000
ARTAX_MAX_OUTPUT_KB=256
ARTAX_AUTH_TOKEN="replace-with-strong-token"
ARTAX_STREAM_DRIVER="websocket" # or "sse"
- Start the HTTP server:
php artisan serve - If using WebSockets (e.g., Laravel Reverb), start the socket server:
php artisan reverb:start
Health Check
GET /api/mcp/health→{ "status": "ok" }
MCP Tools
1) run_command
- Description: Run an allowed shell command with optional args and stream output.
- Input schema:
{
"command": "string", // must be in allowlist
"args": ["string"], // optional, validated per command policy
"cwd": "string", // optional; must be within ARTAX_BASE_DIR
"timeout_ms": 30000, // optional override
"stream": true // enable streaming over socket/SSE
}
- Non-streaming response:
{
"status": "completed",
"exit_code": 0,
"stdout": "...",
"stderr": "...",
"truncated": false
}
- Streaming response (initial HTTP):
{
"status": "started",
"session_id": "abc123",
"channel": "mcp.run.abc123" // socket topic name
}
- Socket events (examples):
{
"type": "output",
"stream": "stdout", // or "stderr"
"chunk": "..."
}
{
"type": "exit",
"exit_code": 0
}
{
"type": "error",
"message": "timeout"
}
2) list_dir (optional, read-only)
- Input:
{ "path": "string" }withinARTAX_BASE_DIR - Output: file/directory listing with metadata
3) read_file (optional, read-only)
- Input:
{ "path": "string", "max_bytes": 65536 }withinARTAX_BASE_DIR - Output: file contents (truncated if necessary)
Note: These helpers are disabled by default. Enable only if needed and keep read-only.
HTTP API
POST /api/mcp/run- Body:
run_commandschema (see above) - Headers:
Authorization: Bearer ${ARTAX_AUTH_TOKEN}
- Body:
GET /api/mcp/health
Optional streaming (SSE):
GET /api/mcp/sessions/{session_id}/events→ server-sent events
WebSocket (Laravel Reverb)
- Connect to your configured Reverb host/port
- Subscribe to
mcp.run.{session_id}for event stream - Events follow the shapes described above
Example Client (Node/TypeScript)
import fetch from "node-fetch";
async function runLs() {
const res = await fetch("https://your-host/api/mcp/run", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.ARTAX_AUTH_TOKEN}`,
},
body: JSON.stringify({
command: "ls",
args: ["-la"],
cwd: "/path/to/safe/workspace",
stream: false,
}),
});
const data = await res.json();
console.log(data);
}
runLs();
Configuration
ARTAX_ALLOWED_COMMANDS— comma-separated allowlist of commandsARTAX_BASE_DIR— root for allowed working directoriesARTAX_TIMEOUT_MS— default timeout per commandARTAX_MAX_OUTPUT_KB— maximum captured output per commandARTAX_AUTH_TOKEN— bearer token for HTTP/socket authARTAX_STREAM_DRIVER—websocketorsse
Operational Guidance
- Run as a non-root service account
- Prefer containerized execution or sandbox (e.g.,
docker execwrapper) - Keep allowlists tight; validate args per command where possible
- Log all invocations; consider redaction of sensitive patterns
- Set conservative timeouts and output limits
Roadmap
- Fine-grained per-command argument schemas
- Container-based command isolation
- File write helpers with explicit opt-in and approvals
- Multi-tenant authentication and quotas
- Rich MCP tool discovery via JSON-RPC endpoints
Contributing
Issues and PRs are welcome. Please include:
- Clear problem statement
- Reproduction steps
- Security impact assessment (if touching executor or auth)
License
Copyright © You. All rights reserved. If you plan to open source this project, consider adopting MIT or Apache-2.0 and update this section accordingly.