Skip to main content
Glama

server-mcp

An MCP server that lets Claude manage Linux servers and Docker. It works over SSH (key or password) or on the local machine. Nothing is installed on the servers.

Every change shows a preview first and waits for your yes.

What Claude can do

  • Docker: list, logs, inspect, stats, start, stop, restart, build, run, copy files, Compose stacks, images, volumes, networks, or any docker command with docker_cli.

  • System: info, processes, services (systemd), logs (journal), packages (apt, dnf, apk), reboot and power off.

  • Files: read, write, edit, move, delete and list on any path. File edits show a diff before they run.

  • Shell: server_run. Safe read commands run at once. Others need approval.

  • Background jobs: add background=true to server_run, server_packages or docker_cli for long work. You get a job id back at once. Use server_job to list, check, read output, cancel or clean.

  • sudo: tools with as_root run as root. Root actions always show a preview.

Related MCP server: SSH MCP Server

How approval works

  1. Claude calls a tool that changes something.

  2. It gets back a preview: the host, the action, the exact command, and a diff for files.

  3. You say yes.

  4. Claude repeats the same call with confirm=true. It runs only if that exact preview was shown in the last 15 minutes. Each preview works once.

Set SERVER_MCP_READ_ONLY=true to refuse all changes.

Secrets

Passwords, tokens and keys are hidden in everything Claude sees. Files such as .env, private keys and credential files are never read or written.

Install

Nothing to install by hand. Add it to your Claude config with uvx, as in claude_desktop_config.example.json. It downloads the tool from GitHub and runs the server-mcp command.

To run from a local copy instead: pip install ., then use the command server-mcp.

Settings

All settings are environment variables. The full list is at the top of server_mcp/server.py.

Setting

Meaning

SERVER_MCP_HOSTS_NAME

Your hosts, as name=address pairs (or address=name). Separate with commas, semicolons or new lines. Every pair is a host.

SERVER_MCP_HOST_1, SERVER_MCP_HOST_2, ...

One pair per setting, so each host is on its own line in the config. They add to SERVER_MCP_HOSTS_NAME.

SERVER_MCP_HOSTS

Optional. A plain list of hosts without names. Empty and no pairs means this machine.

SERVER_MCP_SSH_USER, _SSH_KEY, _SSH_PASSWORD, _SSH_PORT

Login for all hosts. Use a key or a password.

SERVER_MCP_SUDO, _SUDO_PASSWORD

Use sudo for docker and root actions. The SSH password is used for sudo too, unless you set a separate sudo password.

SERVER_MCP_<NAME>_...

Any setting for one host only.

SERVER_MCP_FILE_ROOTS

Limit the file tools to some folders.

SERVER_MCP_READ_ONLY

Refuse every change.

Safety notes

  • Use a dedicated account where you can, and give it only the sudo rights you want Claude to have.

  • Passwords in environment variables are stored in your Claude config file. Prefer SSH keys.

  • New SSH host keys are trusted on first use, then checked. Use this on networks you trust, or set SERVER_MCP_SSH_STRICT=true.

Tests

python tests/test_server.py

License

MIT

Available Tools

42 tools
docker_buildA

Build an image with docker build. Needs confirm=true.

context is a folder on the host (in an allowed folder) or an https git URL such as https://github.com/example/repo.git#main. tag is the image name, for example myapp:latest. dockerfile is a path inside the context. Build args are visible in the image history: do not put real secrets in them.

Inputs: tag (required), context (required), host, pull, +6 more. Returns: result

docker_cliA

Run any docker command, for things the other docker tools do not cover.

Give the arguments after "docker", for example: "system df" or "compose -p demo ps". Read commands (ps, images, inspect, logs, info, version, stats --no-stream, network ls ...) run right away. Anything else shows a preview first. background=true starts it as a background job (builds, pulls, big compose runs). Check it with server_job.

Inputs: args (required), host, as_root, confirm, +1 more. Returns: result

docker_container_actionC

Start, stop, restart, pause or unpause one container. Needs confirm=true.

Inputs: action (required), container (required), host, confirm. Returns: result

docker_copyA

Copy files between a container and the Docker host (docker cp). Needs confirm=true.

direction: to_container (host_path -> container_path) or from_container (container_path -> host_path). host_path must be in an allowed folder. Existing files at the destination are overwritten. keep_owner uses docker cp -a.

Inputs: container (required), direction (required), host_path (required), container_path (required), +3 more. Returns: result

docker_createA

Create a network or a volume. Needs confirm=true.

kind: network or volume. Network: driver (bridge, macvlan ...), subnet, gateway, ip_range, parent (the host interface for macvlan, for example eth0.20), internal. Volume: driver (default local) and options, for example an NFS volume: options {"type": "nfs", "o": "addr=192.0.2.10,nfsvers=3,hard", "device": ":/export/share"}.

Inputs: kind (required), name (required), host, driver, +7 more. Returns: result

docker_disk_usageC

Show how much disk space images, containers, volumes and build cache use.

Inputs: host. Returns: result

docker_execA

Run one command inside a running container (no terminal, no input).

Destructive, because the command can do anything inside the container. Shows a preview first. Run again with confirm=true after the user says yes. By default the command is split like a shell would, but no shell is used (no pipes). Set shell=true to run it with sh -c (pipes, &&, redirects). workdir sets the folder inside the container. user sets the user.

Inputs: command (required), container (required), host, user, +3 more. Returns: result

docker_imagesC

List images: name, tag, size, age.

Inputs: host. Returns: result

docker_inspectB

Show details of a container, volume, network or image (kind).

For a volume this shows its driver and options, such as the NFS address. Secret values in environment variables are hidden.

Inputs: name (required), host, kind. Returns: result

docker_logsB

Show the last lines of a container's log. since like 10m, 2h, or 2026-10-11.

Secrets that look like password or token values are hidden.

Inputs: container (required), host, tail, since. Returns: result

docker_networksC

List networks: name, driver, scope.

Inputs: host. Returns: result

docker_pruneA

Clean up unused things. what: containers (stopped), images (unused, untagged only), networks (unused), volumes (not used by any container), builder (build cache).

Destructive. Shows a preview first. Run again with confirm=true after the user says yes.

Inputs: what (required), host, confirm. Returns: result

docker_psA

List containers: name, image, state, status, ports, networks.

all=true includes stopped containers. name_contains filters by name.

Inputs: all, host, name_contains. Returns: result

docker_pull_imageB

Download an image, for example ghcr.io/example/app:latest. Needs confirm=true.

Inputs: image (required), host, confirm. Returns: result

docker_removeA

Delete one container, image, volume or network (kind).

Destructive. Shows a preview first. Run again with confirm=true after the user says yes. A running container is not removed. Stop it first. Removing a volume deletes the data inside it. A volume with an NFS setting only holds the setting, not the files on the NAS.

Inputs: kind (required), name (required), host, confirm. Returns: result

docker_runA

Start a new container in the background (docker run -d). Needs confirm=true.

For anything that should stay, a compose stack (docker_stack_write) is better. ports like "8080:80" or "127.0.0.1:8080:80/tcp". volumes like "myvol:/data" or "/opt/stacks/app/data:/data:ro" (a host folder must be in an allowed folder). Not possible here: privileged mode, devices, the docker socket.

Inputs: image (required), env, host, name, +8 more. Returns: result

docker_stack_actionA

Run a Compose action on one stack.

action: up (create/start, same as docker compose up -d), pull (get new images), update (pull then up), start, stop, restart, build (build the images the compose file builds itself), build_no_cache, up_build (build then up), recreate (up with --force-recreate). These need confirm=true. down (removes the containers and network, keeps volumes) and down_volumes (also removes the stack's volumes) are destructive and also

Inputs: stack (required), action (required), host, confirm. Returns: result

docker_stack_configA

Check a stack and show the final compose file with all variables filled in.

Good for finding a missing or wrong value in the .env file. Secret values are hidden.

Inputs: stack (required), host. Returns: result

docker_stack_fileB

Show the compose file of a stack. Secret values are hidden. The .env file is never shown.

Inputs: stack (required), host. Returns: result

docker_stack_logsB

Show the last log lines of a whole stack, or one service of it. since like 10m, 2h, 2026-10-22.

Inputs: stack (required), host, tail, since, +1 more. Returns: result

docker_stacksC

List Compose stacks (one folder each under the stacks folder) and whether they are running.

Inputs: host. Returns: result

docker_stack_statusC

Show the containers of one stack and their state.

Inputs: stack (required), host. Returns: result

docker_stack_writeA

Create a new stack, or replace the compose file of one, then check it. Needs confirm=true.

The file goes to //compose.yaml (an existing compose file keeps its name). The result is checked with docker compose config. If the check fails, the old file is put back (or the new file removed) and the error is shown. Nothing is started: use docker_stack_action up. Secret values should be ${VARIABLES} that live in the .env file (write that with server_file_write).

Inputs: stack (required), content (required), host, confirm. Returns: result

docker_statsB

Show CPU, memory and network use of running containers right now.

Inputs: host. Returns: result

docker_tag_imageB

Give an image a second name (docker tag). Needs confirm=true.

Inputs: source (required), target (required), host, confirm. Returns: result

docker_volumesC

List volumes: name and driver.

Inputs: host. Returns: result

server_file_deleteA

Delete a file or an empty folder on the Docker host. Destructive.

Destructive. Shows a preview first. Run again with confirm=true after the user says yes. recursive=true also deletes a folder with everything in it. Never forced.

Inputs: path (required), host, as_root, confirm, +1 more. Returns: result

server_file_editA

Change part of a text file: replace old_string with new_string. Needs confirm=true.

old_string must match the file exactly and must be unique, unless replace_all=true. Works on files Claude can read. Lines with hidden secrets cannot be matched.

Inputs: path (required), new_string (required), old_string (required), host, +4 more. Returns: result

server_file_listA

List files and folders on the Docker host (type, mode, owner, size, date, path).

Any path works. SERVER_MCP_FILE_ROOTS can limit it to some folders. as_root=true uses sudo. An empty path means the stacks folder. A path without a leading / starts there too. depth is how many folder levels to show (1 to 4).

Inputs: host, path, depth, as_root. Returns: result

server_file_mkdirA

Make a folder (and missing parent folders) on the Docker host. Needs confirm=true.

Inputs: path (required), host, as_root, confirm. Returns: result

server_file_moveA

Move or rename a file or folder on the Docker host. Needs confirm=true.

Without overwrite=true an existing destination is left alone.

Inputs: source (required), destination (required), host, as_root, +2 more. Returns: result

server_file_readA

Read a text file on the Docker host. Secret values are hidden.

Files that hold secrets (.env, *.env, keys, credentials) are never shown. Big files are cut (SERVER_MCP_MAX_FILE_KB, default 1024 KB).

Inputs: path (required), host, as_root. Returns: result

server_file_writeA

Create a file, or replace a whole file, on the Docker host. Needs confirm=true.

make_dirs creates missing folders. backup keeps the old file as .bak. mode is an optional octal mode such as 644 or 755 (for scripts). An existing file keeps its mode and owner. encoding is text, or base64 for binary files. For a small change to an existing file use server_file_edit instead: it never touches hidden secret lines.

Inputs: path (required), content (required), host, mode, +5 more. Returns: result

server_hostsA

List the Docker hosts this tool knows and test the connection to each.

Inputs: no named parameters. Returns: result

server_infoB

Show the system: OS, kernel, uptime, CPU, memory, disks and network. Read only.

Inputs: host. Returns: result

server_jobA

Look at background jobs started with background=true.

action: list, status, output (last lines of the log), cancel, clean (remove finished jobs). Jobs started as root must be read with as_root=true. list, status and output run right away. cancel and clean show a preview first.

Inputs: host, lines, action, job_id, +2 more. Returns: result

server_journalA

Read the system log (journalctl). Optional unit, line count, since ("1 hour ago") and grep. Read only.

Inputs: grep, host, unit, lines, +2 more. Returns: result

server_packagesA

Manage system packages (apt, dnf or apk, found automatically).

action: list_updates and search are read only. update (refresh lists), install, remove and upgrade show a preview first. packages is a space separated list. background=true starts it as a background job and returns a job id at once. Use it for upgrade and install, which can take minutes. Check it with server_job.

Inputs: action (required), host, confirm, packages, +1 more. Returns: result

server_powerB

Reboot or power off the host. action: reboot or poweroff. Always shows a preview first.

The SSH link drops when it runs. That is normal.

Inputs: action (required), host, confirm. Returns: result

server_processesB

Show the busiest processes. sort: cpu or mem. Read only.

Inputs: host, sort, limit. Returns: result

server_runA

Run one shell command on the Docker host itself (not inside a container).

It starts in the stacks folder. Safe read-only commands (ls, cat, head, tail, grep, find, df, free, uptime, git status/log/diff, ps, ss, ip, and pipes between them) run right away. Anything else needs confirm=true after the user says yes. Risky ones (rm, mv, dd, chmod, chown, kill, systemctl, apt, reboot, sudo ...) are marked destructive in the preview. as_root=true runs it with sudo. Root commands always show a preview first. background=true starts it as a background job and returns a job id at once (use it for anything that can take more than about 40 seconds). Check it with server_job. Files with passwords or keys (.env, keys, credentials) are blocked. For files, prefer server_file_read, server_file_write and server_file_edit.

Inputs: command (required), host, as_root, confirm, +2 more. Returns: result

server_serviceB

Manage a systemd service. action: status, start, stop, restart, reload, enable, disable.

status is read only and runs right away. The others show a preview first.

Inputs: unit (required), host, action, as_root, +1 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 42 tools

    Disambiguation4/5

    Most tools have a clearly distinct resource+action target: listing (docker_images, docker_networks, docker_volumes, docker_ps), lifecycle (docker_run, docker_create, docker_remove, docker_prune), and stack operations (docker_stacks vs docker_stack_status/file/config/action/write/logs) are well separated. The main friction is the deliberate catch-alls docker_cli and server_run, which overlap every other tool and could pull an agent away from the specific, safer tools; docker_stack_logs vs docker_logs and docker_tag_image vs docker_build are also easy to confuse at a glance.

    Naming Consistency4/5

    Names are uniformly snake_case and follow a clear two-level prefix scheme (docker_* for Docker object operations, server_* for host operations), with list tools consistently using bare nouns and state-changing tools using a verb or an explicit action parameter. Minor deviations exist: docker_ps instead of docker_containers, and docker_create/docker_remove take a 'kind' argument while other tools are single-purpose, but nothing is ambiguous to read.

    Tool Count2/5

    42 tools is a very large surface for one server, well above the range where each tool clearly earns its place. The breadth (containers, images, networks, volumes, compose stacks, files, host shell, systemd, packages, jobs) explains the size, but the escape hatches docker_cli and server_run could absorb several narrow tools (docker_tag_image, docker_copy, docker_pull_image) and reduce the count substantially.

    Completeness4/5

    Coverage is unusually thorough: full container/image/network/volume lifecycle, compose stack create/update/up/down/logs, file CRUD plus edit, host inspection, systemd, packages, background jobs and power control. Only peripheral gaps remain (image push, registry auth, docker events, network connect/disconnect for existing containers), and those are explicitly reachable via docker_cli and server_run, so no real dead ends.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables SSH remote access to servers through Claude, allowing users to execute commands, transfer files via SFTP, and manage multiple remote connections using natural language.
      12
      9
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables managing Ubuntu/Linux servers through natural language by establishing SSH connections and executing remote commands. Supports real-time command execution and output through Claude Desktop or Cursor IDE.
      14
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Execute commands on remote Linux servers through Claude with an interactive web terminal showing full output while Claude receives smart-filtered summaries for token efficiency. Supports multi-server management, SFTP file transfers, batch scripts, and automation recipes.
      35 PyPI
      8
      MIT
    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      Connects Claude to remote servers via SSH to execute commands, manage files, and browse directories. It allows users to add, edit, and switch between multiple server configurations through natural language conversations.
      -