Sign inSign up

superbizon007/linux-terminal-agent

By superbizon007

Updated 5 months ago

A Docker image that runs an SSH-backed Linux terminal with an AI agent, exposed via A2A

Image
Machine learning & AI
0

946

superbizon007/linux-terminal-agent repository overview

Linux Terminal Agent

A Docker image that runs an SSH-backed Linux terminal with an AI agent, exposed via A2A and OpenAI-compatible HTTPS APIs, and a browser-accessible xterm.js terminal UI.

Implements an agent using the ReAct (Reasoning + Acting) pattern for intelligent terminal orchestration.

Overview

The container bundles:

  • OpenSSH server — provides a real PTY for the xterm.js terminal and SSH execution for agent tools
  • xterm.js terminal — full-featured browser terminal accessible at https://localhost/
  • Python agent server — FastAPI service that accepts tasks and autonomously controls the Linux shell using a text LLM via LangGraph

The agent runs shell commands, reads/writes files, and inspects system state — repeating until the task is complete or the step budget is exhausted.


Features

FeatureDetails
Browser terminalxterm.js UI with WebSocket PTY relay to SSH — full ANSI/color support
Shell automationAI agent executes shell commands via SSH to complete tasks
LLM-driven agentAny OpenAI-compatible LLM (GPT-4o, Claude, Gemini, local models)
Loop detectionWarns the LLM after 2 consecutive identical actions
A2A APIGoogle Agent-to-Agent JSON-RPC 2.0 protocol
OpenAI-compatible API/v1/chat/completions endpoint — drop-in for OpenAI clients
HTTPSSelf-signed TLS certificate generated at startup

Quick Start

Build
cd apps/linux_terminal_agent
docker build --build-context a2a_pkg=../../packages/a2a_agent -f Dockerfile.ubuntu -t linux_terminal_agent:ubuntu .
Run
docker run -d \
  --name terminal_agent \
  -p 443:443 \
  -p 2222:22 \
  -e LLM_URL=https://api.openai.com/v1 \
  -e LLM_API_KEY=sk-... \
  -e LLM_MODEL=gpt-4o \
  linux_terminal_agent:ubuntu
Access
ServiceURL / Address
Browser terminalhttps://localhost/
Agent API (A2A + OpenAI)https://localhost/
SSH (direct)ssh root@localhost -p 2222 (password: agent)
Trust the certificate (one-time)

The container generates a local CA on first start. Install it once and your browser will trust all future connections without warnings.

macOS:

curl -k https://localhost/ca.crt -o linux-terminal-agent-ca.crt
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain linux-terminal-agent-ca.crt

Linux (Debian/Ubuntu):

curl -k https://localhost/ca.crt -o /usr/local/share/ca-certificates/linux-terminal-agent-ca.crt
sudo update-ca-certificates

Windows:

curl -k https://localhost/ca.crt -o linux-terminal-agent-ca.crt
certutil -addstore Root linux-terminal-agent-ca.crt

Chrome / Firefox (manual): download https://localhost/ca.crt then add it in Settings → Privacy and security → Manage certificates → Authorities → Import.


API

A2A — send a task
curl -sk -X POST https://localhost/ \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "tasks/send",
    "params": {
      "id": "task-1",
      "message": {
        "role": "user",
        "parts": [{"text": "List the files in /etc and tell me the OS version"}]
      }
    }
  }'
OpenAI-compatible
curl -sk -X POST https://localhost/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "terminal-agent",
    "messages": [{"role": "user", "content": "What OS is this and how much disk space is free?"}]
  }'
Agent card
curl -sk https://localhost/.well-known/agent.json
Streaming (A2A)
curl -sk -N -X POST https://localhost/ \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "tasks/sendSubscribe",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"text": "Find all Python files larger than 100KB"}]
      }
    }
  }'

Environment Variables

Core
VariableDefaultDescription
LLM_URLhttps://api.openai.com/v1Base URL of the LLM API
LLM_API_KEYAPI key for the LLM
LLM_MODELgpt-4oModel name
SSH_HOSTlocalhostSSH server host for agent tools
SSH_PORT22SSH server port
SSH_USERrootSSH username
SSH_PASSWORDSSH password
SSH_KEY_PATHPath to SSH private key file (alternative to password)
API_KEYBearer token to protect the agent API (optional)
PORT443HTTPS port for the agent server
AGENT_URLPublic URL published in the AgentCard (e.g. https://my-agent.example.com/). Defaults to https://localhost:{PORT}/
Trajectory recording (optional)
VariableDefaultDescription
TRAJECTORY_DIRDirectory to save trajectory data; each run creates a YYYYMMDD_HHMMSS/ subdirectory

When TRAJECTORY_DIR is set, each agent run creates a timestamped subdirectory containing one folder per step:

$TRAJECTORY_DIR/
  20260304_181523/              # run timestamp (YYYYMMDD_HHMMSS)
    turn_0000/
      llm_0_request.json        # task, step, model, full message history sent to LLM
      llm_0_response.json       # raw reply, parsed action/args/reasoning, token usage
      command.json              # action, args, shell output, duration_ms
    turn_0001/
      ...
  20260304_182041/              # next run
    ...

Example:

docker run -d \
  -e LLM_URL=... -e LLM_API_KEY=... \
  -e TRAJECTORY_DIR=/data/traj \
  -v /tmp/agent-traj:/data/traj \
  linux_terminal_agent:ubuntu

Agent Tools

ToolDescription
run_commandRun a shell command, return stdout/stderr/exit_code
list_processesList running processes (ps aux)
kill_processSend a signal to a process
get_system_infouname, CPU, memory, and disk summary
list_dirList directory contents (ls -la)
read_fileRead a file (up to max_bytes)
write_fileWrite content to a file
patch_fileApply a unified diff to a file
grep_textSearch files for a pattern (ripgrep / grep fallback)
http_requestMake an HTTP request via curl
tail_fileReturn the last N lines of a file
get_resource_usageCPU/memory/disk/GPU usage snapshot

Architecture

┌──────────────────────────────────────────────┐
│               Docker Container               │
│                                              │
│  OpenSSH server (:22)                        │
│         │                                    │
│         ├── xterm.js PTY relay               │
│         │   (WebSocket /ws/terminal)         │
│         │                                    │
│         └── Agent tool calls                 │
│             (run_command, read_file, ...)     │
│                                              │
│  LangGraph (graph.py)                        │
│    call_llm ──► LLM (OpenAI-compatible)      │
│    execute_action                            │
│                                              │
│  FastAPI Server (:443 HTTPS)                 │
│    ├── GET  /              xterm.js UI       │
│    ├── GET  /ws/terminal   PTY WebSocket     │
│    ├── POST /              A2A JSON-RPC      │
│    └── POST /v1/...        OpenAI-compat     │
└──────────────────────────────────────────────┘

License

MIT

MCP tools

The agent image exposes an MCP (Model Context Protocol) server on the same port as A2A at /mcp. Any MCP client — Claude Desktop, Cursor, Windsurf, ChatGPT Connectors, OpenAI Agents SDK — can list and invoke these tools using the pod's API_KEY as Bearer.

In production, Core proxies https://linux-terminal-agent.agents.forfetch.ai/mcp → the worker pod's /mcp.

Tool (skill_id)Description
run_commandExecute a shell command
write_fileWrite content to a file
read_fileRead content from a file
list_dirList directory contents
install_packageInstall a system or language package

Input schemas are authored in apps/agents_mcp/app/seed.py. Skills without an explicit schema advertise a single {task: str} freeform parameter.

Tag summary

Content type

Image

Digest

sha256:ae8de3137

Size

251.1 MB

Last updated

5 months ago

docker pull superbizon007/linux-terminal-agent