Skip to main content
Glama

MCP Server – 模块化命令提供器

一个 FastAPI 服务器,可将任意终端命令——连同 CalDAV 日历、ICS 订阅源、Gitea 仓库和通知提供器——作为可供语言模型复用的工具暴露出来。将 YAML 文件放入 registry/ 即可注册 CLI 程序;通过设置环境变量即可启用集成能力。模型通过 OpenAPI schema 发现可用工具,并通过类型化 HTTP 端点调用它们。

为什么要做

  • 语言无关 – 可以包装任何脚本、二进制文件或已编译程序。

  • 自描述 – 每个命令都带有其参数的 JSON schema。

  • 可发现 – GET /commands 列出所有命令;OpenAPI 位于 /openapi.json。

  • 安全执行 – 参数在命令真正运行之前会按 schema 校验;30 秒超时防止命令卡住。

  • 条件注册 – 只在对应的后台服务已经配置时端点才存在。LLM 永远不会看到会返回 503 的路由。

  • 可选 API Key – 设置 MCP_API_KEY 后,除了 /api/health 和 /api/about 以外的所有端点都需要认证。

Related MCP server: MCP Tool Server

快速开始

cd ~/projects/mcp-server
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

# Optional: set an API key to secure the server
export MCP_API_KEY="your-secret-key"

.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000

服务器现在监听在 http://127.0.0.1:8000。

如果设置了 MCP_API_KEY,则除了 /api/health 和 /api/about 之外的所有端点都要求请求头 X-API-Key 与密钥匹配。如果未设置,服务器将以开放模式运行(适合本地开发或受信任的网络环境)。

启动安全提示: 如果没有任何配置(没有日历提供器、没有 Gitea、没有通知提供器、没有天气功能,也没有 registry 命令),服务器将拒绝启动。至少要启用一个功能。

架构

服务器使用工厂模式(create_app()),在启动时检查环境变量,并按配置条件为每个已注册的集成注册路由。这意味着 OpenAPI schema 中只包含实际可用的端点——LLM 永远不会发现原来会返回 503 的路由。

提供器体系

日历集成(CalDAV 和 ICS)以提供器方式实现,这些提供器遵循一个统一的协议。全局的 provider_registry 持有所有启用的提供器。统一路由(unified_routes.py)在所有提供器上暴露 /events、/calendars,以及(当配置了 ICS 时)/calendars/refresh。写操作(创建/更新/删除事件)只会在存在可编辑提供器时注册(即设置了 CALDAR_EDITABLE_CALENDAR 的 CalDAV)。

后台任务

一个轻量级任务调度器(jobs.py)在应用的生命周期内运行周期性的后台任务。目前用于刷新 ICS 缓存。任务状态可通过 GET /jobs 查看。

API

端点会根据配置按条件注册。下表列出了所有可能的端点;只有与已启用功能对应的端点才会真正存在。

核心端点(始终存在)

方法

路径

描述

GET

/api/health

存活探针(无需认证)

GET

/api/about

应用名称与版本(无需认证)

GET

/commands

列出所有已注册命令

GET

/commands/{name}

获取某个命令的 schema

GET

/validate

校验所有 registry 文件(详细报告)

GET

/jobs

列出后台周期性任务的状态

POST

/{command}

每个 registry 命令的专用路由(自动生成)

日历(配置了 CalDAV 或 ICS 时)

方法

路径

描述

GET

/events

跨所有日历提供器列出事件

GET

/events/{uid}

按 UID 获取单个事件

GET

/calendars

列出可访问的日历及元数据

POST

/calendars/refresh

刷新 ICS 缓存(配置 ICS 时)

POST

/events

创建事件(只有在可编辑提供器时)

PUT

/events/{uid}

更新事件(只有在可编辑提供器时)

DELETE

/events/{uid}

删除事件(只有在可编辑提供器时)

CalDAV 任务(配置了 CalDAV 时)

方法

路径

描述

GET

/tasks

列出日历任务(VTODO)

GET

/tasks/{uid}

按 UID 获取单个任务

POST

/tasks

创建任务(只有在可编辑提供器时)

PUT

/tasks/{uid}

更新任务(只有在可编辑提供器时)

DELETE

/tasks/{uid}

删除任务(只有在可编辑提供器时)

Gitea(设置了 GITEA_URL 时)

方法

路径

描述

GET

/repos/{owner}/{repo}

获取仓库信息

GET

/user/repos

列出可访问的仓库

GET

/repos/{owner}/{repo}/commits

列出最近提交

GET

/repos/{owner}/{repo}/compare

比较两个 refs(额外工具)

GET

/issues

列出 issue(默认仓库或 owner/repo)

GET

/issues/{index}

按编号获取单个 issue

POST

/issues

创建新 issue

PATCH

/issues/{index}

更新 issue(例如将其关闭)

GET

/issues/{index}/comments

列出 issue 的评论

POST

/issues/{index}/comments

对 issue 发表评论

GET

/branches

列出分支(默认仓库或 owner/repo)

POST

/branches

创建新分支

DELETE

/branches/{name}

删除分支

GET

/prs

列出拉取请求

POST

/prs

创建拉取请求

GET

/prs/{index}

获取单个 PR

PATCH

/prs/{index}

更新 PR(例如将其关闭)

POST

/prs/{index}/merge

合并拉取请求

GET

/prs/{index}/reviews

列出 PR 的 review(额外工具)

POST

/prs/{index}/comments

对 PR 发表评论

GET

/actions

列出 CI 工作流运行

GET

/commits/{sha}/statuses

获取 CI 状态检查(额外工具)

GET

/releases

列出 release

POST

/releases

创建 release

GET

/releases/{release_id}

获取单个 release

PATCH

/releases/{release_id}

更新 release

DELETE

/releases/{release_id}

删除 release

额外工具: /repos/.../compare、/prs/{index}/reviews 和 /commits/{sha}/statuses 默认不会显示在 OpenAPI schema 中,以减少 token 数量。设置 MCP_GITEA_EXTRA_TOOLS=1 可暴露这些工具。

Notify(配置了 Discord 或 Ntfy 时)

方法

路径

描述

POST

/notify

向已配置的通知提供器发送通知

天气(设置了 WEATHER_LOCATION 时)

方法

路径

描述

GET

/weather

当前天气条件与多日预报

示例

# List available commands
curl http://127.0.0.1:8000/commands

# Execute the `log` command (dedicated route — the only way to run it)
curl -X POST http://127.0.0.1:8000/log \
     -H 'Content-Type: application/json' \
     -d '{"message": "Server started"}'

响应:

{"stdout": "[2026-01-15T10:30:00-0500] [INFO] Server started\n", "stderr": "", "exit_code": 0, "success": true}

如果设置了 API Key,请在请求头中包含它:

curl -H "X-API-Key: your-secret-key" http://127.0.0.1:8000/commands

校验 registry

在编辑 registry 文件后、重启服务器之前,你可以先校验这些文件——类似 Caddy 使用 caddy validate 校验配置那样。

命令行

python -m app.validate

可选地,也可以指定一个自定义 registry 目录:

python -m app.validate /path/to/registry

输出:

MCP Server registry validation: /app/registry

  ✓ log.yaml → log
  ✓ log_read.yaml → log_read
  ✗ broken.yaml: mapping values are not allowed here
  ⚠ noprogram.yaml → noprogram: Executable not found: /usr/bin/nonexistent

  4 file(s) checked · 1 error(s) · 1 warning(s)

  Registry has errors — fix them before restarting.

退出码:

  • 0 — 所有文件有效(存在警告也可以)

  • 1 — 有一个或多个文件存在错误

  • 2 — registry 目录不存在

HTTP

curl http://127.0.0.1:8000/validate

返回一个 JSON 报告,包含每个文件的校验结果,包括重复名称检测和可执行文件是否存在检查。

注册命令

在 registry/ 中创建一个文件(例如 my_tool.yaml):

name: my_tool
description: Does something useful.
executable: /usr/local/bin/my_tool
# (relative paths like scripts/my_tool.sh are resolved against
#  the project root, so they work in any clone or Docker image)
args:
  - name: input
    type: string
    required: true
    help: Path to the input file.
  - name: --verbose
    type: flag
    required: false
    help: Enable verbose output.
  - name: --mode
    type: string
    required: false
    choices: [fast, slow]
    help: Execution mode.

参数定义

字段

类型

描述

name

string

位置占位符或 --flag 名称

type

string

string、int、float、bool 或 flag

required

bool

默认 false

choices

list

可选的白名单值

default

any

可选默认值,调用方省略该参数时自动应用

help

string

人类可读的参数说明

field_name

string

可选的原生工具参数名;设置后,它会成为模型的 OpenAPI 参数名(例如 title 而不是 -t)。原始 name 仍用作命令行里的 flag

hidden

bool

为 true 时,该参数对模型不可见,但仍会以其 default 值被应用,用于那些必须总是传入但不应被模型控制的 flag

flag 类型的参数意味着只有“是否存在”的概念(不需要值)。当该参数为真时,flag 名会被追加到命令行中。

条件命令(requires)

命令可以定义一个 requires 列表,里面包含一些环境变量条件。如果这些条件不满足,命令仍会被加载,但不会注册对应的路由(在 GET /commands 中不会显示)。

requires:
  - "MCP_LOG_ENABLED != false"

这样的用法被 log/log_read 使用,当通过 MCP_LOG_ENABLED=false 关闭日志功能时,它们就会消失。

默认值

任何参数都可以携带一个 default 值。当调用方省略该参数时,执行器会自动填入它——例如,强制某个 flag 总是开启(比如静默模式下的 discord.sh -q):

args:
  - name: -q
    type: flag
    default: true
    help: Quiet mode — forced on by default.

原生路由

registry/ 中定义的每个命令都会自动暴露为它自己的 FastAPI 专用路由——POST /{command_name}——并带有根据 YAML 参数 Spec 自动生成的 Pydantic 请求模型。这意味着平台可以读取 OpenAPI schema,并把每个命令作为带有正确类型参数的原生工具提供给模型(包括字符串、枚举、flag、默认值)。

这些专用路由是执行 registry 命令的唯一方式——没有通用的 POST /execute 端点。registry 文件仍然提供给 GET /commands 和 GET /validate,以便于查看或检查命令,但执行只能通过带类型的 per-command 路由进行。

未知字段会被拒绝(extra: forbid)并返回 422,缺少必填参数同样返回 422。

field_name 这个 YAML 键控制模型看到的参数名。当未设置时,使用该参数本身的 name,其中开头的 - 会被去掉。

如果其中一个注册表中的命令名称与现有路由冲突(例如 events、issues),则专用路由会被跳过并发出警告,且该命令无法通过 HTTP 执行(它仍然出现在 GET /commands 中)。请在注册表中重命名该命令以启用其执行。

客户端库

一个基于 httpx 的小型同步客户端位于 app/client.py 中。它镜像了整个 HTTP API,因此模型或脚本可以把每个已注册的命令当作原生的 Python 可调用对象来使用。

from app.client import MCPClient

mc = MCPClient("http://127.0.0.1:8000", api_key="your-secret-key")

# Discover available commands
for cmd in mc.list_commands():
    print(cmd["name"], "-", cmd["description"])

# Execute a command
result = mc.execute("log", message="Server started")
print(result["stdout"])

# Bind a command to a reusable callable
log = mc.tool("log")
log(message="Deploy complete")

以 - 开头的标志名不是有效的 Python 标识符,因此请通过字典解包传递它们:**{"-c": "green"}。

如果服务器设置了 MCP_API_KEY,请向客户端传入 api_key= —— 它会在每个请求中以 X-API-Key 请求头的形式发送。

该客户端也可以作为上下文管理器使用:

with MCPClient() as mc:
    mc.execute("log_read", lines="10")

该客户端还提供了针对日历、任务和 Gitea API 的类型化便捷方法(list_events、create_task、list_issues 等)。

项目布局

mcp-server/
├─ app/
│   ├─ __init__.py            # package marker, resolves version via importlib.metadata
│   ├─ main.py                # FastAPI app factory + conditional router registration
│   ├─ auth.py                # API key authentication dependency
│   ├─ models.py              # Pydantic schemas (commands, args, validation)
│   ├─ executor.py            # validation + subprocess wrapper with timeout
│   ├─ registry.py            # YAML/JSON command loader + validate_registry()
│   ├─ validate.py            # `python -m app.validate` CLI
│   ├─ client.py              # httpx client library (commands + calendar + Gitea API)
│   ├─ registry_routes.py     # Auto-generated native routes for registry commands
│   ├─ caldav_models.py       # Pydantic models for CalDAV events/tasks
│   ├─ caldav_service.py      # CalDAV service (1 editable + N read-only calendars)
│   ├─ caldav_routes.py       # FastAPI router for /tasks (CalDAV-specific)
│   ├─ ics_models.py          # Pydantic models for ICS feed config
│   ├─ ics_service.py         # ICS feed fetcher, parser, cache
│   ├─ ics_routes.py          # ICS service singleton management
│   ├─ unified_routes.py      # Unified /events, /calendars router across providers
│   ├─ provider_adapters.py   # CalDAVProvider, ICSProvider adapters
│   ├─ providers.py           # Global provider registry
│   ├─ gitea_models.py        # Pydantic models for Gitea resources
│   ├─ gitea_service.py       # Gitea API service (issues, PRs, branches, releases)
│   ├─ gitea_routes.py        # FastAPI router for /issues, /prs, /branches, etc.
│   ├─ notify_models.py       # Pydantic models for notifications
│   ├─ notify_service.py      # Discord + Ntfy notify providers
│   ├─ notify_routes.py       # FastAPI router for /notify
│   ├─ weather_models.py      # Pydantic models for weather config
│   ├─ weather_service.py     # Open-Meteo API client
│   ├─ weather_routes.py      # FastAPI router for /weather
│   └─ jobs.py                # Lightweight background job scheduler
├─ registry/                  # command definitions (one file per command)
│   ├─ log.yaml               # logging command
│   └─ log_read.yaml          # read log tail
├─ scripts/                   # helper scripts referenced by registry YAMLs
│   ├─ log.sh                 # append to log file
│   ├─ log_read.sh            # read log tail
│   └─ config.sh.example      # template (unused in Docker; for reference)
├─ tests/                     # pytest test suite
│   ├─ conftest.py
│   ├─ test_models.py
│   ├─ test_executor.py
│   ├─ test_registry.py
│   ├─ test_api.py
│   ├─ test_client.py
│   ├─ test_auth.py
│   ├─ test_caldav.py
│   ├─ test_ics.py
│   ├─ test_ics_recurrence.py
│   ├─ test_gitea.py
│   ├─ test_notify.py
│   ├─ test_weather.py
│   ├─ test_logging.py
│   ├─ test_jobs.py
│   └─ test_conditional_endpoints.py
├─ Dockerfile                 # multi-arch base image definition
├─ LICENSE                    # MIT license
├─ variants/                  # variant Dockerfiles (PHP, Node, etc.)
│   ├─ Dockerfile.php
│   └─ Dockerfile.node
├─ docker-compose.yml         # easy local run with volumes
├─ .env.example               # environment variable template
├─ .dockerignore              # excludes venv, secrets, tests, etc.
├─ pyproject.toml             # package metadata + pytest/ruff config
└─ requirements.txt           # pip dependencies (used by Dockerfile)

配置

所有配置均通过环境变量完成。请参阅 .env.example 获取带注释的完整参考。服务器在启动时读取这些变量,并根据条件注册端点。

变量

功能

描述

MCP_API_KEY

认证

端点的 API 密钥(未设置 = 开放访问)

MCP_REGISTRY_DIR

注册表

自定义注册表目录

MCP_LOG_FILE

日志

日志文件路径

MCP_LOG_DIR

日志

日志目录(其中文件为 mcp.log)

MCP_LOG_LEVEL

日志

日志级别(默认:INFO)

MCP_LOG_ENABLED

日志

设为 false 以禁用日志命令

CALDAV_URL

CalDAV

CalDAV 服务器 URL

CALDAV_USERNAME

CalDAV

CalDAV 用户名

CALDAV_PASSWORD

CalDAV

CalDAV 密码

CALDAV_EDITABLE_CALENDAR

CalDAV

可编辑日历名称(未设置 = 全部只读)

CALDAV_READONLY_CALENDARS

CalDAV

逗号分隔的只读日历名称列表

ICS_CALENDAR_URL

ICS

只读 ICS 数据源 URL

ICS_CALENDAR_NAME

ICS

ICS 数据源的显示名称

ICS_REFRESH_INTERVAL

ICS

缓存刷新间隔(秒,默认 300)

GITEA_URL

Gitea

Gitea 服务器 URL

GITEA_TOKEN

Gitea

API 令牌

GITEA_DEFAULT_OWNER

Gitea

默认仓库属主

GITEA_DEFAULT_REPO

Gitea

默认仓库名称

MCP_GITEA_EXTRA_TOOLS

Gitea

在 OpenAPI 模式中暴露小众端点

DISCORD_*_HOOK

通知

Discord Webhook URL(按严重级别)

DISCORD_SERVER_NAME

通知

机器人显示名称覆盖

DISCORD_TITLE_SUFFIX

通知

Discord 消息的标题后缀

NTFY_URL

通知

Ntfy 服务器 URL

NTFY_*_TOPIC

通知

Ntfy 主题(按严重级别)

NTFY_TOKEN

通知

Ntfy 访问令牌

NTFY_USERNAME / NTFY_PASSWORD

通知

Ntfy 基本认证

NTFY_TITLE_SUFFIX

通知

ntfy 消息的标题后缀

WEATHER_LOCATION

天气

表示天气数据的 "lat,long"

TZ

服务器

时区(默认 UTC)

CalDAV 日历

服务器可以连接 CalDAV 服务器(例如 Radicale、Baikal、Nextcloud)来管理日历事件和任务。设计采用一个可编辑日历(可在此创建、更新和删除事件与任务)以及多个只读日历(可见但不可写)。

当 CALDAV_EDITABLE_CALENDAR 未设置时,所有日历均为只读,且不会注册任何创建/更新/删除端点。

日期(editable 标志、calendar_name)而 editable、calendar_name 共同承载于每个事件与任务之上,因此模型可以看到完整统一的日历视图,同时避免意外修改不该接触的日历。

配置

CALDAV_URL=https://caldav.example.com/dav
CALDAV_USERNAME=user
CALDAV_PASSWORD=secret
# Optional: set to make a calendar writable.  When unset, all calendars
# are read-only and write endpoints are not registered.
#CALDAV_EDITABLE_CALENDAR=MyCalendar
# Optional: comma-separated list of read-only calendar names to include.
# If empty, all calendars except the editable one are included as read-only.
#CALDAV_READONLY_CALENDARS=Personal,Work

当 CALDAV_URL 未设置时,日历端点不会注册。

功能

  • 事件(VEVENT): 列出(可按日期范围过滤)、按 UID 获取、创建、更新、删除——支持全天事件和定时事件。

  • 任务 (VTODO): 列出、按 UID 获取、创建、更新、删除——支持优先级、截止日期和状态管理。

  • 连接恢复: 如果 CalDAV 服务器在操作过程中无法访问,服务会自动重置连接并重试一次。可捕获 DAVError、ConnectionError、TimeoutError 和 OSError。

  • 日历缓存: 日历列表在每次连接时获取一次并缓存,避免重复的服务端来回往返。

  • 显式 UUID: 创建的事件和任务总是会获得 uuid4 的 UID,确保它们创建之后就能立即进行更新或删除。

ICS 日历(只读)

服务器可以将一个只读的 ICS 日历数据源(例如 Outlook 的已发布日历、Google Calendar iCal)与 CalDAV 事件一起合并进统一的 /events 端点。

ICS_CALENDAR_URL=https://outlook.office365.com/owa/calendar/.../calendar.ics
ICS_CALENDAR_NAME=Work
ICS_REFRESH_INTERVAL=300  # seconds (default 300, minimum 30)

ICS 数据源在启动时读取并缓存,然后由后台作业定期刷新。使用 POST /calendars/refresh 可手动触发缓存刷新。

Gitea 集成

服务器可以连接 Gitea 实例,以管理仓库、Issue、Pull Request、分支、发布和 CI 动作。当 GITEA_URL 未设置时,不会注册 Gitea 端点。

配置

GITEA_URL=https://git.example.com
GITEA_TOKEN=your-api-token
GITEA_DEFAULT_OWNER=your-username
GITEA_DEFAULT_REPO=your-repo

Issue、分支、PR 和发布端点接受可选查询参数 owner 和 repo,默认使用已配置的值。仓库信息、提交和比较端点则使用路径参数(/repos/{owner}/{repo}/...)。

通知

服务器 能通过 Discord Webhook 和/或 Ntfy 发送通知。多个提供方可以同时启用 —— 一次 /notify 调用会同时扇出到所有已配置的提供者。

Discord Webhook 按严重级别(info、notice、critical、emergency)分别配置。如果某个级别未配置低级别配置。

Ntfy 的使用方法类似,每个严重级别对应各自的主题。认证支持基于令牌的方式或你已拥有的认证方式。

日志

log 和 log_read 命令提供了一个简单的日志工具——将带时间戳的消息追加至文件,再将它们读回。

# Log a message
curl -X POST http://127.0.0.1:8000/log \
     -H 'Content-Type: application/json' \
     -d '{"message": "Deploy complete"}'

# Log with a level
curl -X POST http://127.0.0.1:8000/log \
     -H 'Content-Type: application/json' \
     -d '{"message": "Disk full", "level": "error"}'

# Read the last 20 lines
curl -X POST http://127.0.0.1:8000/log_read \
     -H 'Content-Type: application/json' \
     -d '{"lines": "20"}'

日志文件路径按以下优先级顺序确定:

  1. MCP_LOG_FILE 环境变量——日志文件的完整路径。

  2. MCP_LOG_DIR 环境变量——截图目录;其中的文件名为 mcp.log。

  3. 默认:/tmp/mcp/mcp.log。

如果父目录不存在,则会自动创建相应目录。

设置 MCP_LOG_ENABLED=false 可以完全禁用日志记录——log 和 log_read 命令不会注册,对应的路由也不会存在。

Docker

服务端自带一个支持的 amd64 和 arm64 的多架构 Dockerfile。

构建

docker build -t digitaladapt/mcp-server:latest .

对于多架构构建(需要 buildx):

docker buildx build --platform linux/amd64,linux/arm64 -t digitaladapt/mcp-server:latest .

运行

GLauncher21

docker run -d --name mcp-server -p 8000:8000 \
  --env-file .env \
  -e MCP_API_KEY="your-secret-key" \
  -v ./registry:/app/registry \
  digitaladapt/mcp-server:latest

或使用 docker compose:

docker compose up -d

卷

挂载

用途

/app/registry

命令定义——运行时覆盖或扩展。

/tmp/mcp

默认日志文件位置(或设置 MCP_LOG_FILE)。

scripts/ 目录(包括 log.sh)已烧入镜像中。生产密码永远不会烧入镜像中——通过环境变量提供即可(--env-file .env)。

镜像详情

  • 基础镜像:python:3.12-slim(多架构)

  • 系统依赖:curl、jq(用于脚本)、tini

  • 运行账户:以非 root 的 mcp 用户(uid 1000)运行

  • 入口点:tini(正确的 PID-1 信号处理)

构建变体(PHP、Node 等)

基础 Dockerfile 必须是基础。变体 Dockerfile 位于 variants/ 中,在它的顶层额外装入其他运行时:

变体

Dockerfile

运行时

示例命令

PHP

variants/Dockerfile.php

PHP CLI + curl、mbstring、xml

php_eval

Olive.js

variants/Dockerfile.node

Node.js 22 LTS + npm

node_run

构建一个变体(在存储库根目录):

# PHP
docker build -f variants/Dockerfile.php -t digitaladapt/mcp-server:php .

# Node.js
docker build -f variants/Dockerfile.node -t digitaladapt/mcp-server:node .

运行一个变体:

docker run -p 8000:8000 \
  --env-file .env \
  -v ./registry:/app/registry \
  digitaladapt/mcp-server:php

创建你自己的变体:

# variants/Dockerfile.ruby
FROM digitaladapt/mcp-server:latest
USER root
RUN apt-get update && apt-get install -y --no-install-recommends \
    ruby && rm -rf /var/lib/apt/lists/*
USER mcp

然后添加一个指向 /usr/bin/ruby 的 registry/ruby_eval.yaml。

测试

项目包含一个全面的 pytest 套件,覆盖:Models(模型)、executor、registry、API 端点 的 API 永久链接(app/client.py),以及根目录许可证与全局注释等。它还涵盖、认证、CalDAV 操作、ICS 解析、Gitea 集成、通知、天气、日志、后台任务以及条件可能注册。

项目还包含所有与a comprehensive pytest 、认证、CalDAV 操作、ICS 解析的套件。

# Install dev dependencies
pip install -e ".[dev]"

# Run the full suite
pytest

# Run with verbose output
pytest -v

# Run a single test module
pytest tests/test_executor.py

标志默认值回归场景(如 default: true 的标志)由 test_executor.py::TestValidateAndBuild::test_flag_default_true_* 覆盖。

执行器的超时和进程组 kill 逻辑在 test_executor.py 中进行测试。

安全说明

  • 只能执行 registry/ 中存在的命令——API 没有任意命令执行端点。

  • 在生成子进程之前会验证参数(类型、是否必需、可选值),并拒绝未知参数。

  • 每个命令都有硬性 30 秒超时, 超时后杀死整个进程组。

  • API 密钥认证:如果没有设置 MCP_API_KEY(即撤销该值),/ 端点除 /api/health 和 /api/about 外的所有请求,都需要依赖 X-API-Key 标。启用后即需全局认证; 未启用时全部开放。

  • 错误消息会进行去敏处理——内部细节只记录在服务器日志中,不会暴露在 HTTP 响应里(这很关键,因为错误信息会回流到 LLM 的上下文窗口中)。

  • 在受限的用户账号下运行服务器; 不要授予它 sudo 权限。

  • 任何具有服务器文件系统探查或任意代码执行能力的命令都由设计上移除——只应当注册明确允许的特定命令。


由 Lyra 为你构建——那个在角落里的银发助手。✨

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables building agent-ready APIs that expose tools as both HTTP and MCP endpoints from a single server definition, with automatic OpenAPI, discovery docs, and interactive API reference.
    5
    Apache 2.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to dynamically discover and call backend tools for arithmetic, SQLite-backed task management, GitHub repository lookups, and text statistics, while also exposing the same functionality through a REST API.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables an AI assistant to invoke local file operations, multi-engine web search, weather, system commands, developer utilities, and code execution over MCP, and includes a web dashboard for managing endpoints, testing tools, and viewing live logs.
    36 npm
    1
    MIT