Skip to main content
Glama
woodwhite0ets

MCP Infrastructure Gateway

README.md
# MCP Infrastructure Gateway

<p align="center">
  <img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License">
  <img src="https://img.shields.io/badge/node-%3E%3D20-339933.svg" alt="Node.js >= 20">
  <img src="https://img.shields.io/badge/docker-compose-2496ED.svg" alt="Docker Compose">
  <img src="https://img.shields.io/badge/MCP-Server-000000.svg" alt="MCP Server">
</p>

> **An authenticated MCP Gateway for your SSH server fleet and RAG knowledge base.**
> Exposes servers, knowledge search and policy-enforced operations as MCP tools:
> read-only checks run automatically, risky commands require human approval.

远程 Linux MCP Gateway:本机 Harness/Codex 通过 HTTPS 连接 Gateway,Gateway 根据明确的 `target` 通过 SSH 访问博客服务器和中转站,并按策略执行知识库检索、只读检查和审批后的运维操作。

## 特性

- 🔐 **身份与 SSRF 防护**:每人独立 Bearer Token + 来源限流;目标只能使用注册表 ID,请求中传入任意 IP 会被拒绝
- 🛡️ **命令策略引擎**:只读命令自动执行;删除、重启、停服、数据库写入、配置修改等操作必须人工审批
- 🧠 **RAG 知识库**:PostgreSQL 全文检索 + pgvector 向量混合检索(Embedding 可本地 TEI 或 OpenAI 兼容 API)
- 🔑 **Web 管理 SSH 凭据**:私钥/密码加密存储,不在 API 返回、日志或知识库中回显
- 🧩 **MCP 原生**:`list_targets` / `inspect_server` / `run_command` / `search_knowledge` 等 18 个工具,附技能手册与知识库检索
- 📦 **安全部署**:docker compose 一键启动,Caddy TLS、read-only 容器、非 root 运行、最低权限 SSH 目标用户

## 结构

```mermaid
flowchart LR
    subgraph Client[Harness / Codex / MCP client]
        H[HTTPS + Bearer Token]
    end
    subgraph Edge[Caddy - TLS termination]
        C[HTTPS 443]
    end
    subgraph GW[Gateway container - read-only]
        M[MCP Server<br>18 tools]
        P[Policy & approval engine]
        S[SSH manager<br>web-managed credentials]
        K[RAG knowledge search<br>pgvector hybrid]
    end
    subgraph Targets[SSH targets]
        T1[blog-prod]
        T2[relay-prod]
    end
    DB[(PostgreSQL<br>+ pgvector)]

    H -- HTTPS/MCP --> C -- private network --> M
    M --> P --> S -- SSH --> T1
    S -- SSH --> T2
    K --> DB
```

## 安全边界

- Gateway 只监听容器内部 HTTP;公网 TLS 由 Caddy 终止。
- MCP 请求使用每人独立的 Bearer Token。
- 认证失败按来源地址限流;正式部署仍建议叠加 VPN、Cloudflare Access 或防火墙白名单。
- SSH 私钥只读挂载到 Gateway 的 `/run/secrets`,不进入 Git、知识库或 MCP 返回结果。
- 目标只能使用 `targets.yaml` 中的 ID,不能从请求中传入任意主机地址。
- 禁止 root、`sudo`、shell 链接/替换/重定向和全局高危命令。
- 只读命令自动执行;配置、部署、重启等命中 approval allowlist 的操作必须先审批。
- 用户只能访问自己的目标服务器和项目知识。
- PostgreSQL 中保存审批状态和审计日志;日志不保存密钥。

## Linux 部署

以下命令在远程 Gateway Linux 主机执行:

```bash
cp .env.example .env
install -d -m 700 secrets
cp config/targets.example.yaml config/targets.yaml
cp config/auth.example.yaml config/auth.yaml
chmod 600 .env config/*.yaml
```

生成用户 Token 的哈希,不要把明文 Token 提交到文件:

```bash
node scripts/hash-token.mjs "生成一段随机长Token"
```

把输出的 `sha256:...` 写入 `config/auth.yaml` 的 `token_hash`。明文 Token 只放在本机 Harness 的环境变量中。

将 SSH 私钥和已核验的主机指纹放入 `secrets/`:

```bash
install -m 600 /secure/source/blog_ssh_key secrets/blog_ssh_key
install -m 600 /secure/source/relay_ssh_key secrets/relay_ssh_key
install -m 600 /secure/source/known_hosts secrets/known_hosts
```

目标服务器应使用独立的非 root 用户,并把 Gateway 的公钥加入该用户的 `~/.ssh/authorized_keys`。确认 `known_hosts` 后再启动服务。

配置 `.env`:

```dotenv
POSTGRES_PASSWORD=long-random-database-password
MCP_DOMAIN=mcp.example.com
DATABASE_URL=postgres://mcp_gateway:long-random-database-password@db:5432/mcp_gateway
```

启动:

```bash
docker compose up -d --build
docker compose --profile index run --rm indexer
curl -fsS https://mcp.example.com/healthz
```

## 本机 Harness/Codex 配置

```bash
export MCP_GATEWAY_TOKEN='本机保存的明文Token'
codex mcp add infra-gateway \
  --url https://mcp.example.com/mcp \
  --bearer-token-env-var MCP_GATEWAY_TOKEN
```

Windows PowerShell:

```powershell
$env:MCP_GATEWAY_TOKEN = "本机保存的明文Token"
codex mcp add infra-gateway `
  --url https://mcp.example.com/mcp `
  --bearer-token-env-var MCP_GATEWAY_TOKEN
```

## 知识库与 RAG

`knowledge/` 中的 Markdown、YAML、JSON 和文本文件由 `indexer` 切块写入 PostgreSQL。默认使用 PostgreSQL 全文检索;配置 `EMBEDDING_BASE_URL`、`EMBEDDING_API_KEY` 和 `EMBEDDING_MODEL` 后,索引器和查询会额外使用 pgvector 做混合检索。

硬性限制单独存放在 `config/rules.yaml`,每次由 `get_constraints` 读取,不依赖向量召回。服务器最新日志、状态和端口通过 SSH 工具实时查询,不放入 RAG。

## MCP 工具

```text
list_targets()
list_projects()
get_constraints(scope?)
search_knowledge(project, query, limit?)
read_document(project, path)
inspect_server(target, check)
read_logs(target, service, lines?)
run_command(target, command, approval_id?)
list_pending_approvals()
decide_approval(approval_id, decision)
```

## 生产前检查

- 将 Gateway 放在 Tailscale/WireGuard 或防火墙之后,SSH 只允许 Gateway 固定地址。
- 将 `auth.yaml`、`targets.yaml` 和 `secrets/` 的权限限制为部署管理员和容器所需用户。
- 为每个人创建独立 Token,人员离开时撤销并重新部署配置。
- 将 PostgreSQL 和 Caddy 数据卷纳入备份;不要备份明文 SSH 私钥到普通备份桶。
- 为审批和审计日志设置保留期限,并监控 Gateway、SSH 和数据库异常。
- 在 staging 目标上验证命令规则后,再添加生产目标。