> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unla.amoylab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Gateway 配置

> mcp-gateway.yaml 配置文件详细说明

配置文件支持使用 `${VAR:default}` 语法进行环境变量注入。如果环境变量未设置，将使用默认值。

常见的做法是通过不同的 `.env`、`.env.development`、`.env.prod` 进行注入，当然也可以直接修改配置写死一个值。

## 基础配置

```yaml theme={null}
port: ${MCP_GATEWAY_PORT:5235}                      # 服务监听端口
pid: "${MCP_GATEWAY_PID:/var/run/mcp-gateway.pid}"  # PID文件路径
```

<Note>
  这里的 PID 和下面涉及的 PID 保持一致，用于服务管理和热重载功能。
</Note>

## 存储配置

存储配置模块主要用于存储网关的代理配置信息。目前支持两种存储方式：

<CardGroup cols={2}>
  <Card title="db 存储" icon="database">
    存到数据库，每个配置是一条记录，支持 SQLite3、PostgreSQL、MySQL
  </Card>

  <Card title="api 存储" icon="api">
    通过 API 端点存储配置，允许使用外部配置管理系统
  </Card>
</CardGroup>

### 配置示例

```yaml theme={null}
storage:
  type: "${GATEWAY_STORAGE_TYPE:db}"                    # 存储类型：db, api

  # 数据库配置（当 type 为 'db' 时使用）
  database:
    type: "${GATEWAY_DB_TYPE:sqlite}"                   # 数据库类型（sqlite,postgres, mysql）
    host: "${GATEWAY_DB_HOST:localhost}"                # 数据库主机地址
    port: ${GATEWAY_DB_PORT:5432}                       # 数据库端口
    user: "${GATEWAY_DB_USER:postgres}"                 # 数据库用户名
    password: "${GATEWAY_DB_PASSWORD:example}"          # 数据库密码
    dbname: "${GATEWAY_DB_NAME:./data/mcp-gateway.db}"  # 数据库名称或文件路径
    sslmode: "${GATEWAY_DB_SSL_MODE:disable}"           # 数据库连接的 SSL 模式

  # API 配置（当 type 为 'api' 时使用）
  api:
    url: "${GATEWAY_STORAGE_API_URL:}"                  # API 端点 URL
    configJSONPath: "${GATEWAY_STORAGE_API_CONFIG_JSON_PATH:}"  # API 响应中配置的 JSON 路径
    timeout: "${GATEWAY_STORAGE_API_TIMEOUT:30s}"       # 请求超时时间
```

## 通知配置

通知配置模块主要是用来当配置更新的时候如何让 `mcp-gateway` 感知到更新并进行热重载而无需重启服务。

### 支持的通知方式

<CardGroup cols={2}>
  <Card title="signal" icon="bell">
    通过发送操作系统信号量来通知，类似 `kill -SIGHUP <pid>` 或者 `nginx -s reload` 这种方式
  </Card>

  <Card title="api" icon="webhook">
    通过调用一个 API 的方式通知，`mcp-gateway` 会监听一个独立的端口
  </Card>

  <Card title="redis" icon="database">
    通过 redis 的发布/订阅功能通知，适合单机或集群部署时使用
  </Card>

  <Card title="composite" icon="puzzle-piece">
    组合通知，通过多种方式组合，默认 `signal` 和 `api` 一定会开启
  </Card>
</CardGroup>

### 通知角色说明

<AccordionGroup>
  <Accordion icon="paper-plane" title="sender（发送者）">
    负责发送通知，`apiserver` 只能走这个模式
  </Accordion>

  <Accordion icon="inbox" title="receiver（接收者）">
    负责接收通知，单机的 `mcp-gateway` 建议只走这个模式
  </Accordion>

  <Accordion icon="arrows-repeat" title="both（双向）">
    既是发送者又是接收者，集群部署的 `mcp-gateway` 可以走这个方式
  </Accordion>
</AccordionGroup>

### 配置示例

```yaml theme={null}
notifier:
  role: "${NOTIFIER_ROLE:receiver}" # 角色：'sender'（发送者）或 'receiver'（接收者）
  type: "${NOTIFIER_TYPE:signal}"   # 类型：'signal'（信号）、'api'、'redis' 或 'composite'（组合）

  # 信号配置（当 type 为 'signal' 时使用）
  signal:
    signal: "${NOTIFIER_SIGNAL:SIGHUP}"                     # 要发送的信号
    pid: "${NOTIFIER_SIGNAL_PID:/var/run/mcp-gateway.pid}"  # PID 文件路径

  # API 配置（当 type 为 'api' 时使用）
  api:
    port: ${NOTIFIER_API_PORT:5235}                                         # API 端口
    target_url: "${NOTIFIER_API_TARGET_URL:http://localhost:5235/_reload}"  # 重载端点

  # Redis 配置（当 type 为 'redis' 时使用）
  redis:
    addr: "${NOTIFIER_REDIS_ADDR:localhost:6379}"                               # Redis 地址
    password: "${NOTIFIER_REDIS_PASSWORD:UseStrongPasswordIsAGoodPractice}"     # Redis 密码
    db: ${NOTIFIER_REDIS_DB:0}                                                  # Redis 数据库编号
    topic: "${NOTIFIER_REDIS_TOPIC:mcp-gateway:reload}"                         # Redis 发布/订阅主题
```

## 会话存储配置

会话存储配置用于存储 MCP 中的会话信息。根据不同的部署场景，可以选择不同的存储方式：

<CardGroup cols={2}>
  <Card title="memory 存储" icon="brain">
    内存存储，适合单机部署（需注意，重启会失去会话信息）
  </Card>

  <Card title="redis 存储" icon="database">
    Redis 存储，适合单机或集群部署，支持持久化
  </Card>
</CardGroup>

### 配置示例

```yaml theme={null}
session:
  type: "${SESSION_STORAGE_TYPE:memory}"                    # 存储类型：memory, redis
  redis:
    addr: "${SESSION_REDIS_ADDR:localhost:6379}"            # Redis 地址
    password: "${SESSION_REDIS_PASSWORD:}"                  # Redis 密码
    db: ${SESSION_REDIS_DB:0}                               # Redis 数据库编号
    topic: "${SESSION_REDIS_TOPIC:mcp-gateway:session}"     # Redis 发布/订阅主题
```

<Warning>
  使用 memory 存储时，服务重启会导致所有会话信息丢失。生产环境建议使用 redis 存储。
</Warning>

## Forward Headers 配置

Forward Headers 配置允许 MCP Gateway 将客户端请求中的 HTTP 头部转发到下游服务。此功能对于身份验证、请求追踪和自定义头部传播非常有用。

<Info>
  为了向后兼容，Forward Headers 功能默认为禁用状态。通过在配置中设置 `enabled: true` 来启用此功能。
</Info>

### 功能特性

<CardGroup cols={2}>
  <Card title="头部过滤" icon="filter">
    使用允许/忽略列表控制哪些头部被转发，支持大小写不敏感匹配
  </Card>

  <Card title="客户端头部" icon="globe">
    将客户端请求（tools/list 和 tools/call）中的头部转发到下游服务
  </Card>

  <Card title="参数头部" icon="code">
    支持通过可配置的参数名称转发作为工具参数传递的头部
  </Card>

  <Card title="覆盖控制" icon="toggle-on">
    选择是否覆盖现有头部或添加到现有头部
  </Card>
</CardGroup>

### 配置选项

```yaml theme={null}
forward:
  enabled: ${FORWARD_ENABLED:false}                                     # 启用 forward headers（默认：false）
  
  mcp_arg:
    key_for_header: "${FORWARD_MCP_ARG_KEY_FOR_HEADER:__forwardHeaders}" # 工具参数的参数名
  
  header:
    allow_headers: "${FORWARD_ALLOW_HEADERS:}"                          # 允许的头部列表，逗号分隔（优先级更高）
    ignore_headers: "${FORWARD_IGNORE_HEADERS:Accept, Accept-Encoding, Accept-Language, Host, Cookie, Connection, User-Agent, Content-Length, Content-Type}" # 要忽略的头部
    case_insensitive: ${FORWARD_HEADER_CASE_INSENSITIVE:true}           # 大小写不敏感的头部匹配
    override_existing: ${FORWARD_HEADER_OVERRIDE_EXISTING:false}        # 覆盖现有头部而不是添加
```

### 头部过滤逻辑

过滤逻辑遵循基于优先级的方法：

<Steps>
  <Step title="优先级检查">
    如果配置了 `allow_headers`（非空），它优先生效，`ignore_headers` 会被完全忽略
  </Step>

  <Step title="允许列表模式">
    当设置 `allow_headers` 时，只有此列表中的头部会被转发，其他所有头部都被忽略
  </Step>

  <Step title="忽略列表模式">
    当 `allow_headers` 为空时，`ignore_headers` 列表中的头部会被过滤掉，其他头部会被转发
  </Step>

  <Step title="大小写敏感性">
    头部匹配遵循 `case_insensitive` 设置，同时适用于允许和忽略列表
  </Step>
</Steps>

### 使用示例

#### 示例 1: 只允许特定头部

```yaml theme={null}
forward:
  enabled: true
  header:
    allow_headers: "Authorization, X-API-Key, X-Request-ID"
    ignore_headers: "Host, Cookie"  # 这个会被忽略
    case_insensitive: true
```

**结果**: 只有 `Authorization`、`X-API-Key` 和 `X-Request-ID` 头部会被转发。

#### 示例 2: 阻止特定头部

```yaml theme={null}
forward:
  enabled: true
  header:
    allow_headers: ""  # 空值 - 使用忽略列表
    ignore_headers: "Accept, Host, Cookie, User-Agent"
    case_insensitive: true
```

**结果**: 除了 `Accept`、`Host`、`Cookie` 和 `User-Agent` 外，所有头部都会被转发。

#### 示例 3: 工具参数头部

```yaml theme={null}
forward:
  enabled: true
  mcp_arg:
    key_for_header: "custom_headers"
  header:
    override_existing: true
```

工具现在可以通过 `custom_headers` 参数传递头部：

```json theme={null}
{
  "name": "api_call",
  "arguments": {
    "url": "https://api.example.com/data",
    "custom_headers": {
      "Authorization": "Bearer token123",
      "X-Custom-Header": "value"
    }
  }
}
```

### 环境变量

所有 forward headers 设置都可以通过环境变量进行配置：

```bash theme={null}
# 启用功能
FORWARD_ENABLED=true

# 配置头部转发行为
FORWARD_MCP_ARG_KEY_FOR_HEADER=__forwardHeaders
FORWARD_ALLOW_HEADERS="Authorization, X-API-Key"
FORWARD_IGNORE_HEADERS="Accept, Host, Cookie"
FORWARD_HEADER_CASE_INSENSITIVE=true
FORWARD_HEADER_OVERRIDE_EXISTING=false
```

<Warning>
  在生产环境中启用 forward headers 时，请仔细审查应该转发哪些头部，以避免安全风险，如暴露敏感的身份验证令牌或 cookies。
</Warning>

## 链路追踪（OpenTelemetry → Jaeger）

MCP Gateway 支持通过 OpenTelemetry 将链路追踪数据导出到 Jaeger。该功能可选，默认关闭。

### 功能概览

* 入站 HTTP 请求通过 Gin 中间件自动打点（排除 /health\_check）
* 下游 HTTP 调用自动透传 Trace 上下文
* 可选捕获下游请求的部分字段/Body 以及错误响应摘要，便于排障

### 配置示例

```yaml theme={null}
tracing:
  enabled: ${TRACING_ENABLED:false}
  service_name: "${TRACING_SERVICE_NAME:mcp-gateway}"
  endpoint: "${TRACING_ENDPOINT:localhost:4317}"   # Jaeger OTLP 采集端：gRPC(4317) 或 HTTP(4318)
  protocol: "${TRACING_PROTOCOL:grpc}"             # grpc 或 http
  insecure: ${TRACING_INSECURE:true}
  sampler_rate: ${TRACING_SAMPLER_RATE:0.1}         # 0.0 ~ 1.0
  environment: "${TRACING_ENV:dev}"
  headers: {}                                       # 可选导出器请求头
  capture:
    downstream_error:
      enabled: ${TRACING_ERR_BODY_ENABLED:false}
      max_body_length: ${TRACING_ERR_BODY_MAX_LEN:256}
    # 全局抓取设置 — 谨慎使用，避免泄露敏感信息。
    downstream_request:
      enabled: ${TRACING_REQ_ARGS_ENABLED:false}
      body_enabled: ${TRACING_REQ_BODY_ENABLED:false}
      body_max_length: ${TRACING_REQ_BODY_MAX_LEN:256}
      max_field_length: ${TRACING_REQ_ARG_MAX_LEN:256}
      include_fields: "${TRACING_INCLUDE_FIELDS:}"   # CSV 或 JSON Map: key=模板
```

### 环境变量

```bash theme={null}
# 启用追踪与服务标识
TRACING_ENABLED=true
TRACING_SERVICE_NAME=mcp-gateway
TRACING_ENV=dev

# 导出器配置（二选一协议）
TRACING_PROTOCOL=grpc
TRACING_ENDPOINT=localhost:4317   # gRPC（OTLP）
# 或者：
# TRACING_PROTOCOL=http
# TRACING_ENDPOINT=http://localhost:4318  # HTTP（OTLP）
TRACING_INSECURE=true
TRACING_SAMPLER_RATE=1.0          # 开发建议 1.0；生产请适当降低

# 可选捕获项（生产慎用）
TRACING_ERR_BODY_ENABLED=true
TRACING_ERR_BODY_MAX_LEN=256
TRACING_REQ_ARGS_ENABLED=false
TRACING_INCLUDE_FIELDS="username={{.Args.username}},email={{.Args.email}}"
TRACING_REQ_ARG_MAX_LEN=256
TRACING_REQ_BODY_ENABLED=false
TRACING_REQ_BODY_MAX_LEN=256
```

### 本地启动 Jaeger

* 可使用项目内提供的 Compose 文件：`deploy/docker/jaeger/docker-compose.yml`
* 启动命令：`docker compose -f deploy/docker/jaeger/docker-compose.yml up`
* Jaeger UI: [http://localhost:16686](http://localhost:16686)

### 示例截图

<img className="block dark:hidden" src="https://mintcdn.com/amoylabs/SHeJJzONcb6WPQ9d/images/trace.client.light.png?fit=max&auto=format&n=SHeJJzONcb6WPQ9d&q=85&s=6c29c43476a6e64c444aab99c64563b2" alt="客户端请求示例（浅色主题）" width="2610" height="1940" data-path="images/trace.client.light.png" />

<img className="hidden dark:block" src="https://mintcdn.com/amoylabs/SHeJJzONcb6WPQ9d/images/trace.client.dark.png?fit=max&auto=format&n=SHeJJzONcb6WPQ9d&q=85&s=c3bac0ce7bf7eb792453251c702c302b" alt="客户端请求示例（深色主题）" width="2610" height="1950" data-path="images/trace.client.dark.png" />

<img src="https://mintcdn.com/amoylabs/SHeJJzONcb6WPQ9d/images/trace.jaeger.png?fit=max&auto=format&n=SHeJJzONcb6WPQ9d&q=85&s=12c226c3b4029932c5d6dd62d6f7b449" alt="Jaeger UI —— Trace 结果展示" width="2622" height="1672" data-path="images/trace.jaeger.png" />

<Warning>
  开启字段或 Body 捕获可能会暴露敏感信息（令牌、密码、个人隐私）。建议默认关闭，在受控环境内以最小化采样与精确字段选择的方式使用。
</Warning>

## 配置文件位置

默认情况下，配置文件应放置在以下位置：

* 容器部署：`/app/configs/mcp-gateway.yaml`
* 二进制部署：`./configs/mcp-gateway.yaml`

## 热重载机制

MCP Gateway 支持热重载配置，无需重启服务即可应用新的配置：

<Steps>
  <Step title="配置更新检测">
    当配置发生变更时，通过配置的通知方式（signal、api、redis）触发重载
  </Step>

  <Step title="配置验证">
    重载前会验证新配置的合法性，确保服务稳定运行
  </Step>

  <Step title="平滑切换">
    验证通过后，平滑切换到新配置，不中断正在进行的连接
  </Step>
</Steps>

## 最佳实践

<AccordionGroup>
  <Accordion icon="gear" title="单机部署">
    * 存储类型建议使用 `db` 配合 SQLite
    * 通知类型使用 `composite` 或 `signal`
    * 会话存储可使用 `memory` 或 `redis`
  </Accordion>

  <Accordion icon="cubes" title="集群部署">
    * 存储类型使用 `db` 配合 PostgreSQL 或 MySQL
    * 通知类型使用 `redis` 或 `composite`
    * 会话存储建议使用 `redis`
  </Accordion>

  <Accordion icon="shield-check" title="生产环境">
    * 使用强密码保护 Redis 和数据库
    * 定期备份配置数据
    * 监控服务健康状态和性能指标
  </Accordion>
</AccordionGroup>
