首页
/ 使用 Terraform 管理 LiteLLM MCP Server:resource_mcp_server 资源完全指南

使用 Terraform 管理 LiteLLM MCP Server:resource_mcp_server 资源完全指南

2026-09-07 14:49:13作者:魏侃纯Zoe

导读

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_toolsenv_varsstatic_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 仅收敛为 nonebearerbasic 三种,配置时应以此为准。


二、四个官方示例逐段拆解

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_nameurltransport)外加展示用的 alias/descriptionauth_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:// 前缀占位,真正决定如何拉起进程的是 commandargs
  • 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 传输类型,仅允许 httpssestdio

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 鉴权方式,仅允许 nonebearerbasic
mcp_access_groups list(string) 允许使用该 MCP 服务器的访问组列表
command string stdio 传输时要执行的命令(如 python3npx
args list(string) 仅 stdio:命令参数列表。不要把密钥放进 args
env map(string),标记为 Sensitive 仅 stdio:命令的环境变量。plan 输出会隐藏,但明文落盘于 state

spec_versionauth_type 的默认值、envSensitive: true 标记,在 resource_mcp_server.go 的 Schema 定义中逐项可查。

mcp_info 嵌套块

mcp_infoMaxItems = 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 applylitellm_mcp_server 触发动作时,Provider 会执行如下请求(实现见 resource_mcp_server_crud.go):

  • CreatePOST /v1/mcp/server,把 HCL 中所有参数组装成 MCPServerRequest,响应里的 server_id 被写入资源 ID(d.SetId(mcpResp.ServerID));
  • ReadGET /v1/mcp/server/{server_id},将远端状态回填进 Terraform state。特别地,若返回 mcp_server_not_found,Provider 会清空资源 ID 以在后续 apply 中触发重建,而不是报错;
  • UpdatePUT /v1/mcp/server,请求体附带 server_id 字段以保证指向正确的服务器;
  • DeleteDELETE /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 最近一次健康检查的错误信息(如有)

statuslast_health_checkhealth_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-serversLITELLM_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 计费。生产建议:

  1. 把成本最高、最易被循环调用的工具单独定价(如企业网关中的 generate_report = 0.50);
  2. 本地/内部工具显式设为 0.0,避免内部流量污染外部计费账单;
  3. 成本信息随服务器元数据存储于 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_toolsextra_headersallow_all_keys 等只读视角。出于安全考虑,数据源 刻意不暴露 envcredentialsstatic_headers 等内容——它们可能持有密钥。资源与数据源在 Terraform Provider 目录 terraform/provider/litellm/ 下成对实现(resource_mcp_server*.godata_source_mcp_server*.go)。


九、综合实战建议

将以上内容落成一套可执行的工作流:

  1. 先规划权限模型:梳理团队 → access group 的映射,避免把服务器直接暴露给全员;
  2. 按传输类型分文件组织:远程 SaaS(HTTP/SSE)与本地进程(stdio)分开管理,stdio 文件中对 env 一律通过变量引用,并开启远程 state 加密后端;
  3. 统一成本口径:每个对外收费的工具都先填写 tool_name_to_cost_per_query,再设一个保守的 default_cost_per_query 兜底;
  4. 用 import 收敛存量:对已在 Proxy 中手工注册的服务器执行 terraform import litellm_mcp_server.<name> <server-id>,纳入 IaC 后只允许通过 terraform apply 变更;
  5. 持续观察健康状态:apply 后通过 terraform state show 或输出块监控 status / last_health_check / health_check_error,第一时间发现不可用的 MCP 端点。

十、快速索引

登录后查看全文
热门项目推荐
相关项目推荐