Token导航 LogoToken导航TokenDH.com
Apollo MCP Oauth logo
AI代理stdio官方级别未说明来源级核验

Apollo MCP Oauth

MCP Server

集成Apollo MCP Server、Auth0 OAuth2和Google ADK的认证AI代理服务,支持外部API访问和双OAuth认证流程。

工具数

0

提示词数

0

GitHub Stars

0

资源数

0
AI代理Python工作流自动化

安装说明

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

作者 / 组织

prashantkul

提供方

prashantkul

最后核验

2026/5/17 20:19

快速接入

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

命令预览

pip install -r requirements.txt

详细介绍

带Auth0身份验证的Apollo MCP服务器+谷歌ADK代理

该项目演示了如何集成 阿波罗MCP服务器, 身份验证0 OAuth2,以及 Google ADK(代理开发工具包) 创建一个经过身份验证的AI代理,可以访问外部API。

概述

该系统由三个主要部分组成:

  1. 阿波罗MCP服务器:提供由GraphQL API支持的MCP(模型上下文协议)工具,受Auth0身份验证保护
  2. Auth0 OAuth2服务器:使用OAuth 2.0流处理身份验证和授权
  3. 谷歌ADK代理:使用具有双OAuth身份验证流的MCP工具的AI代理

建筑

┌──────────────────────────────────────────────────────────────────┐
│                    User / Developer                              │
└────────────┬─────────────────────────────────────────────────────┘
             │
             │ Chat / API Calls
             │
┌────────────▼──────────────────────────────────────────────────────┐
│                   Google ADK Agent                                │
│                   (space_explorer)                                │
│                                                                   │
│  ┌────────────────────────────────────────────────────────────┐  │
│  │ LlmAgent (Gemini 2.0 Flash)                                │  │
│  │  • Natural language understanding                          │  │
│  │  • Tool selection and execution                            │  │
│  │  • Response generation                                     │  │
│  └───────────────────────┬────────────────────────────────────┘  │
│                          │                                        │
│  ┌───────────────────────▼────────────────────────────────────┐  │
│  │ McpToolset                                                  │  │
│  │  • header_provider: Client credentials (M2M auth)          │  │
│  │  • auth_scheme: Authorization code grant (user auth)       │  │
│  │  • auth_credential: OAuth2 configuration                   │  │
│  └───────────────────────┬────────────────────────────────────┘  │
│                          │                                        │
│  ┌───────────────────────▼────────────────────────────────────┐  │
│  │ oauth_helper.py                                             │  │
│  │  • Credential lifecycle management                         │  │
│  │  • Token caching (session state)                           │  │
│  │  • Automatic token refresh                                 │  │
│  │  • Authorization code exchange                             │  │
│  └────────────────────────────────────────────────────────────┘  │
└───────────────────────┬──────────────────┬───────────────────────┘
                        │                  │
         MCP Protocol   │                  │ OAuth 2.0
        (HTTP+JSON-RPC) │                  │ (Authorization Code)
                        │                  │
                        ▼                  ▼
        ┌───────────────────────┐  ┌──────────────────────┐
        │  Apollo MCP Server    │  │  Auth0 OAuth Server  │
        │  (Port 8000)          │  │                      │
        │                       │  │  Grant Types:        │
        │  Endpoints:           │  │  • Client Credentials│
        │  • /mcp (MCP tools)   │  │  • Authorization Code│
        │  • /.well-known/...   │◄─┤  • Refresh Token     │
        │    (OAuth metadata)   │  │                      │
        │                       │  │  Endpoints:          │
        │  Features:            │  │  • /authorize        │
        │  • Bearer token auth  │  │  • /oauth/token      │
        │  • Tool discovery     │  │  • /.well-known/...  │
        │  • Tool execution     │  │                      │
        │  • GraphQL proxy      │  └──────────────────────┘
        └───────────┬───────────┘
                    │
                    │ GraphQL
                    │
                    ▼
        ┌───────────────────────┐
        │  The Space Devs API   │
        │  (thespacedevs.com)   │
        │                       │
        │  Data:                │
        │  • Rocket launches    │
        │  • Astronauts         │
        │  • Celestial bodies   │
        │  • Space missions     │
        └───────────────────────┘

主要特点

双OAuth 2.0身份验证流程

此实现使用 两种不同的OAuth流程 用于不同目的:

1.客户端凭证流(M2M)

  • 目的:初始MCP服务器连接以发现可用工具
  • :代理初始化(listTools MCP方法)
  • 为什么:工具发现不需要用户交互
  • 实施: get_mcp_headers() 功能在 agent.py

2.授权码授权流程

  • 目的:用户身份验证工具执行
  • :第一次实际调用工具
  • 为什么:工具可能会访问用户特定的数据或需要用户同意
  • 实施: oauth_helper.py 使用ADK的凭证管理
  • 特性:

- 用户同意屏幕(仅限首次使用) - 会话状态下的令牌缓存 - 自动令牌刷新 offline_access 范围 - 安全授权码交换

自动令牌管理

ADK代理处理完整的OAuth2令牌生命周期:

  1. 代币交换:将授权码转换为访问+刷新令牌
  2. 令牌缓存:使用以下命令将令牌存储在会话状态中 credential_cache_key
  3. 令牌刷新:使用刷新令牌自动刷新过期令牌
  4. 错误处理:如果刷新失败,则重新启动身份验证流

ADK如何确定身份验证流

ADK使用 header_providerauth_scheme 为了 不同的目的不同阶段:

header_provider 被使用

目的:MCP协议级通信(服务器连接)

触发器:

  • initialize -初始MCP握手
  • listTools -发现可用工具
  • callTool -执行工具
  • 任何MCP协议方法

header_provider总是被召唤 对于MCP服务器的每个HTTP请求。

def get_mcp_headers(context: ReadonlyContext) -> dict[str, str]:
    # Uses client credentials to get token
    # Called for every MCP server request
    return {"Authorization": f"Bearer {token}"}

auth_scheme/auth_credential 被使用

目的:工具级用户身份验证

触发器:

  • 仅当执行工具时 (callTool)
  • 只有 auth_scheme 已配置
  • ADK检查是否存在有效的缓存凭据

流动:

  1. 用户请求调用工具
  2. ADK检查:“此McpToolset是否配置了auth_scheme?”
  3. 如果是:“我们是否有有效的缓存凭据?”
  4. 如果没有缓存凭据:启动OAuth流(显示同意屏幕)
  5. 获取凭据后:使用用户令牌执行工具

ADK决策树

MCP Server Request (initialize, listTools):
  ├─ ADK calls header_provider()
  └─ Uses returned headers for HTTP request

Tool Execution (callTool):
  ├─ ADK calls header_provider() for MCP communication
  └─ IF auth_scheme is configured:
      ├─ Check for cached credentials (via oauth_helper)
      ├─ If no valid credentials:
      │   └─ Initiate OAuth flow (authorization code grant)
      └─ Include user token in tool execution context

实践中的身份验证阶段

第一阶段:代理初始化

User runs: adk web space_agent
  ↓
ADK → listTools (MCP method)
  ├─ header_provider() called
  │   └─ Returns: Client Credentials Token
  └─ MCP server authenticates request
      └─ Returns: Available tools list

第二阶段:首次工具调用

User asks: "What rocket launches are happening soon?"
  ↓
ADK → callTool (MCP method)
  ├─ header_provider() called
  │   └─ Returns: Client Credentials Token (for MCP protocol)
  │
  └─ auth_scheme configured?
      └─ Yes → oauth_helper.get_user_credentials()
          └─ No cached token found
              └─ Return AuthConfig
                  └─ ADK shows Auth0 consent screen
                      └─ User authorizes
                          └─ Authorization Code Grant flow
                              └─ Cache user token
                                  └─ Execute tool with user token

第三阶段:后续工具调用

User asks: "Who is currently in space?"
  ↓
ADK → callTool (MCP method)
  ├─ header_provider() called
  │   └─ Returns: Client Credentials Token (for MCP protocol)
  │
  └─ auth_scheme configured?
      └─ Yes → oauth_helper.get_user_credentials()
          └─ Cached token found ✓
              └─ Execute tool with cached user token
                  └─ No consent screen needed

第四阶段:令牌刷新

User asks: "More launches please"
  ↓
ADK → callTool (MCP method)
  ├─ header_provider() called
  │   └─ Returns: Client Credentials Token (for MCP protocol)
  │
  └─ auth_scheme configured?
      └─ Yes → oauth_helper.get_user_credentials()
          └─ Cached token expired ✗
              └─ Refresh token found ✓
                  └─ OAuth2CredentialRefresher.refresh()
                      └─ Get new access + refresh tokens
                          └─ Update cache
                              └─ Execute tool with new user token

为什么两种身份验证方法?

我们的双重身份验证方法满足不同的需求:

  1. header_provider:MCP服务器本身需要Auth0身份验证才能连接
  2. auth_scheme:工具可能需要用户特定的身份验证(不同于服务器身份验证)

其他可能的配置:

  • header_provider:如果MCP服务器需要身份验证,但工具不需要用户同意
  • auth_scheme:如果MCP服务器是公共的,但工具需要用户身份验证
  • 两者都不如果一切都是公开的

关键见解: header_provider 用于 传输级身份验证, auth_scheme 用于 工具级身份验证.ADK始终使用 header_provider 用于MCP通信,但仅参与 auth_scheme 当工具被实际调用时。

重要提示:页眉合并行为

ADK实际上是如何工作的 (基于源代码分析):

两者 auth_schemeheader_provider 转换为HTTP标头 融为一体:

  1. auth_scheme 凭证→ HTTP报头(例如。, Authorization: Bearer )
  2. header_provider() → 其他HTTP标头
  3. 两个集合合并: headers.update(auth_headers) 然后 headers.update(dynamic_headers)
  4. 如果发生碰撞, header_provider 胜利 (最后申请)

在我们的实施中:

两者都试图设置 Authorization 头球

  • auth_schemeAuthorization: Bearer
  • header_providerAuthorization: Bearer

结果: MCP服务器接收 客户端凭据令牌 (从 header_provider),而不是用户令牌。用户令牌由OAuth流生成,但在到达MCP服务器之前会被覆盖。

为什么这仍然有效:

我们的MCP服务器仅验证是否存在有效的Auth0令牌。它不需要用户特定的权限,因此客户端凭据令牌就足够了。

对于用户级身份验证:

如果您需要MCP服务器接收用户令牌(例如,用于用户级授权):

✅ 已实施的解决方案:

我们的 get_mcp_headers() 函数现在检查用户凭据并进行调整:

def get_mcp_headers(context: ReadonlyContext) -> dict[str, str]:
    # Check if user credentials are cached in session
    user_credential = context._invocation_context.session_state.get(CREDENTIAL_CACHE_KEY)

    if user_credential and user_credential.oauth2.access_token:
        # User is authenticated - don't set Authorization header
        # Let auth_scheme provide the user token
        return {"Content-Type": "application/json"}

    # No user credentials - use client credentials for initial connection
    return {
        "Authorization": f"Bearer {get_client_credentials_token()}",
        "Content-Type": "application/json",
    }

它是如何工作的:

  1. 第一个请求(listTools):没有用户凭据→ 使用的客户端凭据
  2. 用户登录后:缓存用户凭据→ header_provider 跳过授权标头
  3. ADK的认证方案:提供 Authorization: Bearer 无碰撞
  4. MCP服务器接收:用于正确授权的用户特定令牌

备选方案:

  • 选项2:使用 header_provider 仅适用于非授权标头(例如,自定义标头、API密钥)
  • 选项3:删除 header_provider 如果MCP服务器不需要身份验证即可发现

ADK_认证_内部.md 以获取源代码参考的详细分析。

项目结构

apollo-mcp-auth/
├── .env                             # Environment configuration (DO NOT COMMIT)
├── .env.example                    # Example environment variables template
├── .gitignore                      # Git ignore patterns
├── README.md                       # This file
├── ADK_AUTHENTICATION_INTERNALS.md # Deep dive into ADK auth mechanisms
│
├── space_agent/                    # Google ADK Agent
│   ├── __init__.py                # Package initialization
│   ├── agent.py                   # Main agent with dual OAuth flows
│   ├── oauth_helper.py            # Credential lifecycle management
│   ├── requirements.txt           # Python dependencies
│   └── README.md                  # Detailed agent documentation
│
├── test_mcp_auth.py               # Standalone Auth0 + MCP test script
└── requirements.txt               # Root-level Python dependencies

入门指南

先决条件

  1. Python 3.10+ (MCP SDK需要)
  2. Auth0帐户 已配置常规Web应用程序
  3. Google Gemini API密钥 或谷歌云项目
  4. 阿波罗MCP服务器 在端口8000上运行

快速开始

  1. 克隆存储库:
   git clone git@github.com:prashantkul/apollo-mcp-oauth.git
   cd apollo-mcp-oauth
  1. 配置环境:
   cp .env.example .env
   # Edit .env with your Auth0 and Google credentials
  1. 安装依赖项:
   cd space_agent
   pip install -r requirements.txt
  1. 启动代理:
   adk web space_agent
  1. 与代理交互:

- 打开ADK web UI(通常http://localhost:3000) - 问一些问题,比如“什么火箭即将发射?” - 第一次工具调用将触发Auth0同意屏幕 - 后续调用使用缓存的凭据

Auth0配置

应用程序设置

  • 应用类型:常规Web应用程序
  • 资助类型:

- ✅ 授权码 - ✅ 刷新令牌 - ✅ 客户端凭证

  • 允许的回调URL: http://127.0.0.1:8081/dev-ui/
  • 允许的Web来源: http://127.0.0.1:8081

API配置

  • 标识符: http://127.0.0.1:8000/mcp
  • 范围: read:users (API的自定义范围)
  • 授权申请:您的常规Web应用程序

标准OIDC范围

代理请求这些作用域(自动可用):

  • openid -OpenID连接身份验证
  • profile -用户资料信息
  • email -用户电子邮件地址
  • offline_access -刷新令牌以续订令牌

身份验证流程详解

第一阶段:代理初始化

1. User runs: adk web space_agent
2. Agent calls get_mcp_headers()
3. get_mcp_headers() requests token from Auth0 (client credentials)
4. Auth0 returns access token
5. Agent calls listTools on MCP server with Bearer token
6. MCP server validates token and returns available tools
7. Agent is ready, web UI displays

第二阶段:首次工具调用

1. User asks: "What rocket launches are happening soon?"
2. Agent selects: space_SearchUpcomingLaunches tool
3. ADK calls oauth_helper.get_user_credentials()
4. No cached credentials found, returns AuthConfig
5. ADK opens Auth0 consent screen in browser
6. User logs in and accepts permissions
7. Auth0 redirects to http://127.0.0.1:8081/dev-ui/?code=...
8. ADK exchanges code for access + refresh tokens
9. ADK caches tokens in session state
10. Agent executes tool with user's access token
11. MCP server validates token and executes GraphQL query
12. Agent returns results to user

第三阶段:后续通话

1. User asks: "Who is currently in space?"
2. Agent selects: space_GetAstronauts tool
3. ADK checks session cache - valid token found
4. Agent executes tool with cached token
5. No authentication prompt needed
6. Results returned immediately

阶段4:令牌刷新

1. Access token expires (after ~1 hour typically)
2. ADK detects expiration
3. ADK uses refresh token to get new access token
4. Auth0 returns new access + refresh tokens
5. ADK updates cache with new tokens
6. Tool execution continues seamlessly
7. No user interaction needed

文档

  • 太空特工:参见 space_agent/README.md 获取详细的代理文档
  • 架构图:代理README中的组件和序列图
  • Auth0设置:代理README中的配置说明

使用的技术

实现模式

实施的关键模式:

  • 基于环境的配置
  • 关注点分离(oauth_helper.py)
  • 凭证生命周期管理
  • 基于会话的令牌缓存
  • 自动令牌刷新

故障排除

space_agent/README.md 有关详细的故障排除指南。

贡献

这是一个示范项目。请随意分叉并适应您自己的用例。

许可证

麻省理工学院

致谢

  • 谷歌ADK团队 用于代理开发工具包
  • 阿波罗GraphQL 阿波罗路由器中的MCP支持
  • 身份验证0 用于OAuth2身份验证平台
  • 太空开发人员 用于空间数据API

目录标签

目录标签

AI代理Python工作流自动化本地部署OAuth认证GraphQLAPI外部API集成令牌管理

接入字段

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

stdio

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

oauth

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

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

0

权限和风险

stdiooauth部署方式未说明

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

安装前确认

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

来源信息

继续浏览同类 MCP