趋近智
开发 MCP 服务器几乎总是需要认证凭据。无论你连接远程 SQL 数据库、集成 GitHub API,还是使用专有 SaaS 平台,你的服务器都需要访问 API 密钥、连接字符串和令牌等秘密信息。将这些凭据直接硬编码到 Python 或 TypeScript 源代码中会造成严重的安全漏洞,并阻碍代码的安全共享或版本控制。
在标准 Web 开发中,我们通常依赖项目根目录下的 .env 文件。然而,MCP 的架构特点引入了一个特定的限制:服务器是由客户端应用(如 Claude Desktop)启动的子进程。这个子进程的工作目录可能与你的开发目录不符,导致 .env 文件的相对路径不可靠。因此,模型上下文协议依赖宿主应用在运行时将环境变量注入服务器进程。
当 MCP 客户端建立连接时,它会为你的服务器创建一个新进程。在此实例化过程中,客户端可以传递一个环境变量字典,这些变量将可用于该进程的标准输入/输出 (stdio) 流或执行上下文。这确保了秘密信息保存在宿主系统的配置层中,从而使你的服务器实现对认证保持通用和无状态。
环境变量注入的数据流遵循严格的层次结构:
配置数据从宿主 JSON 文件传播到服务器运行时的过程。
对于 Claude Desktop 及类似的 MCP 兼容客户端,环境变量在配置文件中定义(在 macOS 上通常是 claude_desktop_config.json,在 Windows 上是 %APPDATA%\Claude\claude_desktop_config.json)。
配置方案在服务器定义中包含一个 env 对象。此对象将变量名映射到其字符串值。客户端在执行 args 中指定的命令之前读取此映射,并确保这些值存在于所启动进程的环境块中。
设想一个场景,你的服务器连接到 Postgres 数据库和天气 API。你的配置将如下所示:
{
"mcpServers": {
"data-service": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/server",
"run",
"mcp-server-data"
],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost:5432/db",
"WEATHER_API_KEY": "sk_live_1234567890",
"LOG_LEVEL": "DEBUG"
}
}
}
}
在此配置中,env 块与 args 明确分开。args 定义了如何运行可执行文件,而 env 定义了它运行的上下文。
一旦注入,这些变量便可使用你的编程语言提供的标准库方法进行访问。无需特定的 MCP SDK 方法来检索它们;它们的功能与系统级环境变量完全相同。
在 Python 中,os 模块是标准接口。然而,对于生产级的 MCP 服务器,建议执行校验。如果缺少必需的变量,服务器最好能快速失败,并在日志中提供描述性错误,而不是在操作中途崩溃。
使用 os.environ:
import os
import logging
# 获取变量,如果不存在则返回 None
db_url = os.environ.get("POSTGRES_CONNECTION_STRING")
# 获取变量,如果缺少则引发通用 KeyError
api_key = os.environ["WEATHER_API_KEY"]
if not db_url:
logging.error("POSTGRES_CONNECTION_STRING is missing from environment.")
# 根据逻辑,你可以在此处引发异常
raise ValueError("Database configuration required")
一种更常见的模式,在中高级实现中常出现,涉及使用 Pydantic 的 BaseSettings(如在第 3 章关于输入校验的讨论)。这允许你定义一个严格类型的配置方案,在启动时校验环境。
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
postgres_connection_string: str
weather_api_key: str
log_level: str = "INFO" # 如果未提供,则为默认值
try:
config = Settings()
except Exception as e:
# 这确保服务器能清楚记录启动失败的原因
print(f"Configuration Error: {e}")
在 TypeScript 或 JavaScript (Node.js) 中,这些值位于 process.env 中。
const API_KEY = process.env.WEATHER_API_KEY;
if (!API_KEY) {
console.error("Error: WEATHER_API_KEY not set in client configuration");
process.exit(1);
}
// 在工具处理程序中使用
const response = await fetch(`https://api.weather.com/v1?key=${API_KEY}`);
在 MCP 环境下管理环境变量时,请考虑运行时环境的隔离性。
生产逻辑中避免使用 Dotenv
尽管 python-dotenv 或 dotenv 等库非常适合本地开发,但在已安装的 MCP 服务器中使用它们可能会出现问题。如果客户端从与 .env 文件所在目录不同的位置启动服务器,该文件将不会被加载。更安全的方法是完全依赖宿主配置文件的注入,它作为真实信息的来源。
保护配置文件
claude_desktop_config.json 文件包含敏感的明文凭据。请确保此文件具有适当的文件系统权限(例如,仅可由你的用户账户读取)。如果你将 MCP 服务器代码分发给其他开发人员或团队成员,请提供配置模板,但切勿将实际凭据提交到版本控制系统。
变量范围 配置文件中定义的变量仅限于该特定服务器进程。如果你注册了多个 MCP 服务器(例如,一个用于文件系统访问,另一个用于数据库访问),它们不会共享环境变量。这种隔离是一项安全功能,确保一个受损或有 bug 的工具无法访问为另一个服务器准备的 API 密钥。
集成过程中一个常见问题是“未找到变量”错误,即使配置文件看起来正确。这通常由三个原因引起:
env 块,或者无法解析整个服务器定义。API_KEY)和代码访问(例如 os.environ["API_KEY"])之间大小写完全匹配。通过将配置集中在宿主应用中,你可以将服务器的逻辑与其凭据解耦,遵循 12-factor app 方法论,并确保你的 MCP 服务器可以在不同环境和客户端之间移植。
这部分内容有帮助吗?
os - Miscellaneous operating system interfaces (Environment variables), Python Software Foundation, 2024 (Python Software Foundation) - Python 中使用 os.environ 访问和操作环境变量的官方文档。pydantic-settings 进行结构化配置管理以加载和验证环境变量的文档。process object (Environment Variables), Node.js Foundation, 2024 - 通过 process.env 在 Node.js 应用程序中访问环境变量的官方文档。© 2026 ApX Machine Learning用心打造