Skip to main content
Glama
AcosX

Terminal MCP Server

by AcosX

Terminal MCP Server

Terminal MCP Server exposes one MCP tool, run_command, that runs shell commands on the host and returns stdout, stderr, exit code, duration, timeout status, and truncation status.

I personally use it with ChatGPT, so ChatGPT can access my local system in a Codex-like way.

This is intentionally powerful. If the service runs as root, the MCP client has root shell capability. Put it behind HTTPS, require OAuth/OIDC authentication, restrict who can receive the required scope, and review audit logs.

Features

  • Streamable HTTP MCP transport.

  • run_command tool implemented with bash -lc.

  • JWT access-token validation through any OAuth/OIDC server that publishes JWKS.

  • Optional direct Microsoft Entra ID validation.

  • Optional bearer-token and in-memory OAuth modes for local testing.

  • OAuth protected-resource metadata for ChatGPT and other MCP clients.

  • JSON-lines audit log with command, result metadata, source IP, session ID, and non-secret token claims.

Related MCP server: shell-mcp

Demo

Use a real OAuth/OIDC authorization server in front of this MCP server:

MCP client -> Terminal MCP Server
              |
              validates JWT access token
              |
              OAuth/OIDC authorization server

The authorization server should:

  • authenticate users with your preferred identity providers;

  • decide which users may receive the command-execution scope;

  • issue JWT access tokens with a stable issuer, audience, and scope;

  • expose a JWKS endpoint.

The MCP server only validates tokens. It does not need client secrets for the OAuth client used by ChatGPT or another MCP client.

Quick Start

python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
set -a
. ./.env
set +a
python server.py

The MCP endpoint is:

http://127.0.0.1:8767/mcp

For production, put HTTPS in front of the service and set MCP_RESOURCE_BASE_URL to the public origin, for example:

MCP_RESOURCE_BASE_URL=https://mcp.example.com

The advertised MCP resource becomes:

https://mcp.example.com/mcp

Configuration

Common settings:

MCP_HOST=127.0.0.1
MCP_PORT=8767
MCP_TRANSPORT=streamable-http
MCP_COMMAND_TIMEOUT=30
MCP_COMMAND_MAX_TIMEOUT=120
MCP_MAX_OUTPUT_BYTES=131072
MCP_AUDIT_LOG=/var/log/terminal-mcp/audit.log

Recommended JWT mode:

MCP_AUTH_MODE=jwt
MCP_JWKS_URI=https://auth.example.com/jwks
MCP_JWT_ISSUER=https://auth.example.com
MCP_JWT_AUDIENCE=https://mcp.example.com/mcp
MCP_JWT_ALGORITHM=RS256
MCP_REQUIRED_SCOPES=terminal.run
MCP_ADVERTISED_SCOPES=terminal.run
MCP_OAUTH_ISSUER=https://auth.example.com
MCP_RESOURCE_BASE_URL=https://mcp.example.com

The token must contain the required scope. Depending on your provider this is usually represented as scp, scope, or a compatible claim understood by FastMCP's JWT verifier.

OAuth Discovery Endpoints

The server exposes:

/.well-known/oauth-protected-resource
/.well-known/oauth-protected-resource/mcp
/.well-known/oauth-authorization-server

MCP_OAUTH_ISSUER controls the authorization-server issuer advertised to MCP clients. For a generic OAuth/OIDC provider, that issuer is normally your auth server origin.

ChatGPT Connector Setup

Use these values when creating a ChatGPT connector:

Server URL: https://mcp.example.com/mcp
OAuth client ID: <client id from your authorization server>
OAuth client secret: <client secret from your authorization server>
Authorization URL: https://auth.example.com/authorize
Token URL: https://auth.example.com/token
Scope: terminal.run

If ChatGPT sends a resource parameter during OAuth, configure MCP_JWT_AUDIENCE to match the access token audience issued for that resource, often the full MCP resource URL:

MCP_JWT_AUDIENCE=https://mcp.example.com/mcp

Microsoft Entra ID Direct Mode

You can validate Entra ID tokens directly:

MCP_AUTH_MODE=entra
MCP_ENTRA_TENANT_ID=<tenant-id>
MCP_ENTRA_AUDIENCE=api://<api-application-client-id>
MCP_REQUIRED_SCOPES=terminal.run
MCP_ENTRA_ALLOWED_OIDS=<allowed-user-object-id>[,<another-object-id>]

Use two app registrations:

1. API app: exposes the terminal.run delegated scope.
2. Client app: has the MCP client's redirect URI and a client secret.

MCP_ENTRA_ALLOWED_OIDS is optional but strongly recommended. When set, only those Entra user object IDs can call run_command.

Local Testing Modes

Bearer-token mode:

MCP_AUTH_MODE=bearer
MCP_BEARER_TOKEN=<random token>

Development OAuth mode:

MCP_AUTH_MODE=memory_oauth
MCP_PUBLIC_BASE_URL=https://mcp.example.com
MCP_RESOURCE_BASE_URL=https://mcp.example.com
MCP_OAUTH_CLIENT_ID=terminal-mcp
MCP_OAUTH_CLIENT_SECRET=<random secret>
MCP_OAUTH_REDIRECT_URIS=https://chatgpt.com/connector/oauth/<connector-id>

Do not use memory_oauth in production. Tokens and client registrations are in-memory and restart-sensitive.

systemd

An example unit is available at:

examples/terminal-mcp.service

Typical layout:

/opt/terminal-mcp/server.py
/opt/terminal-mcp/.venv
/etc/terminal-mcp/env

Install and start:

sudo cp examples/terminal-mcp.service /etc/systemd/system/terminal-mcp.service
sudo systemctl daemon-reload
sudo systemctl enable --now terminal-mcp.service

Audit Log

Command calls are appended as JSON lines to MCP_AUDIT_LOG. The audit record contains command metadata and non-secret authentication context. It does not log access tokens.

Security Notes

  • Prefer running with the minimum Linux privileges needed for your use case.

  • Restrict terminal.run issuance in your authorization server.

  • Put HTTPS and a WAF or reverse proxy in front of the service.

  • Keep client secrets in the OAuth client or authorization server, not in this MCP resource server.

  • Rotate keys and review audit logs regularly.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Give hands to AI. MCP server to run shell commands securely, auditably, and on demand.
    105
    GPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables secure execution of shell commands via MCP with multiple security layers including command whitelisting and directory restrictions.
    23 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables LLM clients to execute shell commands safely through the MCP protocol, with features like session management, safe mode, and process control.
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes a Windows or Linux host terminal to remote MCP clients via Streamable HTTP, enabling command execution, tunnel management, and privileged operations with security features like OAuth and audit logging.
    26 npm
    2
    MIT