Skip to main content
Glama
README.md
# mcp_server

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Streamable HTTP [MCP](https://modelcontextprotocol.io/) server for remote Linux operations. A local agent (Cursor, Cherry Studio, and other MCP clients) connects to `POST /mcp` and can read/write files, run shell jobs, keep disk memory, and activate operator-authored TypeScript tools.

The operator confirms every tool call in the client. There is no extra server-side sandbox.

## Features

- Streamable HTTP only (`0.0.0.0:7891` by default). No stdio.
- Static Bearer token from `config/server.json` (timing-safe compare).
- Builtin tools: `help`, `fs.*`, `exec.start` / `exec.poll` / `exec.kill` / `exec.list`, `memory.*`.
- Dynamic tools: `meta.tool.draft` then `meta.tool.activate` (esbuild + child-process worker). Survives reboot because disk is the source of truth.
- Long commands are ordinary tools, not the MCP Tasks extension, so clients that only implement `tools/call` can use them.

See [docs/architecture.md](docs/architecture.md) and [docs/decisions.md](docs/decisions.md).

## Requirements

- Node.js 20.11 or later
- Linux host for production (`exec.start` uses `sh -c`)

## Quick start

```sh
git clone https://github.com/luoxi0615/mcp_server.git
cd mcp_server
npm ci
cp config/server.example.json config/server.json
```

Edit `config/server.json`: set a long random `token`, and put the public IP or DNS name you will use in the client URL into `allowedHosts` (this is the HTTP `Host` header allowlist, not a client-IP whitelist).

```sh
npm run build
npm start
```

Development:

```sh
npm run dev
```

## Client

```json
{
  "mcpServers": {
    "linux-ops": {
      "url": "http://YOUR_PUBLIC_IP:7891/mcp",
      "headers": {
        "Authorization": "Bearer <same token as config/server.json>"
      }
    }
  }
}
```

Open TCP `7891` on the host firewall. The `Host` header in the request must match `allowedHosts`.

After connect, call `help` (optionally `{ "name": "exec.start" }`) before using tools.

## Linux install script

On the target host, as root:

```sh
sudo bash scripts/linux-install.sh
```

The script installs Node if needed, writes `config/server.json` on first run, opens TCP 7891 when ufw/firewalld is active, and enables `mcp-server.service`. Override the packaged tarball with `MCP_TARBALL_URL`. Re-running keeps the existing token unless `MCP_RESET_TOKEN=1`.

Do not copy Windows `node_modules` onto Linux. Build a tarball with `npm run pack` when you need a new release archive.

## Security

This process can run shell commands and touch arbitrary absolute paths. Treat the Bearer token as a root-equivalent secret. Traffic is plaintext HTTP unless you terminate TLS in a reverse proxy. `config/server.json` is gitignored.

## License

[MIT](LICENSE)