termalin-web

Run commands and read/write files on your servers over Termalin's keyless tunnels (hosted MCP).

Should I use this

Quality & Safety

A
Description quality
100%
Schema completeness
90%
Naming quality
83%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~1,533Tokens (tool definitions)
~1.2 KBTypical response size
Moderate attention impact (1.20% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "termalin-web": {
      "url": "https://termal.in/api/v1/mcp"
    }
  }
}

Remote endpoints

https://termal.in/api/v1/mcpstreamable-http

What it can do

Tool inventory

Tools (8)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢hosts_list

List the servers reachable through Termalin (your tunnel agents). Returns id, name, whether the server is online, and the default login user. Use the id with ssh_exec.

Input Schema

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
🟢generate_password(length)

Generate a strong random password — handy when creating a user or setting a password on a server. Returns the password only; nothing is stored.

Input Schema

{
  "type": "object",
  "properties": {
    "length": {
      "type": "integer",
      "description": "length (default 20, 8-128)"
    }
  },
  "additionalProperties": false
}
🔴ssh_exec(host, command, username, timeoutSeconds)

Run a single shell command on one of your servers and return its combined output and exit code. Runs keyless over Termalin's tunnel — no SSH key, and the server needs no open inbound port. Each call is a fresh shell (cd does not persist — chain with &&). Keep a call under about 90 seconds: for anything longer, start it in the background (nohup … > log 2>&1 &) and check on it with later calls.

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "command": {
      "type": "string",
      "description": "Shell command to execute"
    },
    "username": {
      "type": "string",
      "description": "Login user (defaults to the tunnel's user, else root)"
    },
    "timeoutSeconds": {
      "type": "number",
      "description": "Max seconds to wait (default 60). Calls longer than about 90 seconds are usually cut off by the network before they answer — run long jobs in the background instead."
    }
  },
  "required": [
    "host",
    "command"
  ],
  "additionalProperties": false
}
🟢sftp_list(host, path, username)

List a directory on one of your servers over SFTP. Returns each entry's name, whether it's a directory, size and modified time. Runs keyless over Termalin's tunnel, like ssh_exec.

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "path": {
      "type": "string",
      "description": "Directory to list (default the login home, \".\")"
    },
    "username": {
      "type": "string",
      "description": "Login user (defaults to the tunnel's user, else root)"
    }
  },
  "required": [
    "host"
  ],
  "additionalProperties": false
}
🟢sftp_read(host, path, username)

Read a text file from one of your servers over SFTP and return its contents. Files over 512 KB or non-text (binary) files are refused — use ssh_exec (e.g. sed/tail) for those.

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "path": {
      "type": "string",
      "description": "Absolute or home-relative file path"
    },
    "username": {
      "type": "string",
      "description": "Login user (defaults to the tunnel's user, else root)"
    }
  },
  "required": [
    "host",
    "path"
  ],
  "additionalProperties": false
}
🔴sftp_write(host, path, content, username)

Create or overwrite a text file on one of your servers over SFTP. 'content' is written as UTF-8. Capped at 512 KB; for binary uploads use a terminal/scp instead.

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "path": {
      "type": "string",
      "description": "Destination file path (created or overwritten)"
    },
    "content": {
      "type": "string",
      "description": "UTF-8 text to write"
    },
    "username": {
      "type": "string",
      "description": "Login user (defaults to the tunnel's user, else root)"
    }
  },
  "required": [
    "host",
    "path",
    "content"
  ],
  "additionalProperties": false
}
🔴data_query(host, engine, query, database, username, ...)

Run a database query on one of your servers — passwordless. It executes the engine's own client on the host over Termalin's keyless tunnel, using the database's local trust (Postgres peer auth via `sudo -u postgres`, MySQL/MariaDB unix-socket via `sudo mysql`, redis-cli, mongosh, sqlite3) — so no database password is needed or stored anywhere. Read-only by default: only SELECT/SHOW-style statements run unless allowWrites is set (full-access keys only). SQL engines return CSV/TSV with a header. For MongoDB pass a shell expression, e.g. db.products.find({}).limit(20).toArray().

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "engine": {
      "type": "string",
      "enum": [
        "postgres",
        "mysql",
        "mariadb",
        "redis",
        "mongodb",
        "sqlite"
      ],
      "description": "Database engine on that server (default postgres)"
    },
    "query": {
      "type": "string",
      "description": "The statement / command / expression to run"
    },
    "database": {
      "type": "string",
      "description": "Database name (for sqlite: the .db file path)"
    },
    "username": {
      "type": "string",
      "description": "SSH login user (defaults to the tunnel's user, else root)"
    },
    "allowWrites": {
      "type": "boolean",
      "description": "Allow a non-read statement (full-access keys only; default false)"
    },
    "timeoutSeconds": {
      "type": "number",
      "description": "Max seconds to wait (default 60). Calls longer than about 90 seconds are usually cut off by the network before they answer — run long jobs in the background instead."
    }
  },
  "required": [
    "host",
    "query"
  ],
  "additionalProperties": false
}
🟢data_tables(host, engine, database, username)

List the tables / collections / keys of a database on one of your servers — passwordless, over the same local-client path as data_query.

Input Schema

{
  "type": "object",
  "properties": {
    "host": {
      "type": "string",
      "description": "Server id from hosts_list"
    },
    "engine": {
      "type": "string",
      "enum": [
        "postgres",
        "mysql",
        "mariadb",
        "redis",
        "mongodb",
        "sqlite"
      ],
      "description": "Database engine on that server (default postgres)"
    },
    "database": {
      "type": "string",
      "description": "Database name (for sqlite: the .db file path)"
    },
    "username": {
      "type": "string",
      "description": "SSH login user (defaults to the tunnel's user, else root)"
    }
  },
  "required": [
    "host"
  ],
  "additionalProperties": false
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded8 tools
verifiedversion not recorded8 tools
verifiedversion not recorded8 tools