Token导航 LogoToken导航TokenDH.com
timeserver (Patrickyoung) logo
AI代理stdio官方级别未说明来源级核验

timeserver (Patrickyoung)

MCP Server

一个简单的Go Web服务,提供通过REST API和MCP服务器接口获取当前服务器时间的功能。

工具数

7

提示词数

0

GitHub Stars

0

资源数

0
时间服务API集成GoClaudeClaude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

patrickyoung

提供方

patrickyoung

最后核验

2026/5/17 20:22

运行时

Docker

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

docker run -p 8080:8080 -e ALLOW_CORS_WILDCARD_DEV=true timeservice:v1.0.0

详细介绍

时间服务

一个简单的Go网络服务,通过HTTP提供标准REST API和模型上下文协议(MCP)服务器接口,以获取服务器当前时间。

特点/功能

  • REST API(Representational State Transfer Application Programming Interface,表述性状态传递应用程序编程接口)简单的端点以获取当前服务器时间
  • 命名位置基于SQLite的存储,用于自定义位置管理
  • MCP 服务器带有时间相关工具的模型上下文协议服务器
  • 身份验证与授权基于JWT声明的OAuth2/OIDC授权
  • 结构化日志记录使用 slog 的 JSON 格式日志
  • 优雅地关闭在终止信号时进行适当的清理
  • 中间件栈日志记录、恢复、认证和CORS支持
  • Prometheus 指标HTTP和MCP指标,包括认证和数据库指标
  • 最小化的Docker镜像多阶段构建生成小于10MB的镜像

快速入门

重要服务器需要CORS配置才能启动。对于本地开发,请使用 ALLOW_CORS_WILDCARD_DEV=true 环境变量。

本地运行

HTTP服务器模式(用于远程访问)

# Download dependencies
make deps

# Run the server (development mode with wildcard CORS)
ALLOW_CORS_WILDCARD_DEV=true make run

服务器将在8080端口(或指定的端口)上启动 PORT 环境变量)。

用于生产始终设置明确的允许来源:

ALLOWED_ORIGINS="https://example.com,https://app.example.com" make run

标准输入输出模式(适用于Claude Code/MCP客户端)

# Run in stdio mode for MCP communication
# Note: stdio mode doesn't require CORS configuration
go run cmd/server/main.go --stdio

此模式通过stdin/stdout使用JSON-RPC进行通信,这是Claude Code和其他本地MCP客户端所必需的。

构建二进制文件

make build

# Run with development CORS (local only)
ALLOW_CORS_WILDCARD_DEV=true ./bin/server

# Or with explicit origins (production)
ALLOWED_ORIGINS="https://example.com" ./bin/server

使用 Docker 运行

# Build image (creates both v1.0.0 and latest tags)
make docker

# Run with versioned tag (recommended)
docker run -p 8080:8080 -e ALLOW_CORS_WILDCARD_DEV=true timeservice:v1.0.0

# Or run with latest tag (local dev only)
docker run -p 8080:8080 -e ALLOW_CORS_WILDCARD_DEV=true timeservice:latest

制作说明: 始终使用带版本的标签(v1.0.0) 或图像摘要 (@sha256:...) 用于生产部署,以确保确定性、可重复的部署。该 latest 标签是可变的,仅应用于本地开发。

使用 Docker Compose 运行(加固版)

该项目包含一个经过加固的 docker-compose.yml 文件,遵循了安全最佳实践:

docker-compose up

此配置包括:

  • 只读根文件系统
  • 已移除的功能(全部)
  • 没有新的特权
  • 资源限制
  • 非root用户执行
  • 用于可写目录的Tmpfs

API终端点

1. 根端点

获取服务信息:

curl http://localhost:8080/

回复:

{
  "service": "timeservice",
  "version": "1.0.0",
  "endpoints": {
    "time": "GET /api/time",
    "locations": "GET /api/locations",
    "location_detail": "GET /api/locations/{name}",
    "location_time": "GET /api/locations/{name}/time",
    "mcp": "POST /mcp",
    "health": "GET /health"
  },
  "mcp_info": "Supports both stdio mode (--stdio flag) and HTTP transport (POST /mcp)"
}

2. 时间终点

获取当前服务器时间:

curl http://localhost:8080/api/time

回答:

{
  "current_time": "2025-10-17T15:30:45.123456Z",
  "unix_time": 1729180245,
  "timezone": "UTC",
  "formatted": "2025-10-17T15:30:45Z"
}

3. 健康终端(或健康终点)

检查服务状态:

curl http://localhost:8080/health

回答:

{
  "status": "healthy",
  "time": "2025-10-17T15:30:45Z"
}

MCP服务器端点

该服务包括一个模型上下文协议(MCP)服务器,为AI代理和其他客户端提供时间相关工具。

列出可用工具

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/list"
  }'

回答:

{
  "result": {
    "tools": [
      {
        "name": "get_current_time",
        "description": "Get the current server time in various formats",
        "inputSchema": {
          "type": "object",
          "properties": {
            "format": {
              "type": "string",
              "description": "Time format (iso8601, unix, rfc3339, or custom Go format)",
              "default": "iso8601"
            },
            "timezone": {
              "type": "string",
              "description": "IANA timezone (e.g., America/New_York, UTC)",
              "default": "UTC"
            }
          }
        }
      },
      {
        "name": "add_time_offset",
        "description": "Add a time offset to the current time",
        "inputSchema": {
          "type": "object",
          "properties": {
            "hours": {
              "type": "number",
              "description": "Hours to add (can be negative)",
              "default": 0
            },
            "minutes": {
              "type": "number",
              "description": "Minutes to add (can be negative)",
              "default": 0
            },
            "format": {
              "type": "string",
              "description": "Output format",
              "default": "iso8601"
            }
          }
        }
      }
    ]
  }
}

调用工具:获取当前时间

获取当前时间的ISO8601格式表示(UTC):

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "get_current_time",
      "arguments": {
        "format": "iso8601",
        "timezone": "UTC"
      }
    }
  }'

获取特定时区的当前时间:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "get_current_time",
      "arguments": {
        "format": "rfc3339",
        "timezone": "America/New_York"
      }
    }
  }'

获取当前的Unix时间戳:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "get_current_time",
      "arguments": {
        "format": "unix"
      }
    }
  }'

调用工具:添加时间偏移

在当前时间上加3小时:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "add_time_offset",
      "arguments": {
        "hours": 3,
        "minutes": 0,
        "format": "rfc3339"
      }
    }
  }'

从当前时间减去30分钟:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "add_time_offset",
      "arguments": {
        "hours": 0,
        "minutes": -30,
        "format": "iso8601"
      }
    }
  }'

命名位置管理

该服务提供基于数据库的存储功能,用于管理带有相关IANA时区的命名位置。这样,您可以自定义位置名称(如“总部”、“东京办公室”、“数据中心西区”),并查询这些位置的当前时间,而无需记住时区字符串。

位置存储

  • 数据库带有性能优化的 SQLite(WAL 模式,64MB 缓存)
  • 模式(或架构)不区分大小写的地点名称,IANA时区验证
  • 坚持不懈存储在(某处)的数据 data/timeservice.db (可通过 DB_PATH)
  • 自动迁移模式在启动时自动创建和更新

位置API终端点

创建一个位置

创建一个新命名的位置(需要 locations:write (当启用认证时,需要权限):

curl -X POST http://localhost:8080/api/locations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "name": "headquarters",
    "timezone": "America/New_York",
    "description": "Company HQ in NYC"
  }'

回应:

{
  "id": 1,
  "name": "headquarters",
  "timezone": "America/New_York",
  "description": "Company HQ in NYC",
  "created_at": "2025-10-19T10:00:00Z",
  "updated_at": "2025-10-19T10:00:00Z"
}

列出所有位置

获取所有已配置的位置:

curl http://localhost:8080/api/locations

回答:

{
  "locations": [
    {
      "id": 1,
      "name": "headquarters",
      "timezone": "America/New_York",
      "description": "Company HQ in NYC",
      "created_at": "2025-10-19T10:00:00Z",
      "updated_at": "2025-10-19T10:00:00Z"
    },
    {
      "id": 2,
      "name": "tokyo-office",
      "timezone": "Asia/Tokyo",
      "description": "Tokyo branch office",
      "created_at": "2025-10-19T10:05:00Z",
      "updated_at": "2025-10-19T10:05:00Z"
    }
  ]
}

获取特定位置

检索指定位置的详细信息:

curl http://localhost:8080/api/locations/headquarters

回答:

{
  "id": 1,
  "name": "headquarters",
  "timezone": "America/New_York",
  "description": "Company HQ in NYC",
  "created_at": "2025-10-19T10:00:00Z",
  "updated_at": "2025-10-19T10:00:00Z"
}

获取某个地点的当前时间

获取指定地点的当前时间:

curl http://localhost:8080/api/locations/headquarters/time

回答:

{
  "location": "headquarters",
  "timezone": "America/New_York",
  "current_time": "2025-10-19T06:30:45.123456-04:00",
  "unix_time": 1729180245,
  "formatted": "2025-10-19T06:30:45-04:00"
}

更新位置

更新现有位置的时区或描述(需要 locations:write (权限):

curl -X PUT http://localhost:8080/api/locations/headquarters \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "timezone": "America/Los_Angeles",
    "description": "Company HQ relocated to LA"
  }'

删除一个位置

移除一个已命名的位置(需要 locations:write (权限):

curl -X DELETE http://localhost:8080/api/locations/headquarters \
  -H "Authorization: Bearer $TOKEN"

回复:

{
  "message": "location deleted successfully"
}

租赁MCP工具

MCP服务器提供了通过AI代理和其他MCP客户端来管理位置的工具。

添加位置工具

添加一个新命名位置:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "add_location",
      "arguments": {
        "name": "london-office",
        "timezone": "Europe/London",
        "description": "London branch office"
      }
    }
  }'

列出位置工具

列出所有已配置的位置:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "list_locations",
      "arguments": {}
    }
  }'

获取位置时间工具

获取指定地点的当前时间:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "get_location_time",
      "arguments": {
        "name": "london-office",
        "format": "rfc3339"
      }
    }
  }'

更新位置工具

更新现有位置:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "update_location",
      "arguments": {
        "name": "london-office",
        "timezone": "Europe/Paris",
        "description": "Relocated to Paris"
      }
    }
  }'

移除位置工具

删除一个命名位置:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "remove_location",
      "arguments": {
        "name": "london-office"
      }
    }
  }'

位置数据库配置

配置SQLite数据库的位置和性能设置:

变量默认值描述
DB_PATHdata/timeservice.dbSQLite数据库文件的路径
DB_MAX_OPEN_CONNS25最大打开数据库连接数
DB_MAX_IDLE_CONNS5连接池中的最大空闲连接数
DB_CACHE_SIZE_KB64000缓存大小(以KB为单位,内部转换为页面)
DB_WAL_MODEtrue启用预写日志以提高并发性

自定义数据库路径的示例:

DB_PATH=/var/lib/timeservice/locations.db \
ALLOWED_ORIGINS="https://example.com" \
./bin/server

性能调优:

# For high-traffic workloads
DB_MAX_OPEN_CONNS=50 \
DB_CACHE_SIZE_KB=128000 \
./bin/server

# For low-memory environments
DB_MAX_OPEN_CONNS=10 \
DB_CACHE_SIZE_KB=32000 \
./bin/server

数据库备份与恢复

该服务包含一个用于创建数据库一致性备份的备份脚本:

创建备份:

# Basic usage
./scripts/backup-db.sh data/timeservice.db backups/

# With custom retention (days)
RETENTION_DAYS=30 ./scripts/backup-db.sh data/timeservice.db backups/

该脚本使用了SQLite的 VACUUM INTO 命令用于创建优化且一致的备份,并自动删除超过保留期限(默认:7天)的备份。

从备份中恢复:

# Stop the service
docker-compose down

# Replace database with backup
cp backups/timeservice_20251020_094227.db data/timeservice.db

# Restart service
docker-compose up -d

Docker Compose 备份:

# Backup volume data
docker run --rm -v time-server_timeservice-data:/data -v $(pwd)/backups:/backup alpine \
  tar czf /backup/timeservice-data-$(date +%Y%m%d).tar.gz -C /data .

# Restore volume data
docker run --rm -v time-server_timeservice-data:/data -v $(pwd)/backups:/backup alpine \
  tar xzf /backup/timeservice-data-YYYYMMDD.tar.gz -C /data

Kubernetes 备份:

# Copy database from pod
kubectl cp timeservice-0:/app/data/timeservice.db ./timeservice-backup.db

# Restore to pod
kubectl cp ./timeservice-backup.db timeservice-0:/app/data/timeservice.db
kubectl rollout restart statefulset timeservice

关于在 Kubernetes 中进行自动化备份,请参阅 k8s/README.md 用于CronJob示例。

位置使用场景

团队协作:

# Add team member locations
curl -X POST .../api/locations -d '{"name":"alice-home","timezone":"America/New_York",...}'
curl -X POST .../api/locations -d '{"name":"bob-home","timezone":"Europe/London",...}'

# Check what time it is for Alice
curl .../api/locations/alice-home/time

多区域基础设施:

# Define datacenter locations
curl -X POST .../api/locations -d '{"name":"us-east-dc","timezone":"America/New_York",...}'
curl -X POST .../api/locations -d '{"name":"eu-west-dc","timezone":"Europe/Dublin",...}'
curl -X POST .../api/locations -d '{"name":"ap-south-dc","timezone":"Asia/Singapore",...}'

# Check maintenance window times
curl .../api/locations/us-east-dc/time

国际商务时间:

# Store office locations
curl -X POST .../api/locations -d '{"name":"corporate","timezone":"America/Chicago",...}'
curl -X POST .../api/locations -d '{"name":"apac-support","timezone":"Asia/Tokyo",...}'

# Quickly check if offices are open
for loc in corporate apac-support; do
  echo "$loc: $(curl -s .../api/locations/$loc/time | jq -r .formatted)"
done

配置

该服务可以通过环境变量进行配置。所有配置在启动时都会进行验证,如果提供了无效值,服务器将无法启动。

服务器配置

变量默认值描述有效值
(无对应中文翻译)(无对应中文翻译)(无对应中文翻译)(无对应中文翻译)PORT80801-65535HTTP服务器端口
HOST

| (所有接口)| 绑定地址 | 任何有效的IP地址或主机名 |

日志配置 | 变量 | 默认值 | 描述 | 有效值 | |----------|---------|-------------|--------------| LOG_LEVEL | 中文翻译 | 中文 | 中文 | 中文 | info | debug| info| 日志级别 | warnwarningerror

|CORS 配置

安全关键(或:至关重要的安全) 服务器启动需要CORS配置。 | 变量 | 默认值 | 描述 | 有效值 | ALLOWED_ORIGINS |----------|---------|-------------|--------------| | 中文翻译 | 中文 | 中文 | 中文 | | https://example.com,https://app.example.com | 必需的 ALLOW_CORS_WILDCARD_DEV | 允许的CORS来源(逗号分隔) | 显式来源如 true | * |

| (无) | 仅开发者使用的逃生口,允许使用通配符CORS |使能够;启用

  • 原点(仅限开发使用)|安全注意事项
  • ALLOWED_ORIGINS 是必需的
  • 如果未设置 ALLOWED_ORIGINS,服务器将无法启动,从而防止在生产环境中意外启用通配符 CORS。无通配符默认值 ALLOWED_ORIGINS="https://example.com,https://app.example.com"没有默认值。您必须明确配置允许的来源。
  • 生产总是使用明确的来源(例如。, ALLOW_CORS_WILDCARD_DEV=true )。*仅限开发
  • 使用启用通配符CORS(*) 用于本地开发。这是一种有意识的选择加入机制,可防止意外暴露生产环境。

为什么这很重要

ALLOWED_ORIGINS="https://example.com,https://app.example.com" ./bin/server

通配符 CORS(

ALLOW_CORS_WILDCARD_DEV=true ./bin/server

) 允许任何网站向您的API发送经过身份验证的请求,这可能会导致cookie、会话令牌和用户数据被盗。这是一个严重的安全漏洞。

$ ./bin/server
Configuration error: invalid configuration: ALLOWED_ORIGINS is required. Set explicit origins (e.g., ALLOWED_ORIGINS="https://example.com") or use ALLOW_CORS_WILDCARD_DEV=true for development ONLY. Wildcard CORS (*) is a security vulnerability in production

示例 - 生产(正确):

示例 - 开发(谨慎使用): 10s未进行配置时会发生什么: 1m超时配置 500ms所有超时值均使用Go语言的持续时间格式(例如。,

, , )。 READ_TIMEOUT | 变量 | 默认值 | 描述 | 有效值 | 10s |----------|---------|-------------|--------------| | 中文翻译 | 中文 | 中文 | 中文 | WRITE_TIMEOUT | 10s | | 读取请求的最大持续时间 | 正数持续时间 | IDLE_TIMEOUT | 60s | | 写入响应的最大持续时间 | 正持续时间 | READ_HEADER_TIMEOUT | 5s | | 请求之间的最大空闲时间 | 正数时长 | SHUTDOWN_TIMEOUT | 10s |

| 读取请求头的最大持续时间 | 正数持续时间 |

| | | 优雅关闭的最大持续时间 | 正数持续时间 | MAX_HEADER_BYTES 资源限制 1048576 | 变量 | 默认值 | 描述 | 有效值 | 1-10485760 |----------|---------|-------------|--------------|

|

|(1MB) | 请求头的最大大小 | (1 字节 - 10MB) | 认证与授权配置 安全 该服务支持使用基于JWT的声明(角色、权限、范围)进行OAuth2/OIDC身份验证及授权。身份验证是

选择加入(或主动订阅) 为了向后兼容,但 强烈推荐 AUTH_ENABLED 用于生产。 false | 变量 | 默认值 | 描述 | 有效值 | true |----------|---------|-------------|--------------| false | | OIDC_ISSUER_URL | 启用认证(选择加入) | 或者 | https://auth.example.com | https://login.microsoftonline.com/{tenant-id}/v2.0| 如果启用认证,则为必填项 OIDC_AUDIENCE | OIDC 提供商 URL | 有效的 HTTPS URL(例如。, 或者 ) | timeservice | api://timeservice| 如果启用了认证,则必需 AUTH_PUBLIC_PATHS | JWT中的预期受众声明 | 您的服务标识符(例如。, /health,/,/metrics 或者 /health,/,/metrics) | | AUTH_REQUIRED_ROLE | time-reader| 逗号分隔的公共路径列表(无需认证) | 路径模式(例如。, )| AUTH_REQUIRED_PERMISSION | time:read| (无) | 所有受保护端点所需的角色 | 角色名称(例如。, ) | AUTH_REQUIRED_SCOPE | time:read| (无) | 所有受保护端点所需的权限 | 权限字符串(例如。, )| OIDC_SKIP_EXPIRY_CHECK | false | (无) | 所有受保护端点所需的OAuth2范围 | 范围字符串(例如。, ) || true | | OIDC_SKIP_CLIENT_ID_CHECK 危险 false 跳过令牌过期检查 | (仅开发者)|| true | | OIDC_SKIP_ISSUER_CHECK 危险 false 跳过观众验证 (仅开发者)|| true | | ALLOW_HTTP_OIDC_DEV 危险 true 跳过发行者验证 |

(仅开发者可见)||

  • | (无) | 允许用于开发的HTTP(不安全)OIDC发行者 |(仅限开发者)| AUTH_ENABLED=true
  • 安全注意事项
  • 生产建议在生产环境中始终启用身份验证,使用
  • 与提供商无关的与任何符合OIDC标准的提供商(如Auth0、Okta、Azure Entra ID、Keycloak、AWS Cognito、Google等)兼容工作
  • 基于声明的授权使用JWT声明(角色、权限、范围)实现细粒度访问控制 ALLOW_HTTP_OIDC_DEV=true 无状态的

无需数据库查询;所有授权数据都在JWT中需要HTTPS

  • /health OIDC 发行者在生产环境中必须使用 HTTPS(设置
  • / (仅用于本地测试)
  • /metrics 公共路径解析

\- 用于容器健康检查和负载均衡器探测 - 提供服务发现信息(哪些端点存在) - Prometheus 抓取所需(监控工具通常不使用身份验证令牌)

  • 关键:CORS 和认证中间件的顺序 当启用身份验证时,服务器
  • 需要适当的中间件排序 Authorization 与浏览器客户端正确配合工作:
  • CORS 中间件必须放在 Auth 中间件之前
  • 在链条中

浏览器CORS预检请求(OPTIONS)不包含 cmd/server/main.go头球 如果在CORS之前运行Auth,预检请求会因缺少CORS头部而收到401错误 这会导致浏览器阻止对API的所有请求,使其无法使用

服务器已正确配置为CORS→Auth顺序。如果您修改了中间件链中的

保持这个顺序

AUTH_ENABLED=true \
OIDC_ISSUER_URL="https://keycloak.example.com/realms/myrealm" \
OIDC_AUDIENCE="timeservice" \
AUTH_PUBLIC_PATHS="/health,/" \
AUTH_REQUIRED_ROLE="time-reader" \
ALLOWED_ORIGINS="https://app.example.com" \
./bin/server

或者浏览器客户端将会出现故障。

AUTH_ENABLED=true \
OIDC_ISSUER_URL="https://your-tenant.auth0.com/" \
OIDC_AUDIENCE="https://timeservice.example.com" \
AUTH_PUBLIC_PATHS="/health,/,/metrics" \
AUTH_REQUIRED_SCOPE="time:read" \
ALLOWED_ORIGINS="https://app.example.com" \
./bin/server

如需详细解释,请参阅

AUTH_ENABLED=true \
OIDC_ISSUER_URL="https://login.microsoftonline.com/{tenant-id}/v2.0" \
OIDC_AUDIENCE="api://timeservice" \
AUTH_PUBLIC_PATHS="/health,/" \
AUTH_REQUIRED_ROLE="time-reader" \
ALLOWED_ORIGINS="https://app.example.com" \
./bin/server

在DESIGN.md中的中间件排序要求

AUTH_ENABLED=true \
OIDC_ISSUER_URL="http://localhost:8080/realms/test" \
OIDC_AUDIENCE="timeservice" \
ALLOW_HTTP_OIDC_DEV=true \
ALLOW_CORS_WILDCARD_DEV=true \
./bin/server

示例 - 使用 Keycloak 的生产环境:

# Obtain JWT token from your OIDC provider first
TOKEN="eyJhbGc..."

# Make authenticated request
curl http://localhost:8080/api/time \
  -H "Authorization: Bearer $TOKEN"

示例 - 使用 Auth0 的生产环境:

$ ./bin/server
{"level":"INFO","msg":"authentication disabled - all endpoints are unprotected","recommendation":"enable auth in production with AUTH_ENABLED=true"}

示例 - 使用 Azure Entra ID 进行生产

$ AUTH_ENABLED=true ./bin/server
Configuration error: invalid configuration: OIDC_ISSUER_URL is required when AUTH_ENABLED=true

示例 - 开发(本地OIDC用于测试): 认证API请求示例: 当认证被禁用时(默认状态)会发生什么: 当启用认证但未配置必要设置时会发生什么:如需详细的认证设置说明、提供商示例以及安全最佳实践,请参阅

docs/SECURITY.md 翻译为中文是:docs/安全指南.md(或根据具体语境,也可译为“docs/安全文档.md”)

并且

PORT=8080 \
LOG_LEVEL=info \
ALLOWED_ORIGINS="https://example.com,https://app.example.com" \
READ_TIMEOUT=15s \
WRITE_TIMEOUT=15s \
make run

ADR 0005

PORT=3000 \
LOG_LEVEL=debug \
ALLOW_CORS_WILDCARD_DEV=true \
make run

PORT=8080 \
ALLOWED_ORIGINS="https://api.example.com,https://app.example.com" \
READ_TIMEOUT=5s \
WRITE_TIMEOUT=5s \
IDLE_TIMEOUT=30s \
MAX_HEADER_BYTES=524288 \
make run

配置示例

environment:
  - PORT=8080
  - LOG_LEVEL=info
  - ALLOWED_ORIGINS=https://example.com,https://app.example.com
  - READ_TIMEOUT=15s
  - WRITE_TIMEOUT=15s

基本生产配置:

带调试日志记录的开发配置:

# Missing ALLOWED_ORIGINS example
$ ./bin/server
Configuration error: invalid configuration: ALLOWED_ORIGINS is required. Set explicit origins (e.g., ALLOWED_ORIGINS="https://example.com") or use ALLOW_CORS_WILDCARD_DEV=true for development ONLY. Wildcard CORS (*) is a security vulnerability in production

# Invalid port example
$ PORT=999999 ALLOWED_ORIGINS="https://example.com" ./bin/server
Configuration error: invalid configuration: invalid PORT 999999: must be between 1 and 65535

# Invalid timeout example
$ READ_TIMEOUT=-5s ALLOWED_ORIGINS="https://example.com" ./bin/server
Configuration error: invalid configuration: READ_TIMEOUT must be positive, got -5s

高性能配置:

{
  "time": "2025-10-18T09:22:14Z",
  "level": "INFO",
  "msg": "configuration loaded",
  "port": "8080",
  "log_level": "INFO",
  "allowed_origins": ["https://example.com","https://app.example.com"],
  "read_timeout": 10000000000,
  "write_timeout": 10000000000,
  "idle_timeout": 60000000000
}

Docker Compose 配置: ALLOW_CORS_WILDCARD_DEV=true配置验证

{
  "time": "2025-10-18T09:22:14Z",
  "level": "WARN",
  "msg": "wildcard CORS (*) is enabled - this is INSECURE for production",
  "recommendation": "set explicit origins in ALLOWED_ORIGINS",
  "dev_only": "use ALLOW_CORS_WILDCARD_DEV=true only in development"
}

服务器在启动时验证所有配置,如果发现任何值无效,则会显示错误信息并退出:

在启动时(INFO 级别)会记录配置值,以便调试部署问题:

timeservice/
├── cmd/                 # Command-line applications
│   ├── server/          # Main server application
│   │   └── main.go
│   └── healthcheck/     # Healthcheck utility
│       └── main.go
├── internal/            # Private application code
│   ├── handler/         # HTTP handlers
│   ├── mcpserver/       # MCP server implementation (using mcp-go SDK)
│   ├── middleware/      # HTTP middleware (CORS, logging, metrics, recovery)
│   └── testutil/        # Testing utilities
├── pkg/                 # Public packages
│   ├── config/          # Configuration management
│   ├── metrics/         # Prometheus metrics
│   ├── model/           # Data models
│   └── version/         # Version information
├── k8s/                 # Kubernetes deployment manifests
│   ├── deployment.yaml  # K8s deployment with ServiceMonitor
│   └── prometheus.yml   # Sample Prometheus configuration
├── docs/                # Documentation
│   └── TESTING.md       # Testing guide
├── bin/                 # Compiled binaries (gitignored)
│   ├── server           # Main server binary
│   └── healthcheck      # Healthcheck binary
├── run-mcp.sh           # Helper script to run in stdio mode
├── Makefile             # Build commands
├── Dockerfile           # Multi-stage container image
├── docker-compose.yml   # Docker Compose configuration
└── README.md

如果检测到通配符CORS(通过

make help     # Show available commands
make build    # Build binary
make run      # Run server
make test     # Run tests
make fmt      # Format code
make lint     # Lint code
make clean    # Remove build artifacts
make deps     # Download dependencies
make docker   # Build Docker image

), 将记录一条警告:

发展

项目结构

可用的Make命令 .git/hooks/pre-commit 预提交钩子(或:提交前钩子)

  • 该项目包含了预提交钩子,用于强制执行代码质量标准,并防止提交二进制文件或覆盖率文件。.exe传统的 Git 钩子 .dll一个预提交钩子(pre-commit hook)会自动安装在 .so阻止提交: .dylib二进制文件(
  • bin/
  • .test
  • 在(指定位置)构建工件.out目录 .coverprofile测试二进制文件(

)

  1. 覆盖文件(

该钩子(hook)会在每次提交时自动运行。如果它检测到被禁止的文件,它将:

阻止提交 显示匹配到禁止模式的文件提供解决问题的说明 .pre-commit-config.yaml 现代预提交框架(可选)

对于使用该(工具/系统/服务)的团队来说

# Install pre-commit (if not already installed)
pip install pre-commit

# Install the git hooks
pre-commit install

# Run hooks manually on all files
pre-commit run --all-files

预提交框架

  • 提供了额外的检查:
  • 设置:
  • 包含的支票:go fmt文件大小限制(最大500KB)
  • 合并冲突检测go vetYAML语法验证
  • Go 语言格式化(
  • 进行背景调查(或审查)
  • Go 导入组织(或“Go 导入包组织”)

Go mod tidy(Go模块整理)

进行构建验证 .gitignore 运行Go测试

  • 二进制文件和覆盖率文件的防护bin/.gitignore(Git忽略文件) *.exe这个(或“该”)
  • 文件防止意外添加:*.test构建产物(
  • *.outcoverage.html测试二进制文件(
  • .idea/覆盖率文件( .vscode/
  • ).env*IDE 文件(
  • .DS_Store)
  • 环境文件(tmp/) *.tmp操作系统文件(

)

临时文件(

  • )所有开发人员应确保其本地构建过程遵循这些忽略规则。
  • 建筑这项服务遵循了Go语言中惯用的网络服务模式: log/slog 关注点分离(或译为:职责分离)
  • 处理程序 → 服务 → 存储层(此例中简化)结构化日志记录
  • 使用用于结构化、JSON格式的日志
  • 中间件链用于处理横切关注点的可组合中间件
  • 优雅关闭在接收到SIGINT/SIGTERM信号时进行适当的清理

上下文传播

请求上下文贯穿所有层级

最小化依赖主要依赖于Go标准库 ~/.config/Claude/claude_desktop_config.json 与Claude Desktop一起使用要在Claude Desktop中使用此MCP服务器,请将以下配置添加到您的Claude Desktop MCP设置文件中: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "timeservice": {
      "command": "/full/path/to/time-server/bin/server",
      "args": ["--stdio"],
      "description": "Time service providing current time and time offset calculations"
    }
  }
}

macOS/Linux(操作系统) /full/path/to/time-server :

Windows

  1. make build
  2. 替换
  3. 使用此项目目录的实际绝对路径。

添加配置后:

构建服务器:

重启Claude桌面版

  • get_current_time 时区服务工具将对克劳德(Claude)可用

- 你可以通过询问克劳德来验证它是否正常工作:“现在东京是什么时间?” format 可用的MCP工具 timezone 时间工具:

  • add_time_offset - 获取当前服务器时间,支持多种格式和时区

- 参数: hours (iso8601, unix, unixmilli, rfc3339), minutes (IANA时区名称) format - 为当前时间添加小时/分钟偏移量

参数:

  • add_location (数字),

- (数字), name (输出格式) timezone 位置管理工具: description - 添加一个带有时区的命名位置

  • list_locations 参数:

- (字符串),

  • get_location_time (IANA时区),

- (字符串,可选) name - 列出所有已配置的位置 format 参数:无

  • update_location - 获取指定地点的当前时间

- 参数: name (字符串), timezone (输出格式,可选) description - 更新现有位置

  • remove_location 参数:

- (字符串), name (IANA时区,可选),

(字符串,可选)

\- 删除指定位置 参数: (字符串)

  • MCP协议 模型上下文协议(MCP)是一种允许人工智能模型与工具和资源进行交互的协议。此服务通过(某种技术或框架)实现了一个MCP服务器
  • mcp-go SDK 翻译为中文是:“mcp-go 软件开发工具包(SDK)” 以两种模式:

标准输入输出模式(Stdio mode)

  • tools/list(适用于Claude Desktop和本地MCP客户端):通过stdin/stdout的JSON-RPC
  • tools/callHTTP模式

(用于远程访问):使用StreamableHTTPServer通过HTTP POST进行JSON-RPC通信

MCP 方法

{
  "result": { ... }
}

列出所有可用的工具

{
  "error": {
    "code": 400,
    "message": "error description"
  }
}

调用具有参数的特定工具

MCP响应格式

make test

成功响应:

make test-race

错误响应:

make test-coverage

测试

make test-coverage-html
# Open coverage.html in your browser

运行测试套件:

使用竞态检测器运行测试:

生成覆盖率报告:

生成HTML覆盖率报告:.github/workflows/ci.yml持续集成/持续交付流水线(CI/CD Pipeline)

这个项目包含一个使用GitHub Actions构建的全面CI/CD(持续集成/持续交付)流水线,该流水线在每次推送和拉取请求时都会运行。

  • GitHub Actions 工作流CI流水线(
  • 包括:测试任务 go fmt
  • 多版本测试针对 Go 1.22、1.23 和 1.24 的测试 go vet 代码格式化
  • 确保代码格式化为静态分析
  • 运行捕捉常见错误
  • 单元测试执行所有测试,并输出详细信息
  • 竞态条件检测启用竞态检测器运行测试

覆盖率报告

  • 生成并上传覆盖率报告Codecov 集成
  • 可选地上传到Codecov以跟踪随时间变化的覆盖率“Lint Job”可以翻译为“代码检查任务”或“静态代码分析任务”,具体取决于上下文和所使用的工具或方法。在这里,“Lint”通常指的是对代码进行静态检查的过程,用于发现潜在的错误、不符合编码规范的地方等,而“Job”则指的是这项任务或工作。因此,“Lint Job”可以理解为对代码进行静态检查的工作或任务
  • golangci-lint(中文可译为“Go语言代码检查工具”或保持原名,因其是一个专有名词)运行带有多个静态代码分析工具的全面代码检查

超时

  • 5分钟的代码静态检查超时并行执行
  • 与测试并行运行构建任务
  • 二进制编译构建服务器二进制文件

工件上传

  • 将二进制文件上传为 GitHub 艺术品(保留7天)尺寸报告
  • 报告二进制文件大小Docker 作业
  • 镜像构建使用 BuildKit 构建 Docker 镜像
  • 缓存优化使用GitHub Actions缓存以加快构建速度

图像测试

  • 验证构建的镜像尺寸报告
  • 报告最终图像尺寸保安工作
  • Gosec 扫描器注重安全的Go语言检查工具

Trivy 扫描器

依赖项和代码漏洞扫描器

make ci-local

SARIF 上传

  1. make deps 将安全发现结果上传到GitHub的安全选项卡
  2. make fmt 本地CI(持续集成)模拟
  3. make vet 在推送之前,先在本地运行所有CI检查:
  4. make lint 这运行着:
  5. make test-race - 下载并验证依赖项
  6. make test-coverage - 格式代码

- 运行 go vet

\- 运行 golangci-lint.golangci.yml- 使用竞态检测器运行测试

  • - 生成覆盖率报告代码检查配置
  • 该项目使用了golangci-lint,并采用了全面的配置()其中包括:
  • 错误检查errcheck,gosec
  • 代码质量gosimple,staticcheck,unused
  • 风格gofmt,goimports,revive
  • 演出带有性能检查的gocritic

安全

# Linux/macOS
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

# Or using Go
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

带有安全检查功能的gosec

make lint

最佳实践

bodyclose(关闭体),nilerr(空错误),unconvert(无法转换)

  • 安装 golangci-lint:
  • 在本地运行代码检查:
  • 覆盖率工件(或覆盖率相关制品)
  • 覆盖率报告会自动:

为每个测试的Go版本生成

作为GitHub Actions工件上传(保留30天)

[![CI](https://github.com/yourorg/timeservice/workflows/CI/badge.svg)](https://github.com/yourorg/timeservice/actions)

可在“操作”选项卡中下载

可选择上传到Codecov以追踪趋势

CI徽章

  1. 在你的 README 文件中添加 CI 状态徽章(更新仓库 URL):

- 容器安全加固 golang:1.24-alpine Docker镜像已按照安全最佳实践进行了加固: alpine:3.20 - Dockerfile 安全特性

  1. 固定基础镜像

- 使用特定版本: - 并且 - 确保构建过程可重复,并防止供应链攻击

  1. 最小攻击面

- 多阶段构建将最终镜像大小减小至约16MB appuser 仅包含必要的运行时依赖(ca-certificates,tzdata) appgroup 最终镜像中不含shell或不必要的二进制文件 - 非管理员用户 - 创建专用用户

  1. (用户ID 10001) 和组

- (GID 10001) apk add --no-cache tzdata 所有进程默认以非root用户身份运行 - 非root用户拥有的应用程序文件 /usr/share/zoneinfo 时区数据 - 通过……安装

  1. 在构建器中

- -trimpath复制自 - -w -s而不是使用 Go 内置的 zoneinfo - -extldflags "-static"支持所有IANA时区,无需在二进制中嵌入 - go mod verify构建安全标志

  1. 从二进制文件中移除绝对路径

- 去除调试信息 - 生成静态二进制文件(无动态依赖)

确保依赖项未被篡改

健康检查 docker-compose.yml 内置的 Docker HEALTHCHECK 指令 k8s/deployment.yaml 验证容器是否正常工作

运行时安全(Docker/Kubernetes)

# Read-only root filesystem
read_only: true

# Drop all capabilities
cap_drop: - ALL

# Prevent privilege escalation
security_opt:
  - no-new-privileges:true

# Resource limits
deploy:
  resources:
    limits:
      cpus: '0.5'
      memory: 128M

所包含的

securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]
  seccompProfile:
    type: RuntimeDefault

并且

展示运行时加固:

  1. Docker Compose 功能: Kubernetes 安全上下文:

- 容器镜像扫描 - CI流水线包含三个扫描工具: - Trivy

  1. (Aqua Security) 可以翻译为“(Aqua 安全)”。不过,通常在中文语境中,我们可能会更直接地翻译为“(Aqua 安全公司)”或者根据具体上下文调整为更贴切的表述,但基本保留了原名中的“Aqua”和“Security”两部分。如果“Aqua Security”是一个特定公司或产品的名称,那么直接保留原名也是可以的,只是可能需要在上下文中稍作解释或说明 扫描操作系统和应用程序漏洞

- 检查配置错误 - 结果已上传至GitHub安全选项卡 - Grype(可能指某种疾病或病毒的名称,具体需根据上下文确定,此处直译为“格雷普”)

  1. (Anchore)

- 多源漏洞数据库 - 从不同来源捕获CVE(可利用漏洞) - 用于GitHub集成的SARIF格式

Docker Scout(可译为“Docker侦察兵”或根据具体语境简化为“Docker侦察工具”)

  • 官方Docker漏洞扫描器
  • 与Docker Hub的CVE数据库集成
  • 提供补救建议

所有扫描结果均可在以下位置查看:

GitHub Actions 工作流日志

docker run -d \
  --name timeservice \
  --read-only \
  --cap-drop=ALL \
  --security-opt=no-new-privileges:true \
  --tmpfs /tmp:noexec,nosuid,size=10M \
  -p 8080:8080 \
  -e ALLOW_CORS_WILDCARD_DEV=true \
  timeservice:v1.0.0

GitHub 安全 → 代码扫描警报

docker-compose up -d

可下载的SARIF工件

# Build and tag image for production
docker build -t timeservice:v1.0.0 .

# Push to your container registry (update with your registry)
# docker tag timeservice:v1.0.0 your-registry.com/timeservice:v1.0.0
# docker push your-registry.com/timeservice:v1.0.0

# Deploy to Kubernetes
kubectl apply -f k8s/deployment.yaml

在全面安全模式下运行 Docker 运行: image: timeservice:v1.0.0 Docker Compose: k8s/deployment.yaml Kubernetes:(通常不直接翻译,保持原名,若需解释性翻译可为“Kubernetes:一个容器编排平台”)

注:

Kubernetes 部署使用

docker run --rm timeservice:v1.0.0 id
# Expected: uid=10001(appuser) gid=10001(appgroup)

用于确定性部署。更新

docker scout cves timeservice:v1.0.0
# Or
trivy image timeservice:v1.0.0

如果要部署到真实集群,请提供您的注册表URL和凭据。

安全验证

验证容器是否以非root用户身份运行:

检查镜像漏洞: /metrics Prometheus 可观测性

curl http://localhost:8080/metrics

此服务提供了Prometheus指标,以实现全面的可观测性和监控。

指标端点

这个(或“该”) 端点暴露了Prometheus格式的指标: 可用指标 timeservice_http_requests_total HTTP 指标 method| 指标 | 类型 | 标签 | 描述 | path|--------|------|--------|-------------| status | 项目 | 类型 | 数量 | 描述 | | timeservice_http_request_duration_seconds | 计数器 | methodpath , | HTTP请求的总数 | timeservice_http_request_size_bytes | method| 直方图 | path , | HTTP请求持续时间(秒) | timeservice_http_response_size_bytes | method| 直方图 | path , | HTTP请求大小(以字节为单位) | timeservice_http_requests_in_flight |

| 直方图 |

, | HTTP响应大小(以字节为单位) | | timeservice_mcp_tool_calls_total | 指标 | - | 当前正在处理的HTTP请求数 | toolMCP工具指标 status | 指标 | 类型 | 标签 | 描述 | |--------|------|--------|-------------| timeservice_mcp_tool_call_duration_seconds |(无) |(无)|(无) |(无) | tool | | 计数器 | timeservice_mcp_tool_calls_in_flight

| MCP工具调用的总次数 |

| | 直方图 | |MCP工具调用持续时间(秒)| timeservice_build_info | version| 指标 | - | 当前正在处理的MCP工具调用数量 | go_version 应用指标

| 指标 | 类型 | 标签 | 描述 |

|--------|------|--------|-------------|

  • go_goroutines |(无对应中文)|(无对应中文)|(无对应中文)|(无对应中文)|
  • go_memstats_* |
  • go_gc_* | 表盘/刻度盘 |
  • process_*

| 构建信息(始终为1) |

标准Go指标

该服务还公开了标准的Go运行时指标: docker-compose.yml - 协程(goroutine)的数量

labels:
  - "prometheus.scrape=true"
  - "prometheus.port=8080"
  - "prometheus.path=/metrics"

- 内存统计

\- 垃圾回收统计

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "8080"
  prometheus.io/path: "/metrics"

\- 进程统计信息(CPU、内存、文件描述符) ServiceMonitor Prometheus 配置

kubectl apply -f k8s/deployment.yaml

Docker Compose

这个(或:那个)k8s/prometheus.yml包含用于 Prometheus 服务发现的标签:

scrape_configs:
  - job_name: 'timeservice'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'
    scrape_interval: 30s

Kubernetes(通常简称为K8s)

Kubernetes 部署中包含了用于自动 Prometheus 抓取的 Pod 注解:

A.

rate(timeservice_http_requests_total[5m])

同时也为 Prometheus Operator 提供了资源:

histogram_quantile(0.95, rate(timeservice_http_request_duration_seconds_bucket[5m]))

独立部署的Prometheus

rate(timeservice_http_requests_total{status=~"5.."}[5m])
/ rate(timeservice_http_requests_total[5m])

示例Prometheus配置(

rate(timeservice_mcp_tool_calls_total{status="success"}[5m])
/ rate(timeservice_mcp_tool_calls_total[5m])

):

timeservice_http_requests_in_flight

Grafana 仪表板

  1. 示例查询
  2. 请求速率(请求/秒):
  3. 请求持续时间(p95):

- 错误率: - MCP工具成功率: - 飞行中请求:

创建仪表板

将指标端点导入到Grafana数据源中

使用上述查询创建面板

为以下设置提醒:

- alert: HighErrorRate
  expr: |
    rate(timeservice_http_requests_total{status=~"5.."}[5m])
    / rate(timeservice_http_requests_total[5m]) > 0.05
  for: 5m
  annotations:
    summary: "High error rate detected"
    description: "Error rate is {{ $value | humanizePercentage }}"

高错误率(> 5%)

- alert: HighLatency
  expr: |
    histogram_quantile(0.95,
      rate(timeservice_http_request_duration_seconds_bucket[5m])
    ) > 1.0
  for: 5m
  annotations:
    summary: "High latency detected"
    description: "P95 latency is {{ $value }}s"

高延迟(p95 > 1秒)

- alert: ServiceDown
  expr: up{job="timeservice"} == 0
  for: 1m
  annotations:
    summary: "Timeservice is down"
    description: "Service has been down for more than 1 minute"

服务宕机(未抓取指标)

监控最佳实践

groups:
  - name: timeservice
    interval: 30s
    rules:
      - record: timeservice:http_requests:rate5m
        expr: rate(timeservice_http_requests_total[5m])

      - record: timeservice:http_request_duration:p95
        expr: histogram_quantile(0.95, rate(timeservice_http_request_duration_seconds_bucket[5m]))

      - record: timeservice:http_error_rate:rate5m
        expr: |
          rate(timeservice_http_requests_total{status=~"5.."}[5m])
          / rate(timeservice_http_requests_total[5m])

警报

推荐提醒:

# Start server
ALLOWED_ORIGINS="*" ./bin/server

# Generate requests
for i in {1..100}; do
  curl -s http://localhost:8080/health > /dev/null
  curl -s http://localhost:8080/api/time > /dev/null
done

# View metrics
curl http://localhost:8080/metrics | grep timeservice

高错误率:

高延迟:

  1. 服务宕机:录制规则
  2. 预计算常见查询:测试指标
  3. 生成测试流量:指标架构
  4. 指标的实现遵循了Prometheus的最佳实践:自动仪器化 timeservice HTTP 中间件自动追踪所有请求
  5. 工具级追踪MCP工具调用被封装在指标收集之中

基数控制

标签经过精心选择,以防止指标爆炸(或指标数量激增) docs/ 命名空间

所有指标均使用

- - 详细的覆盖率分析和测试指标 SECURITY.md 翻译为中文是:“安全指南/声明文件”或“安全说明文件”。不过,具体翻译可能根据上下文有所调整,以更贴合文件的实际内容和用途。在这里,“SECURITY.md”通常是一个用于说明项目或软件安全方面的注意事项、漏洞报告流程、安全最佳实践等内容的Markdown格式文件

- 安全实践、认证和威胁模型

DEVSECOPS.md 翻译为中文是:“开发安全运维(DevSecOps).md” 或者更简洁地表述为:“DevSecOps 文档.md”。这里,“DEVSECOPS”代表“Development Security Operations”的缩写,意为开发安全运维,是一种将安全性融入到开发和运维流程中的实践方法。而“.md”是Markdown文件格式的扩展名 docs/adr/ - DevSecOps实践、安全控制和合规性

- 使用 slog 进行结构化日志记录

ADR 0005 docs/implementation-plans/ - OAuth2/OIDC 授权

ADR 0006

\- MCP HTTP传输实现

目录标签

目录标签

时间服务API集成GoClaude本地部署RESTAPIMCP协议SQLite数据库OAuth2认证

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

token

运行时(runtime,运行环境)

Docker

工具数量(toolCount,工具数)

7

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiotoken部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP