返回市场
社区-MCP训练营天气-MCP

社区-MCP训练营天气-MCP

作者:f11 星标更新:2025-10-18

项目介绍

使用 GitHub OAuth 和位置管理的 Weather MCP 服务器

本项目演示了一个高级的模型上下文协议(MCP)服务器,该服务器使用 GitHub OAuth 认证,个性化的位置管理,并通过 Open-Meteo 的免费 API 获取天气数据。

功能

  • 🔐 GitHub OAuth 2.0 认证:使用 GitHub 应用的安全认证
  • 📍 个人位置管理:保存并管理自定义位置标签(例如,“家”,“办公室”)
  • 🌤️ 智能天气查询:使用已保存的标签或直接位置名称检查天气
  • 💾 SQLite 数据库:持久存储用户及其位置信息
  • 🆓 免费天气 API:使用 Open-Meteo API —— 不需要 API 密钥!
  • 🔄 流式 HTTP 传输:现代 HTTP 传输与 MCP SDK
  • 🛠️ 多种工具:天气查询、位置管理(添加、列出、删除)、用户信息
  • 👤 用户资料:从 GitHub 资料数据自动创建用户,并获取资料

预备条件

  • Node.js(推荐 v18 或更高版本)
  • GitHub 账户
  • GitHub OAuth 应用(见下文说明)
  • OpenAI API 密钥(可选,用于客户端示例)

设置

1. 安装依赖项:

npm install

2. 创建 GitHub OAuth 应用:

  1. 前往 GitHub 开发者设置
  2. 点击 "新建 OAuth 应用"
  3. 填写应用详情:
    • 应用名称:Weather MCP 服务器(或您喜欢的名称)
    • 主页 URLhttp://localhost:3000
    • 授权回调 URLhttp://localhost:3000/oauth/callback
  4. 点击 "注册应用"
  5. 复制您的 客户端 ID
  6. 点击 "生成新的客户端密钥" 并复制它

3. 配置环境变量:

cp .env.example .env

编辑 .env 并添加您的 GitHub OAuth 凭据:

GITHUB_CLIENT_ID=your_github_client_id_here
GITHUB_CLIENT_SECRET=your_github_client_secret_here
GITHUB_REDIRECT_URI=http://localhost:3000/oauth/callback
PORT=3000

4. 启动 MCP 服务器:

node server.js

服务器将在 http://127.0.0.1:3000 上启动

5. 使用 GitHub 进行身份验证:

  1. 打开浏览器并访问:http://localhost:3000/oauth/login
  2. 点击 "授权" 以连接到 GitHub
  3. 复制成功页面上显示的 访问令牌
  4. 在 Authorization 标头中使用此令牌:Bearer <your-token>

6. 配置 Claude Desktop

在您的 Claude Desktop 配置文件中添加配置:

macOS~/Library/Application Support/Claude/claude_desktop_config.json

Windows%APPDATA%\Claude\claude_desktop_config.json

选项 A:自动 OAuth(推荐)

{
  "mcpServers": {
    "weather-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://127.0.0.1:3000/mcp"
      ]
    }
  }
}

Claude Desktop 将自动发现 OAuth 端点并打开浏览器进行身份验证。只需在提示时授权 GitHub!

选项 B:手动令牌

{
  "mcpServers": {
    "weather-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://127.0.0.1:3000/mcp",
        "--header",
        "Authorization: Bearer YOUR_GITHUB_ACCESS_TOKEN",
        "--no-auth"
      ]
    }
  }
}

首先通过访问 http://localhost:3000/oauth/login 获取您的令牌,然后将 YOUR_GITHUB_ACCESS_TOKEN 替换为您自己的令牌。

使用示例

一旦通过 Claude Desktop 连接,您可以:

基本天气查询

  • “旧金山的天气如何?”
  • “告诉我东京的当前天气”
  • “巴黎的天气怎么样?”

保存个人位置

  • “将我的家位置保存为纽约”
  • “添加我的办公室位置为旧金山”
  • “将健身房位置保存为波士顿主街123号”

使用已保存的标签查询

  • “家里的天气怎么样?”
  • “办公室的天气如何?”
  • “检查健身房的天气”

管理位置

  • “列出我保存的所有位置”
  • “显示我的位置”
  • “删除我家的位置”

用户资料

  • “我是谁?”
  • “显示我的资料”
  • “我的 GitHub 用户名是什么?”

工作原理

  1. OAuth 流程:用户通过 GitHub OAuth 2.0 进行身份验证
  2. 令牌交换:服务器将授权码交换为访问令牌
  3. 用户创建:服务器根据 GitHub 数据创建或更新用户资料
  4. 身份验证:客户端在 Authorization 标头中发送 Bearer 令牌
  5. 令牌验证:服务器将令牌与 SQLite 数据库进行验证
  6. 会话创建:服务器为用户上下文创建经过身份验证的会话
  7. 工具发现:客户端从服务器发现可用的 MCP 工具
  8. 工具执行
    • 天气查询将位置标签解析为实际地址
    • 位置管理按用户存储数据于数据库中
    • 所有操作都限于经过身份验证的用户
  9. 天气数据:服务器从 Open-Meteo API 获取实时天气
  10. 响应:结果返回给客户端,带有特定用户的上下文

架构

      用户浏览器
           │
           │ 1. 访问 /oauth/login
           ▼
    GitHub OAuth 服务器
           │
           │ 2. 授权
           ▼
      /oauth/callback
           │
           │ 3. 访问令牌
           ▼
┌─────────────────────────────────────────────┐
│        Claude Desktop / MCP 客户端          │
│  (带 Authorization: Bearer 令牌)            │
└─────────────────┬───────────────────────────┘
                  │ 流式 HTTP + 身份验证
                  ▼
┌─────────────────────────────────────────────┐
│           server.js (MCP 服务器)            │
│  ┌───────────────────────────────────────┐  │
│  │  OAuth 身份验证 (auth.js)             │  │
│  │           ↓                           │  │
│  │  令牌验证中间件                       │  │
│  │           ↓                           │  │
│  │  会话管理(每个用户)                 │  │
│  │           ↓                           │  │
│  │  MCP 工具:                           │  │
│  │  - get_current_weather                │  │
│  │  - add_location                       │  │
│  │  - list_locations                     │  │
│  │  - delete_location                    │  |
│  └───────────────────────────────────────┘  │
│                 ↓                           │
│  ┌───────────────────────────────────────┐  │
│  │     SQLite 数据库 (weather.db)        │  │
│  │  - 用户(含 GitHub 数据)             │  │
│  │  - 位置                               │  │
│  └───────────────────────────────────────┘  │
└─────────────────┬───────────────────────────┘
                  │
                  ▼
         Open-Meteo 天气 API

MCP 工具

1. get_current_weather

获取任何位置或已保存标签的实时天气数据。

  • 参数
    • location (字符串):位置名称或已保存标签(例如,“纽约”,“家”)
    • unit (枚举):温度单位 - "摄氏度" 或 "华氏度"(默认:摄氏度)
  • 返回值:温度、状况、湿度、风速、压力、云量
  • 特殊:自动解析已保存位置标签为地址

2. add_location

保存一个具有自定义标签的位置以便快速访问。

  • 参数
    • label (字符串):自定义标签(例如,“家”,“办公室”,“健身房”)
    • location (字符串):实际位置名称或地址
  • 返回值:确认消息
  • 注意:如果标签已存在,则替换现有标签

3. list_locations

显示经过身份验证的用户的所有已保存位置。

  • 参数:无
  • 返回值:所有已保存位置及其标签的列表

4. delete_location

通过标签删除已保存的位置。

  • 参数
    • label (字符串):要删除的位置标签
  • 返回值:确认或错误消息

5. get_user_info

获取当前登录用户的信息。

  • 参数:无
  • 返回值:用户资料,包括 GitHub 用户名、姓名、电子邮件、头像 URL 和用户 ID

项目结构

komunite-bootcamp-mcp/
├── server.js              # 带 OAuth 的 MCP HTTP 服务器
├── database.js            # SQLite 数据库操作
├── auth.js                # GitHub OAuth 身份验证
├── index.js               # OpenAI 函数调用示例(遗留)
├── .env.example           # 环境变量模板
├── .env                   # 您的环境变量(创建这个文件)
├── package.json           # 依赖项和脚本
├── weather.db             # SQLite 数据库(首次运行时创建)
└── README.md             # 本文档

数据库模式

用户表

CREATE TABLE users (
  id TEXT PRIMARY KEY,
  github_id TEXT UNIQUE,
  github_username TEXT,
  github_email TEXT,
  name TEXT,
  avatar_url TEXT,
  access_token TEXT,
  refresh_token TEXT,
  token_expires_at DATETIME,
  auth_token TEXT UNIQUE,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)

位置表

CREATE TABLE locations (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL,
  label TEXT NOT NULL,
  location_name TEXT NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  UNIQUE(user_id, label)
)

安全特性

  • GitHub OAuth 2.0:行业标准的 OAuth 身份验证流程
  • PKCE (RFC 7636):S256 证明密钥用于代码交换的公共客户端
  • 动态客户端注册 (RFC 7591):自动客户端注册
  • 状态参数:CSRF 保护与状态验证
  • Bearer 令牌身份验证:所有 MCP 端点都需要有效的身份验证
  • 令牌验证:访问令牌与数据库进行验证
  • 用户隔离:每个用户只能访问他们自己的位置
  • 会话管理:带有用户上下文的安全会话处理
  • 数据库约束:外键约束确保数据完整性
  • 自动令牌过期:跟踪令牌过期时间以增强安全性

自定义

添加自定义 MCP 工具

  1. 打开 server.js
  2. 在现有工具之后注册新工具:
sessionServer.tool(
  'your_tool_name',
  '工具描述',
  {
    param1: z.string().describe('参数描述'),
  },
  async ({ param1 }) => {
    const userId = sessionUsers[transport.sessionId]?.id;
    // 您的工具逻辑在这里
    return {
      content: [{ type: 'text', text: '结果' }],
    };
  }
);
  1. 客户端将自动发现该工具

API 端点

OAuth 发现端点 (RFC 8414 & RFC 9728)

  • GET /.well-known/oauth-authorization-server - OAuth 2.0 授权服务器元数据
  • GET /.well-known/oauth-protected-resource - OAuth 2.0 受保护资源元数据

OAuth 端点 (符合标准)

  • POST /oauth/register - 动态客户端注册 (RFC 7591)
  • GET /oauth/authorize - OAuth 2.0 授权端点
  • POST /oauth/token - OAuth 2.0 令牌端点
  • POST /oauth/revoke - OAuth 2.0 令牌撤销 (RFC 7009)
  • GET /oauth/login - 手动 OAuth 流程(基于浏览器)
  • GET /oauth/callback - OAuth 回调处理器
  • GET /oauth/me - 返回当前用户信息(需要身份验证)

MCP 端点

  • POST /mcp - 主 MCP 端点用于工具调用
  • GET /mcp - 通知的 Server-Sent Events
  • DELETE /mcp - 会话终止

实用端点

  • GET /health - 健康检查端点

注意事项

  • 基于 模型上下文协议 (MCP) 规范
  • 使用 @modelcontextprotocol/sdk 实现 MCP 服务器
  • 流式 HTTP 传输:带有会话管理的现代 HTTP 传输
  • SQLite 数据库:轻量级、基于文件的数据库,使用 better-sqlite3
  • GitHub OAuth 2.0:通过 GitHub 应用的安全认证
  • 使用 Open-Meteo API —— 免费且开源的天气 API
  • 获取天气数据不需要 API 密钥!
  • 按用户管理位置,数据库隔离
  • 自动解析标签以方便天气查询
  • 用户资料自动从 GitHub 数据创建

登出 / 撤销访问

当使用 Claude Desktop 登出 OAuth 时:

选项 1:清除 mcp-remote 缓存

rm -rf ~/.cache/mcp-remote/auth/

选项 2:手动令牌撤销

curl -X POST http://localhost:3000/oauth/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=YOUR_ACCESS_TOKEN"

然后清除缓存并重新启动 Claude Desktop。

故障排除

令牌过期

如果您遇到身份验证错误,您的 GitHub 令牌可能已过期:

  1. 再次访问 http://localhost:3000/oauth/login
  2. 获取新的访问令牌
  3. 使用新的令牌更新您的 Claude Desktop 配置

使用 cURL 测试

您可以直接使用 cURL 测试 API:

# 检查 OAuth 服务器元数据:
curl http://localhost:3000/.well-known/oauth-authorization-server

# 检查受保护资源元数据:
curl http://localhost:3000/.well-known/oauth-protected-resource

# 首先通过访问获取您的访问令牌:
open http://localhost:3000/oauth/login

# 然后测试经过身份验证的端点:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  http://localhost:3000/oauth/me

参考文献