Token导航 LogoToken导航TokenDH.com
wtMCP (Le Gambi Art) logo
运维云端未说明官方级别未说明来源级核验

wtMCP (Le Gambi Art)

MCP Server

wtmcp是一个支持多语言插件的MCP服务器,核心处理认证、HTTP代理、缓存和输出编码,插件通过JSON-lines协议与核心通信。

工具数

0

提示词数

0

GitHub Stars

11

资源数

0
Go云端部署Docker

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

LeGambiArt

提供方

LeGambiArt

最后核验

2026/5/17 20:19

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

wtmcp

带有语言无关插件系统的MCP服务器。插件很简单 与以下对象通信的可执行文件(Python、bash或任何语言) 核心位于stdin/stdout上的JSON行之上。核心处理身份验证、HTTP 代理、缓存和输出编码,使插件保持最小。

建筑

┌─────────────────────────────────────────────────┐
│  wtmcp (Go)                                     │
│                                                 │
│  MCP Server ─── Plugin Manager ─── HTTP Proxy   │
│  (mcp-go)       Discovery         Auth inject   │
│                 Lifecycle          SSRF protect │
│                 Dispatch           TLS verify   │
│                                    Rate limit   │
│                                                 │
│  Audit Log ─── Cache Store ─── Auth Providers   │
│  (JSON)        (memory/fs)     Bearer, Basic,   │
│                                Kerberos, OAuth2 │
│  Sandbox (optional)                             │
│  Landlock + cgroups + netns                     │
└────────┬──────────────────────────┬─────────────┘
         │ stdio (MCP/JSON-RPC)     │ stdin/stdout (JSON-lines)
    ┌────┴────┐               ┌─────┴──────────┐
    │ AI      │               │ Plugins        │
    │ Client  │               │ Zero deps      │
    └─────────┘               │ No HTTP libs   │
                              │ No auth code   │
                              └────────────────┘

特性

  • 插件协议:任何语言的stdin/stdout上的JSON行
  • 认证:承载、基本、Kerberos/SPNEGO、带令牌刷新的OAuth2,

从可用凭据中自动检测

  • HTTP代理:身份注入、域验证、TLS强制、,

二进制响应编码,多部分上传支持

  • 缓存:具有命名空间隔离和TTL的内存存储
  • 输出:TOON编码可节省约40%的代币(可选)
  • 插件设置:CLI工具的清单声明向导元数据
  • 渐进式发现:工具默认为延迟;仅初级

工具被加载到模型上下文中。延期工具包括 可通过以下方式发现 tool_search 并通过MCP直接调用

  • 加密凭据:Ansible Vault加密的env.d文件,

启动时自动检测并透明解密

安全

wtmcp在核心级别强制执行安全性,因此插件不需要 实现自己的身份验证、输入验证或网络限制。

HTTP代理和SSRF防护

所有插件HTTP流量都通过核心代理。没有插件 直接网络连接。

  • SSRF安全拨号器 在连接时验证已解析的IP--

阻止私有、环回、链路本地、多播和IPv6映射 IPv4地址

  • 域名分配 每个插件——只有声明的域

可到达的

  • 跨域重定向时的凭据剥离 --授权,

Cookie和API密钥头在重定向到 不同的主机

  • 危险顶盖已拆除 来自插件精心编制的请求

(主机、代理授权、X-Forwarded-For等)

  • HTTPS强制 用于经过身份验证的请求;mTLS支持

使用证书链验证

  • 用户信息URL拒绝user:pass@host URL被阻止

沙盒(可选)

建立 -tags sandbox 通过以下方式启用操作系统级插件隔离 阿拉伯:

  • Landlock LSM 文件系统限制——插件只能

读/写声明路径

  • cgroup v2 资源限制——内存、CPU、PID、文件大小

(每个插件可配置)

  • 网络命名空间隔离 --插件不能直接

连接;通过核心代理的所有流量路由

  • OOM检测 进程退出后的资源使用情况报告
# Build with sandbox support (requires libarapuca)
make build-sandbox

# Default build works without libarapuca
make build

当配置中启用了沙盒但二进制文件缺少标签时, 服务器以明显错误拒绝启动。当配置使用 默认情况下(隐式启用沙盒),服务器以 警告。

速率限制

令牌桶速率限制,可配置每个插件、每个域、, 以及全球限制。默认值:每个插件120请求/分钟,600请求/分钟 全球的。

http:
  rate_limit:
    default: "120/m"
    global: "600/m"
    per_plugin:
      jira: "60/m"
    per_domain:
      api.github.com: "30/m"

HTTP检索

瞬时上游采用指数回退的自动重试 失败。只有幂等方法(GET、HEAD、OPTIONS、PUT、, DELETE)被重试——POST/PATCH永远不会被重试。尊重 Retry-After 头部(夹紧至30秒)。上下文感知:工具 呼叫超时自然会限制总重试持续时间。

http:
  retries:
    max: 3                          # retries (not counting initial)
    backoff: exponential            # 1s, 2s, 4s... capped at 30s
    retry_on: [500, 502, 503, 504]  # status codes to retry

缓存限制

LRU驱逐时的每个插件入口限制。参赛作品超过 max_entry_size 被拒绝。后台清理删除已过期 以配置的间隔输入。

cache:
  max_entries_per_plugin: 10000  # LRU eviction when exceeded
  max_entry_size: 1048576        # 1MB max per entry
  cleanup_interval: 60s          # expired entry sweep

审计日志

具有UUID v7相关ID的结构化JSON审核日志:

  • 工具调用事件:插件、工具、参数(已擦除)、持续时间
  • 诱导事件:插件、工具、操作(接受/拒绝/取消/

错误/不支持)

  • HTTP代理事件:方法、主机、路径、状态、响应大小
  • 凭证清理:字段名(密码、令牌、机密),

JWT检测(eyJ 前缀),高熵字符串检测

  • 可配置输出:文件(0600权限)和/或stdout
audit:
  log_file: logs/audit.log
  stdout: false
  scrub_fields: [password, token, secret, api_key, authorization]

快速注射防御

  • MCP激发 (默认启用)提示用户

在执行任何写入工具之前进行确认。确认书 消息显示了工具名称和已擦除的参数。客户 默认情况下,缺乏启发支持会被阻止 (elicitation_strict: true).完全禁用启发式 security.elicitation: false,或允许客户失误 没有启发式支持 security.elicitation_strict: false

  • 输出框架 (默认启用)每个会话

加密随机数——检测插件输出中注入的标签 然后逃走了。禁用 security.tag_tool_output: false

  • MCP受众注释 着手 [assistant] 在所有工具上

结果(始终处于活动状态)

  • JSON模式验证 在编译后的每个工具调用上

插件YAML

  • 编写工具约定:默认包含插件

dry_run=true 在他们的模式中,需要明确的退出。 这是一个插件级别的约定,不是核心强制的

  • 只读模式 在三个层面上执行:工具注册,

禁用存根和运行时拒绝

security:
  elicitation: true        # confirm before write tools (default: true)
  elicitation_strict: true # block writes if client lacks elicitation (default: true)
  tag_tool_output: true    # nonce-based output tagging (default: true)

凭证隔离

插件进程只接收它们需要的凭据。

  • 范围env.d --每个插件只接收其凭据

组变量

  • 过滤环境 --所有安全系统变量均已通过

插件(PATH、HOME、LANG、TZ、TMPDIR、XDG\_\*dirs等)

  • 文件权限执行 --env.d文件和目录

需要0600/0700(SSH样式)

  • Symlink拒绝 在凭据文件、CA证书和env.d上

条目

  • 保险库密码清零 --从内存中清除解密密钥

使用后(尽最大努力;Go的GC可能会保留副本)

  • 内存支持的安全文件 --已存储解密凭据

通过 memfd_create,切勿触摸磁盘

建立和运行

make build

# Run with a workdir (default: ~/.config/wtmcp)
./wtmcp --workdir ~/.config/wtmcp

工作目录布局:

~/.config/wtmcp/
  config.yaml           Core config (optional)
  .env                  Environment variables
  env.d/*.env           Additional env files
  plugins/
    jira/
      plugin.yaml       Plugin manifest
      handler.py        Plugin executable

编写插件

插件是一个包含清单的目录(plugin.yaml)以及一个处理程序 可执行。核心发现插件,作为子进程启动处理程序 使用JSON行在stdin/stdout上处理和路由工具调用。

docs/plugin-guide.md 查看完整指南 有多种语言的例子。

最小示例(bash)

一个oneshot插件,每次工具调用运行一次处理程序:

plugin.yaml:

name: hello
version: "1.0.0"
description: "A greeting plugin"
execution: oneshot
handler: ./handler.sh
tools:
  - name: hello_world
    description: "Says hello to someone"
    params:
      name:
        type: string
        default: "World"
        description: "Who to greet"
enabled: true

handler.sh:

#!/bin/bash
read -r INPUT
ID=$(echo "$INPUT" | jq -r '.id')
NAME=$(echo "$INPUT" | jq -r '.params.name // "World"')

echo "{}" | jq -c --arg id "$ID" --arg name "$NAME" \
  '{id: $id, type: "tool_result", result: {message: ("Hello, " + $name + "!")}}'

API插件示例(Python)

通过核心的HTTP代理调用API的持久插件。 处理程序保持运行并处理多个工具调用。认证 头文件是自动注入的——插件永远不会看到令牌。

plugin.yaml:

name: myapi
version: "1.0.0"
description: "Example API plugin"
execution: persistent
handler: ./handler.py

services:
  auth:
    type: bearer
    token: "${MY_API_TOKEN}"
  http:
    base_url: "${MY_API_URL}"

tools:
  - name: myapi_get_status
    description: "Get API status"
    params: {}
  - name: myapi_search
    description: "Search the API"
    params:
      query:
        type: string
        required: true
enabled: true

handler.py:

#!/usr/bin/env python3
import json, sys

def _send(msg):
    print(json.dumps(msg, separators=(",", ":")), flush=True)

def _recv():
    line = sys.stdin.readline()
    if not line:
        sys.exit(0)
    return json.loads(line.strip())

def http(method, path, query=None):
    msg = {"id": "1", "type": "http_request", "method": method, "path": path}
    if query:
        msg["query"] = query
    _send(msg)
    resp = _recv()
    return resp.get("status", 0), resp.get("body", {})

def get_status(_params):
    status, body = http("GET", "/status")
    return body

def search(params):
    status, body = http("GET", "/search", query={"q": params["query"]})
    return body

TOOLS = {"myapi_get_status": get_status, "myapi_search": search}

while True:
    msg = _recv()
    if msg.get("type") == "init":
        _send({"id": msg["id"], "type": "init_ok"})
    elif msg.get("type") == "shutdown":
        _send({"id": msg["id"], "type": "shutdown_ok"})
        break
    elif msg.get("type") == "tool_call":
        fn = TOOLS.get(msg.get("tool"))
        if fn:
            result = fn(msg.get("params", {}))
            _send({"id": msg["id"], "type": "tool_result", "result": result})
        else:
            _send({"id": msg["id"], "type": "tool_result",
                   "error": {"code": "unknown_tool", "message": msg.get("tool")}})

关键概念

  • Oneshot 每次工具调用都会生成插件。写起来最简单。
  • 持久 插件启动一次,通过主循环处理许多调用。
  • HTTP代理:插件发送 http_request 核心信息

带有auth并返回的调用 http_response。不需要HTTP库。

  • 缓存:插件发送 cache_get/cache_set 信息。核心

管理存储和TTL。

  • 身份验证变体:单个插件可以支持多种身份验证方法

(例如,Cloud Basic+服务器承载+Kerberos)具有自动检测功能。

插件管理

插件可以在运行时重新加载,而无需重新启动服务器。

来自AI助手:

plugin_reload(name="jira")
plugin_list()

从终端 (控制目录):

touch ~/.config/wtmcp/control/commands/reload-jira
touch ~/.config/wtmcp/control/commands/reload-all

结果显示在 ~/.config/wtmcp/control/results/。服务器写入 其PID为 ~/.config/wtmcp/control/mcp.pid 用于过程跟踪。

当工具或资源发生变化时,MCP客户端会自动收到通知。

OAuth插件管理

插件身份验证(特别是对于启用OAuth的插件)是通过 wtmcpctl 命令行实用程序。看 README-wtmcpctl.md 了解使用说明和设置。

加密凭据

env.d文件可以用加密 Ansible保险库 用于休息保护。服务器通过以下方式自动检测加密文件 魔术头,并在启动时透明地解密它们。插件 像往常一样接收明文凭据——不需要更改插件。

快速开始

# Create a vault password file (umask prevents brief permission race)
(umask 077 && openssl rand -base64 32 > ~/.vault-pass)

# Tell wtmcp where the password file is
# (add to ~/.config/wtmcp/config.yaml)
#   secrets:
#     vault_password_file: ~/.vault-pass

# Encrypt an env.d file
ansible-vault encrypt --vault-password-file ~/.vault-pass \
    ~/.config/wtmcp/env.d/jira.env

# Start the server — decrypts automatically
wtmcp

加密文件可以安全地提交到git、共享或备份 起来。任何获得它们的人仍然需要保管库密码才能 解密。

密码来源

保管库密码按优先级顺序解析:

  1. WTMCP_VAULT_PASSWORD 环境变量(CI/CD便利性)
  2. WTMCP_VAULT_PASSWORD_FILE 环境变量(文件路径)
  3. secrets.vault_password_file 在config.yaml中(推荐)

对于生产和工作站,首选基于文件的密码。环境 var用于装载文件的CI/CD管道 不方便。

多密码支持(保险库ID)

Ansible Vault 1.2支持标记密码(Vault ID)。不同 env.d文件可以使用不同的密码:

# Encrypt with a vault ID label
ansible-vault encrypt --vault-id prod@~/.vault-pass-prod \
    ~/.config/wtmcp/env.d/jira.env

在config.yaml中配置每个ID的密码文件:

secrets:
  vault_password_file: ~/.vault-pass          # default
  vault_ids:
    prod: ~/.vault-pass-prod
    dev: ~/.vault-pass-dev

还支持每ID环境变量: WTMCP_VAULT_PASSWORD_PROD, WTMCP_VAULT_PASSWORD_DEV.

如果找不到每个ID的密码,服务器将回退到 默认密码链自动。

诊断

wtmcp check

报告保管库密码状态和每组加密详细信息 (仅显示加密组):

vault password: file (~/.vault-pass)
  - jira (encrypted, vault 1.1, decryption ok)
  - snyk (encrypted, vault 1.2 id=prod, decryption failed)

迁移现有文件

  1. 创建vault密码文件(请参阅快速入门)
  2. 配置 secrets.vault_password_file 在config.yaml中
  3. 加密一个env.d文件:

ansible-vault encrypt --vault-password-file ~/.vault-pass env.d/jira.env

  1. 验证: wtmcp check 应显示“解密正常”
  2. 对剩余文件重复此操作
  3. 可选地将加密文件提交到git

单个env.d目录可以混合纯文本和加密文件。 增量迁移--一次一个文件。

如果之前以明文形式提交env.d文件,则加密 它们不会从git历史记录中删除明文。旋转 迁移后受影响的凭据,并考虑使用 git filter-repo 从历史记录中删除旧明文。

重新加载加密凭据

凭证更改将于生效 plugin_reload 没有服务器 重新启动。每次从密码源重新读取保管库密码 reload,因此密码轮换会自动进行。

安全须知

  • Ansible Vault使用AES-256-CTR和PBKDF2-SHA256(10000

迭代)。使用强密码(20+个字符或 openssl rand -base64 32)以补偿低迭代次数 计数。

  • 备份您的保管库密码文件。 失去它意味着永久

无法访问加密凭据。将副本存储在 单独的安全位置。

  • Ansible Vault是对开发和

CI/CD。需要密钥轮换、审计的受监管环境 日志记录或FIPS验证的加密货币应使用HashiCorp Vault或 云KMS。

凭证文件加密

除了env.d文件外 credentials// 也可以进行vault加密。支持 文件夹:

  • client-credentials.json (OAuth2客户端凭据)
  • 传输层安全 client_certclient_key PEM文件

令牌文件(token-*.json)都是 加密——它们是 自动旋转、短暂且从客户端凭据派生。

加密的凭据文件被解密为内存支持的文件 描述符(Linux上的memfd,macOS上的未链接tmpfile)因此 解密的内容永远不会触及持久存储。插件 像往常一样接收相同的文件路径——不需要更改插件。

wtmcpctl保险库命令

加密和解密文件,无需 ansible-vault:

# Encrypt a file
wtmcpctl vault encrypt env.d/jira.env

# Encrypt with vault ID
wtmcpctl vault encrypt --vault-id prod env.d/jira.env

# Decrypt a file
wtmcpctl vault decrypt env.d/jira.env

# Verify decryption without writing
wtmcpctl vault decrypt --check env.d/jira.env

# View decrypted content without modifying the file
wtmcpctl vault view env.d/jira.env

密码来源于 --vault-password-file, WTMCP_VAULT_PASSWORD env-var、config.yaml或交互式提示(带回声抑制)。

包含的插件

谷歌插件

谷歌插件使用OAuth2提供对谷歌工作区服务的访问 身份验证:

插件描述
谷歌驱动器文件元数据、搜索和导出
谷歌日历日历事件和管理
谷歌gmail电子邮件阅读和发送

所有Google插件都需要OAuth2身份验证。看 README-wtmcpctl.md 有关设置说明。

Jira插件

附带的Jira插件涵盖了读取、写入、冲刺和导出 操作:

类别示例
阅读jira_search, jira_get_myself, jira_get_transitions
jira_create_issue, jira_add_comment, jira_assign_issue
Sprintjira_list_available_sprints, jira_get_sprint_issues
出口jira_export_sprint_data, jira_download_attachment

所有写入工具默认为 dry_run=true云感知(ADF格式, accountId分配)。身份验证变体:Cloud Basic、服务器承载、, 服务器Kerberos。

渐进式工具发现

默认情况下(tools.discovery: full),所有工具都加载到 模型的上下文。随着逐步发现,只有主要工具 加载;可通过以下方式发现延迟工具 tool_search.

启用 config.yaml:

tools:
  discovery: progressive

插件作者用以下符号标记关键工具 visibility: primaryplugin.yaml。所有其他工具默认为延迟。看 docs/plugin-guide.md 了解详情。

测试

# Go core tests
go test ./...

# Go core tests with race detector
go test -race ./...

# Sandbox tests (requires libarapuca)
make test-sandbox

# Python plugin tests
.venv/bin/pytest tests/ -v

# All pre-commit checks
pre-commit run --all-files

项目布局

cmd/
  wtmcp/                MCP server entry point
  wtmcpctl/             Plugin management CLI tool
internal/
  audit/                Structured JSON audit logging
  auth/                 Auth providers (bearer, basic, kerberos, oauth2)
  cache/                Key-value cache with TTL
  config/               Env var resolution, YAML config
  encoding/             TOON output encoding
  google/               Google OAuth helper (shared by Google plugins)
  plugin/               Manager, manifest, transport, dispatch
  protocol/             Wire protocol message types
  proxy/                HTTP proxy with SSRF prevention
  ratelimit/            Token-bucket rate limiting
  sandbox/              OS-level plugin isolation (optional)
  secrets/              Vault decryption, secure file descriptors
  server/               MCP server, output framing, tool index
  stats/                Per-tool call statistics
plugins/
  google-drive/         Google Drive plugin (Go)
  google-calendar/      Google Calendar plugin (Go)
  google-gmail/         Gmail plugin (Go)
  jira/                 Jira plugin (Python, zero external deps)
  confluence/           Confluence plugin (Python)
  gitlab/               GitLab plugin (Python)
tests/
  plugins/              Plugin unit tests
docs/
  plugin-guide.md       Plugin development guide
  wtmcpctl.md           OAuth management tool guide

许可证

此项目根据GNU通用公共许可证v3.0获得许可。 看 许可证 全文。

目录标签

目录标签

Go云端部署Docker插件系统本地部署HTTP代理认证管理多语言支持安全沙箱

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

oauth

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明oauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP