使用 Terraform 管理 LiteLLM MCP Server:resource_mcp_server 资源完全指南
导读
terraform-provider-litellm 的 litellm_mcp_server 资源 用于在 LiteLLM Proxy 中声明式地管理 MCP(Model Context Protocol)服务器。MCP 服务器通过暴露的 tools 与 resources,让接入 LiteLLM 的大模型能够调用 GitHub、Zapier、企业内网 API 乃至本地开发脚本等外部能力。读完本文,你将掌握如何通过 Terraform HCL 配置 HTTP / SSE / stdio 三种传输协议的 MCP 服务器,如何用访问组做权限收敛,如何按工具粒度配置成本核算,以及如何安全处理 stdio 场景下的命令参数与环境变量。
一、资源定位:它在 LiteLLM 技术栈中处于什么位置
LiteLLM 在 litellm/types/mcp_server/mcp_server_manager.py 中维护了一个可跨实例共享的 MCP 服务器管理器(global_mcp_server_manager),其核心数据模型 MCPServer 支持 http/sse/stdio 多种传输、none/bearer/basic/oauth2 等鉴权方式,以及 allowed_tools、env_vars、static_headers、单工具级成本信息等配置。
Terraform Provider 中的 litellm_mcp_server 资源,本质上是对 Proxy 管理 API POST/PUT/GET/DELETE /v1/mcp/server 的封装——CRUD 常量的定义位于 resource_mcp_server_crud.go。因此,凡是代码里通过 HTTP 调用来注册、修改、查询、删除 MCP 服务器的操作,都可以等价地用一段 terraform apply 来完成,并获得 Terraform 状态文件的幂等性与可审计性。
从源码结构看,Proxy 侧还支持 OAuth2、AWS SigV4、Token Exchange 等更高级的 MCP 鉴权形态(见
MCPServer模型中的oauth2/aws_*/token_exchange_*字段),但当前版本 Terraform 资源暴露的auth_type仅收敛为none、bearer、basic三种,配置时应以此为准。
二、四个官方示例逐段拆解
2.1 基础 HTTP MCP Server
resource "litellm_mcp_server" "github_server" {
server_name = "github-mcp-server"
alias = "github"
description = "GitHub MCP server for repository operations"
url = "https://api.github.com/mcp"
transport = "http"
auth_type = "bearer"
mcp_access_groups = ["dev_team", "devops_team"]
}
这是最精简的形态:只有 4 个必填参数(server_name、url、transport)外加展示用的 alias/description。auth_type = "bearer" 意味着请求该 MCP 服务器时需携带 Bearer Token。实际接入时通常还需要在 LiteLLM 侧或经由凭证/密钥通道补充该 token 的具体值,Terraform 只负责服务端注册与元数据。
2.2 SSE 传输 + 完整成本核算
resource "litellm_mcp_server" "zapier_server" {
server_name = "zapier-automation"
alias = "zapier"
description = "Zapier MCP server for workflow automation"
url = "https://actions.zapier.com/mcp/sk-xxxxx/sse"
transport = "sse"
auth_type = "bearer"
spec_version = "2024-11-05"
mcp_access_groups = ["automation_team", "marketing_team"]
mcp_info {
server_name = "Zapier Integration Server"
description = "Provides automation tools through Zapier's MCP interface"
logo_url = "https://zapier.com/assets/images/zapier-logo.png"
mcp_server_cost_info {
default_cost_per_query = 0.01
tool_name_to_cost_per_query = {
"send_email" = 0.05
"create_document" = 0.03
"update_spreadsheet" = 0.02
"post_to_slack" = 0.01
"create_calendar_event" = 0.04
}
}
}
}
SSE 适合需要服务端主动推送事件流的场景(如 Zapier 这类自动化平台)。示例同时展示了 按工具差异化计费:default_cost_per_query 是兜底单价(0.01 美元/次),tool_name_to_cost_per_query 则对单个工具给出更贵的单价——比如 send_email 每次 0.05 美元,以便更贴近真实成本、抑制高消耗工具的滥用。
2.3 stdio 本地开发服务器
resource "litellm_mcp_server" "local_dev_server" {
server_name = "local-development-tools"
alias = "local-dev"
description = "Local MCP server for development tools"
url = "stdio://local-dev"
transport = "stdio"
auth_type = "none"
command = "python3"
args = ["/opt/mcp-servers/dev-tools/server.py", "--verbose"]
env = {
"PYTHONPATH" = "/opt/mcp-servers/dev-tools"
"DEBUG" = "true"
"LOG_LEVEL" = "info"
"WORKSPACE_DIR" = "/workspace"
}
mcp_access_groups = ["local_developers"]
mcp_info {
server_name = "Development Tools"
description = "Local development utilities and tools"
mcp_server_cost_info {
default_cost_per_query = 0.0 # Free for local development
}
}
}
stdio 传输通过标准输入输出与本地进程通信,用于托管在 LiteLLM 所在主机上的命令行工具。关键点:
url使用stdio://前缀占位,真正决定如何拉起进程的是command与args;env注入进程环境变量(这里全部设置为本地免费场景,成本单价为 0);- 无需任何
auth_type,设为none。
2.4 企业级全量配置
resource "litellm_mcp_server" "enterprise_api_server" {
server_name = "enterprise-api-gateway"
alias = "enterprise"
description = "Enterprise API gateway MCP server"
url = "https://api.enterprise.com/mcp/v1"
transport = "http"
auth_type = "bearer"
spec_version = "2024-11-05"
mcp_access_groups = [
"enterprise_users",
"api_consumers",
"integration_team"
]
mcp_info {
server_name = "Enterprise API Gateway"
description = "Provides access to enterprise APIs and services"
logo_url = "https://enterprise.com/logo.png"
mcp_server_cost_info {
default_cost_per_query = 0.10
tool_name_to_cost_per_query = {
"query_database" = 0.25
"generate_report" = 0.50
"send_notification" = 0.05
"create_user" = 0.15
"update_permissions" = 0.20
"audit_log_query" = 0.30
}
}
}
}
典型的企业接入面:一个 HTTP MCP 网关,绑定三个访问组,default_cost_per_query 抬高到 0.10 美元,并针对数据库查询、报表生成、权限变更、审计日志等高价值/高风险操作设置差异单价。
三、参数参考(Argument Reference)
必填参数
| 参数 | 类型 | 说明 |
|---|---|---|
server_name |
string | MCP 服务器的名称,会作为资源标识呈现给使用者 |
url |
string | MCP 服务器地址;stdio 传输需使用 stdio:// 前缀 |
transport |
string | 传输类型,仅允许 http、sse、stdio |
transport 的取值在白名单校验里写死为三者之一,定义见 resource_mcp_server.go;若传入其他值,terraform plan/apply 阶段会被 Provider 直接拒绝。
可选参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
alias |
string | — | 服务器别名,便于在 Prompt/调用侧简短引用 |
description |
string | — | 服务器用途说明 |
spec_version |
string | 2024-11-05 |
MCP 规范版本,未指定时回落到该日期版本 |
auth_type |
string | none |
鉴权方式,仅允许 none、bearer、basic |
mcp_access_groups |
list(string) | — | 允许使用该 MCP 服务器的访问组列表 |
command |
string | — | stdio 传输时要执行的命令(如 python3、npx) |
args |
list(string) | — | 仅 stdio:命令参数列表。不要把密钥放进 args |
env |
map(string),标记为 Sensitive | — | 仅 stdio:命令的环境变量。plan 输出会隐藏,但明文落盘于 state |
spec_version 与 auth_type 的默认值、env 的 Sensitive: true 标记,在 resource_mcp_server.go 的 Schema 定义中逐项可查。
mcp_info 嵌套块
mcp_info(MaxItems = 1)用于补充服务器展示信息与成本配置,其内部字段:
| 字段 | 说明 |
|---|---|
server_name |
展示用服务器名 |
description |
展示用描述 |
logo_url |
服务器 Logo 地址 |
mcp_server_cost_info 嵌套块(位于 mcp_info 内)
| 字段 | 类型 | 说明 |
|---|---|---|
default_cost_per_query |
float | 所有工具的默认单次调用成本 |
tool_name_to_cost_per_query |
map(float) | 指定工具名 → 单次调用成本的映射,优先级高于默认值 |
这两层嵌套结构在 Schema 中的定义见 resource_mcp_server.go,并在请求构造时递归转换为 Proxy API 的 MCPServerRequest/MCPInfo/MCPServerCostInfo JSON 结构(见 types.go 中的 json:"mcp_server_cost_info"、json:"tool_name_to_cost_per_query" 标签)。
四、资源创建、导入与生命周期
4.1 创建 / 更新 / 删除背后的 API 调用
每次 terraform apply 对 litellm_mcp_server 触发动作时,Provider 会执行如下请求(实现见 resource_mcp_server_crud.go):
- Create:
POST /v1/mcp/server,把 HCL 中所有参数组装成MCPServerRequest,响应里的server_id被写入资源 ID(d.SetId(mcpResp.ServerID)); - Read:
GET /v1/mcp/server/{server_id},将远端状态回填进 Terraform state。特别地,若返回mcp_server_not_found,Provider 会清空资源 ID 以在后续 apply 中触发重建,而不是报错; - Update:
PUT /v1/mcp/server,请求体附带server_id字段以保证指向正确的服务器; - Delete:
DELETE /v1/mcp/server/{server_id},成功则移除资源 ID。
另外,代码中保留了一个 retryMCPServerRead 辅助函数(指数退避,从 1 秒起逐步翻倍并封顶 10 秒),说明注册类 API 可能存在最终一致性窗口,读取时需要容忍短暂的“未找到”。
4.2 导入既有服务器
对于已在 Proxy 中存在的 MCP 服务器,可以用资源 ID 直接纳入 Terraform 管理:
terraform import litellm_mcp_server.example server-id-here
导入机制基于 schema.ImportStatePassthroughContext(见 resource_mcp_server.go),导入完成后执行一次 Read 将远端属性回填到 state。
4.3 只读导出属性(Attribute Reference)
除上述配置参数外,apply/refresh 后资源会额外导出以下属性(对应 Proxy 返回的 MCPServerResponse,见 types.go):
| 属性 | 含义 |
|---|---|
server_id |
MCP 服务器的全局唯一标识 |
created_at |
创建时间戳 |
created_by |
创建者 |
updated_at |
最近更新时间戳 |
updated_by |
最近更新者 |
status |
服务器当前状态 |
last_health_check |
最近一次健康检查时间戳 |
health_check_error |
最近一次健康检查的错误信息(如有) |
status、last_health_check、health_check_error 是 Proxy 侧健康检查机制的输出,可用于监控 MCP 服务器的可用性。
五、传输类型对比与选型建议
| 维度 | HTTP | SSE | stdio |
|---|---|---|---|
| 通信方式 | 标准 HTTP/HTTPS 请求-响应 | 服务端事件流(Server-Sent Events) | 标准输入输出管道 |
| 适用场景 | REST API 形态的 MCP 服务器 | 需要服务端实时推送更新,如 Zapier | 本地进程、命令行工具 |
| 鉴权支持 | 由 auth_type 提供 |
由 auth_type 提供 |
一般设 none(本机信任) |
| 额外必配 | 无 | 建议显式声明 spec_version |
command,可选 args/env |
值得注意的是,stdio 模式下 env 变量与 args 参数会被传入被拉起进程,若进程位于 Proxy 宿主机上,任何能读取进程列表或 procfs 的账号都可能看到命令行中的 args——这正是文档强调“不要通过 args 传递密钥”的原因;env 虽对 Terraform plan 隐藏、也建议配合加密的远程 state 使用。
补充:env 不会被服务端响应覆写
Provider 配套的单元测试 resource_mcp_server_crud_test.go 验证了一个容易被忽略的细节:当 Proxy 在 Read 响应中原样返回服务器内存中解析后的 env(可能包含服务端派生出的明文令牌)时,updateSchemaFromResponse 不会用服务端值覆盖本地配置的 env,也不会把服务端额外返回的密钥写入 state——从而避免密钥通过 state 文件外泄。这为“env 是敏感字段”提供了源码级佐证。
六、访问控制:用 mcp_access_groups 做权限收敛
mcp_access_groups 直接对接 LiteLLM 的权限管理系统:只有列表中被授权的访问组(通常是团队、角色或用户组)所关联的 API Key 才能调用该 MCP 服务器暴露的 tools。
在 Proxy 侧,MCPRequestHandler 解析请求头中的 x-litellm-mcp-servers(LITELLM_MCP_SERVERS_HEADER_NAME),把逗号分隔的服务器名/访问组名解析后交给全局 MCP 服务器管理器做授权判定(见 user_api_key_auth_mcp.py)。设计上遵循“最少授权”原则:
- 一个服务器可以同时归属多个访问组(如
["dev_team", "devops_team"]),任一命中即可访问; - 未命中的团队在使用工具时会收到权限拒绝,而不是能发现工具的元数据;
- 当需要按工具而非按服务器细粒度收敛时,Proxy 侧
MCPServer还支持allowed_tools/disallowed_tools/tool_name_to_display_name等字段,可配合在控制台或管理 API 层补充(当前 Terraform 资源未直接暴露这些字段,可从源码 mcp_server_manager.py 确认其存在)。
因此建议在组织内将 mcp_access_groups 视为 RBAC 的一部分:先建好代表团队的 access group,再在 MCP 服务器资源中引用,避免用“全体可用”的宽松策略上线高风险工具。
七、成本跟踪:把 MCP 工具调用纳入计量
mcp_info.mcp_server_cost_info 让 MCP 工具调用像 LLM 请求一样被计入成本与用量体系:
default_cost_per_query:未单独定价工具的默认单价;tool_name_to_cost_per_query:按工具名覆盖默认单价。
计费逻辑遵循“具体优先于默认”:示例中 send_email = 0.05 覆盖 default_cost_per_query = 0.01,而未被列出的工具(如 list_triggers)按 0.01 计费。生产建议:
- 把成本最高、最易被循环调用的工具单独定价(如企业网关中的
generate_report = 0.50); - 本地/内部工具显式设为
0.0,避免内部流量污染外部计费账单; - 成本信息随服务器元数据存储于
MCPInfo结构中(字段为mcp_server_cost_info,见 types.go),因此可在 Proxy 的日志、用量与预算报表中统一关联。
八、配套 Data Source:只读查询与密钥保护
除了管理资源的资源类型,Provider 还提供对应的 litellm_mcp_server 数据源,用于把已存在的服务器信息读入 Terraform 配置做引用:
data "litellm_mcp_server" "github" {
server_id = "srv-1234"
}
output "github_mcp_url" {
value = data.litellm_mcp_server.github.url
}
数据源基于 GET /v1/mcp/server/{server_id},额外导出 allowed_tools、extra_headers、allow_all_keys 等只读视角。出于安全考虑,数据源 刻意不暴露 env、credentials、static_headers 等内容——它们可能持有密钥。资源与数据源在 Terraform Provider 目录 terraform/provider/litellm/ 下成对实现(resource_mcp_server*.go 与 data_source_mcp_server*.go)。
九、综合实战建议
将以上内容落成一套可执行的工作流:
- 先规划权限模型:梳理团队 → access group 的映射,避免把服务器直接暴露给全员;
- 按传输类型分文件组织:远程 SaaS(HTTP/SSE)与本地进程(stdio)分开管理,stdio 文件中对
env一律通过变量引用,并开启远程 state 加密后端; - 统一成本口径:每个对外收费的工具都先填写
tool_name_to_cost_per_query,再设一个保守的default_cost_per_query兜底; - 用 import 收敛存量:对已在 Proxy 中手工注册的服务器执行
terraform import litellm_mcp_server.<name> <server-id>,纳入 IaC 后只允许通过terraform apply变更; - 持续观察健康状态:apply 后通过
terraform state show或输出块监控status/last_health_check/health_check_error,第一时间发现不可用的 MCP 端点。
十、快速索引
- 资源参考文档:terraform/provider/docs/resources/mcp_server.md
- 数据源参考文档:terraform/provider/docs/data-sources/mcp_server.md
- Terraform Schema 定义:terraform/provider/litellm/resource_mcp_server.go
- CRUD / API 封装实现:terraform/provider/litellm/resource_mcp_server_crud.go
- 请求 / 响应类型定义:terraform/provider/litellm/types.go
- env 密钥保护单元测试:terraform/provider/litellm/resource_mcp_server_crud_test.go
- Proxy 侧 MCP 服务器数据模型:litellm/types/mcp_server/mcp_server_manager.py
- MCP 请求鉴权与服务器解析:litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00