h

hburgoyne

@hburgoyne/picard_mcp
0 Stars 322 次浏览 hburgoyne 更新于 2026-08-23
该服务暂未提供标准配置,请参考 README 手动接入

服务介绍

Picard MCP 服务器

概述

Picard MCP 是一个基于 Model Context Protocol (MCP) 标准构建的完整内存管理系统。它由两个主要组件组成:提供安全内存存储和检索服务的 MCP 服务器,以及展示如何与 MCP 服务器集成的 Django 客户端应用程序。该系统使用户能够存储、检索和管理他们的记忆,同时控制访问权限,并允许基于存储的记忆进行语义搜索和 AI 驱动的查询。

MCP 合规性

此实现遵循 Model Context Protocol 标准,允许 LLM 应用程序以标准化方式与服务器交互。MCP 服务器提供了以下功能:

  • 资源:提供给 LLM 的只读端点(记忆内容)
  • 工具:执行操作的功能端点(记忆创建、更新、查询)
  • 认证:OAuth 2.0 实现,用于安全访问受保护的资源

关键组件

  1. MCP 服务器:基于 FastAPI 的 Model Context Protocol 实现,提供:

    • 支持 PKCE 的 OAuth 2.0 认证和授权
    • 带有向量嵌入的记忆存储
    • 基于权限的记忆访问控制
    • 用于基于记忆查询的 LLM 集成
  2. Django 客户端:演示与 MCP 服务器集成的 Web 应用程序:

    • 用户注册和认证
    • OAuth 2.0 客户端实现
    • 记忆创建、检索和管理的用户界面
    • 基于角色的查询界面

系统架构

整体架构

Picard MCP 系统采用客户端-服务器架构,包含以下组件:

  1. MCP 服务器:处理记忆存储、检索和 AI 操作的核心后端服务

    • 使用 FastAPI(FastMCP)构建,以实现高性能和异步支持
    • 使用带有 pgvector 扩展的 PostgreSQL 进行向量存储和语义搜索
    • 实现了用户、记忆(带向量嵌入)、OAuth 客户端和令牌的数据模型
    • 使用 SQLAlchemy ORM 和 Alembic 迁移进行数据库管理
    • 实现了 OAuth 2.0 以确保安全认证和授权
    • 与 OpenAI API 集成以生成记忆嵌入(text-embedding-3-small)
    • 在可用时使用 LangChain 进行 LLM 操作
    • 提供有状态和无状态两种操作模式
    • 支持可流式传输的 HTTP 传输以提高可扩展性
  2. Django 客户端:演示与 MCP 服务器集成的 Web 应用程序

    • 提供用户注册、认证和个人资料管理
    • 实现了 OAuth 2.0 客户端,以确保与 MCP 服务器的安全通信
    • 提供用户友好的记忆管理和查询界面
    • 使用独立于 MCP 服务器的 PostgreSQL 数据库
  3. Docker 基础设施:容器化部署,便于设置和扩展

    • 分别为 MCP 服务器(端口 8001)、Django 客户端(端口 8000)和 PostgreSQL 数据库配置单独的容器
    • 配置网络以确保容器间的安全通信
    • 卷挂载以实现持久数据存储
    • 兼容本地 Docker 部署和 Render 云部署

认证方法

系统提供了两种主要的认证方法:

1. 直接连接并使用用户上下文令牌流(推荐)

这种简化的方法允许用户仅通过 Django 客户端进行一次认证,避免了需要单独对 MCP 服务器进行认证的需求:

  1. 客户端注册
    • Django 客户端使用 /api/admin/clients/register 端点在 MCP 服务器上注册
    • 注册需要管理员认证,并包括客户端名称、重定向 URI 和请求的作用域
    • MCP 服务器会颁发基于 UUID 的客户端 ID 和加密安全的客户端密钥
    • 客户端凭据应安全存储,且不应在客户端代码中暴露- 用户仅通过Django客户端进行身份验证
  • 当用户发起与MCP服务器的连接时,Django客户端向MCP服务器的/api/user-tokens/user-token端点发起服务器端请求
  • 请求包括:
    • 客户端凭证(client_idclient_secret
    • 用户信息(用户名和电子邮件)
    • 如果用户不存在则创建用户的选项
  • MCP服务器验证客户端凭证,并查找或创建相应的用户
  • MCP服务器为用户颁发访问令牌和刷新令牌
  • Django客户端安全地存储这些令牌,并使用它们进行API请求
  1. API访问:

    • 客户端在所有API请求中将访问令牌包含在Authorization头部 (Authorization: Bearer {token})
    • MCP服务器验证令牌签名、过期时间和受众声明
    • MCP服务器对每个端点实施基于范围的权限控制
    • 当访问令牌过期时,客户端使用刷新令牌获取新的令牌
  2. 安全特性:

    • 只有机密客户端可以使用此方法,提供服务器到服务器的安全性
    • 每次令牌请求都会验证客户端凭证
    • 使用后令牌会被列入黑名单以防止重放攻击
    • 刷新令牌使用轮换机制:每次使用都会生成一个新的刷新令牌并使旧令牌失效

2. 标准OAuth 2.0授权码流与PKCE(遗留)

系统还支持遵循RFC 6749和RFC 7636标准的标准OAuth 2.0授权码流程与PKCE,以增强安全性。这种方法要求用户同时通过客户端和MCP服务器进行身份验证:

  1. 授权流程:

    • 用户通过Django客户端启动登录
    • 客户端生成一个用于CSRF保护的加密安全随机state参数
    • 客户端生成一个随机的PKCE code_verifier,并通过SHA-256导出code_challenge
    • 客户端重定向到MCP服务器的/authorize端点,携带以下参数:
      • response_type=code
      • client_id (UUID格式)
      • redirect_uri
      • scope (空格分隔列表,例如memories:read memories:write)
      • state (用于CSRF保护)
      • PKCE参数 (code_challengecode_challenge_method=S256)
    • MCP服务器验证用户身份(如果尚未验证)
    • MCP服务器验证所有参数并将带有短期授权码的响应重定向回客户端
  2. 令牌交换:

    • 客户端验证返回的state参数与授权请求中发送的一致
    • 客户端通过/token端点用授权码换取访问令牌和刷新令牌
    • MCP服务器颁发JWT访问令牌、刷新令牌、过期时间和授予的范围
  3. API访问:

    • 与直接连接方式相同

数据库模型

MCP服务器使用SQLAlchemy ORM,其关键模型如下:

  1. 用户模型:

    • 存储用户信息,包括电子邮件、用户名和哈希密码
    • 包含账户状态标志(如is_active, is_superuser
    • 通过一对多关系关联记忆
  2. 带向量存储的记忆模型:

    • 使用pgvector扩展来存储和查询向量嵌入(1536维)
    • 支持文本内容及可选加密
    • 包括权限控制(私有/公开)
    • 支持时间限制的记忆到期日期
    • 通过外键关系与用户关联
  3. OAuth模型:

    • OAuthClient: 存储客户端应用程序详情,包括client_idclient_secret、重定向URI和授权范围
    • AuthorizationCode: 管理临时授权码,并支持PKCE
    • Token: 存储访问令牌和刷新令牌,并跟踪过期时间

系统使用Alembic进行数据库迁移,确保模式版本控制和易于更新。

记忆管理系统

Picard MCP的核心功能围绕记忆管理展开,主要包括以下几个组件:1. 内存存储:

  • 记忆以带有相关元数据的文本形式存储
  • 通过使用text-embedding-3-small模型生成的向量嵌入,实现了语义搜索功能
  • 权限控制谁可以访问每条记忆
  • 时间戳跟踪创建、修改和过期时间
  • 记忆文本在静止状态下被加密,而元数据保持可搜索性
  • 所有标识符使用UUID格式而非顺序整数,以提高扩展性
  • 每条记忆都使用OpenAI的嵌入模型转换为向量嵌入
  • 嵌入支持语义搜索和相似度匹配
  • PostgreSQL结合pgvector扩展提供了高效的向量存储与检索
  1. 权限管理:

    • 每条记忆都有一个权限级别(私有或公开)
    • 私有记忆仅所有者可访问
    • 公开记忆可供其他用户用于角色查询
    • 系统设计为可扩展,以支持未来的权限类型(例如,统计/聚合用途)
    • 共享记忆可由特定用户或组访问
    • 记忆所有者可以随时修改权限
  2. 记忆检索:

    • 用户可以通过过滤和排序选项检索自己的记忆
    • 语义搜索允许根据意义而不是仅仅关键词来查找记忆
    • 向量相似度(余弦)能够在整个数据库中找到相关的记忆
    • 根据查询的相关性返回最相似的前N条记忆
    • 权限检查确保用户只能访问授权的记忆
  3. 大语言模型集成:

    • 记忆可以用作大语言模型查询的上下文
    • 用户可以根据他们的公开记忆创建角色
    • 其他用户可以查询这些角色以获得基于记忆的信息响应
    • 系统自动处理上下文管理和提示工程

主要特性

MCP服务器特性

  • OAuth 2.0认证:

    • 使用PKCE增强安全性的授权码流程
    • 基于范围的权限系统 (memories:read, memories:write, memories:admin)
    • 支持刷新令牌的令牌管理
    • 客户端注册与管理
  • 记忆管理:

    • 创建、读取、更新和删除记忆
    • 用于语义搜索的向量嵌入
    • 基于权限的访问控制
    • 批量操作以实现高效的记忆管理
  • 用户管理:

    • 用户注册与认证
    • 个人资料管理和设置
    • 活动跟踪与分析
    • 系统管理的管理员控制
  • AI集成:

    • OpenAI API集成用于嵌入和大语言模型查询
    • 基于用户记忆的角色创建
    • 上下文感知的查询处理
    • 可定制的AI参数和设置

Django客户端特性

  • 用户界面:

    • 清晰、响应式的桌面和移动设计
    • 直观的记忆管理界面
    • 高级搜索和过滤选项
    • 角色创建和查询界面
  • OAuth客户端实现:

    • 安全的令牌存储与管理
    • 自动令牌刷新
    • 基于范围的功能可用性
    • 错误处理与恢复
  • 记忆工具:

    • 支持富文本的记忆创建
    • 批量导入导出
    • 权限管理界面
    • 标签和分类

MCP接口

MCP资源

  • 记忆资源: memories://{memory_id}

    • 返回特定记忆的内容,并进行权限检查
    • 参数: memory_id (UUID)
    • 响应: 包含元数据的记忆内容
  • 用户记忆资源: users://{user_id}/memories

    • 返回特定用户的记忆列表,并进行权限检查
    • 参数: user_id (UUID), 可选过滤器
    • 响应: 记忆摘要列表

MCP工具

  • 提交记忆工具: 创建新的记忆

    • 参数: text (字符串), permission (字符串)
    • 返回: 创建的记忆详情及UUID
  • 更新记忆工具: 更新现有记忆- 参数: memory_id (UUID), text (字符串)

    • 返回: 更新后的记忆详情
  • 删除记忆工具: 删除一条记忆

    • 参数: memory_id (UUID)
    • 返回: 成功确认信息
  • 查询记忆工具: 对记忆进行语义搜索

    • 参数: query (字符串), limit (整数)
    • 返回: 相关记忆列表
  • 查询用户: 根据记忆查询用户的个性

    • 参数: user_id (UUID), query (字符串)
    • 返回: 基于用户记忆的响应

API 端点

OAuth 端点

  • 客户端注册: /register

    • 方法: POST
    • 描述: 注册一个新的 OAuth 客户端
    • 请求: 客户端详细信息(ID、密钥、重定向 URI、作用域)
    • 响应: 客户端凭证和注册信息
  • 授权: /authorize

    • 方法: GET
    • 描述: 初始化 OAuth 授权流程
    • 参数: response_type, client_id, redirect_uri, scope, state, code_challenge, code_challenge_method
    • 响应: 重定向到带有授权码的客户端
  • 令牌交换: /token

    • 方法: POST
    • 描述: 用授权码换取令牌
    • 请求: grant_type, code, redirect_uri, client_id, client_secret, code_verifier
    • 响应: 访问令牌、刷新令牌、过期时间和作用域信息

记忆端点

  • 获取记忆: /api/tools (工具: get_memories)

    • 方法: POST
    • 描述: 检索记忆,可选过滤
    • 身份验证: Bearer 令牌
    • 请求: 可选过滤参数 (user_id, permission, expiration status)
    • 响应: 用户可访问的记忆列表
    • 示例请求:
      json
      {
      "tool": "get_memories",
      "data": {
      "user_id": "550e8400-e29b-41d4-a716-446655440000",
      "permission": "private"
      }
      }
  • 提交记忆: /api/tools (工具: submit_memory)

    • 方法: POST
    • 描述: 创建新的记忆
    • 身份验证: Bearer 令牌
    • 请求: 记忆文本、权限级别和过期日期 (ISO 8601 格式,例如 "2025-12-31T23:59:59Z")
    • 响应: 包括 UUID 标识符在内的创建的记忆详情
    • 示例请求:
      json
      {
      "tool": "submit_memory",
      "data": {
      "text": "这是我的记忆内容",
      "permission": "private"
      }
      }
  • 检索记忆: /api/tools (工具: retrieve_memories)

    • 方法: POST
    • 描述: 获取已认证用户的所有记忆
    • 身份验证: Bearer 令牌
    • 响应: 包含 UUID 标识符的记忆对象列表
    • 示例请求:
      json
      {
      "tool": "retrieve_memories",
      "data": {}
      }
  • 更新记忆: /api/tools (工具: update_memory)

    • 方法: POST
    • 描述: 更新现有记忆
    • 身份验证: Bearer 令牌
    • 请求: 记忆 ID、更新的内容以及可选的更新过期日期 (ISO 8601 格式)
    • 响应: 更新后的记忆详情
    • 示例请求:
      json
      {
      "tool": "update_memory",
      "data": {
      "memory_id": "550e8400-e29b-41d4-a716-446655440000",
      "text": "更新后的记忆内容",
      "expiration_date": "2026-01-01T00:00:00Z"
      }
      }
  • 修改权限: /api/tools (工具: modify_permissions)

    • 方法: POST
    • 描述: 更新记忆的权限级别
    • 身份验证: Bearer 令牌
    • 请求: 记忆 UUID 和新的权限级别
    • 响应: 更新后的记忆详情
    • 示例请求:
      json
      {
      "tool": "modify_permissions",
      "data": {
      "memory_id": "550e8400-e29b-41d4-a716-446655440000",
      "permission": "public"
      }
      }
  • 查询用户: /api/tools (工具: query_user)

    • 方法: POST
    • 描述: 根据记忆查询用户的个性(对其他用户公开,对自己公开+私有)
    • 身份验证: Bearer 令牌
    • 请求: 用户 UUID 和查询提示- 响应:包含未过期记忆的 JSON,可以是所有有效记忆或与查询最相似的前 N 条
    • 响应:基于用户记忆生成的 AI 响应
    • 示例请求:
      json
      {
      "tool": "query_user",
      "data": {
      "user_id": "550e8400-e29b-41d4-a716-446655440000",
      "prompt": "你对人工智能有什么看法?"
      }
      }

设置和部署

先决条件

  • Docker 和 Docker Compose
  • Python 3.10+
  • OpenAI API 密钥

完整设置指南

  1. 克隆仓库:
    bash
    git clone https://github.com/yourusername/picard_mcp.git
    cd picard_mcp

  2. 为两个组件创建环境文件:
    bash

    对于 MCP 服务器

    cp mcp_server/.env.example mcp_server/.env

    对于 Django 客户端

    cp django_client/.env.example django_client/.env

  3. 编辑环境文件以设置您的配置:

    • mcp_server/.env 中:设置数据库凭据、OpenAI API 密钥和管理员凭据
    • django_client/.env 中:设置数据库凭据和 OAuth 设置
  4. 使用 Docker Compose 启动服务:
    bash
    docker-compose up -d

    这将启动以下服务:

    • db-mcp:MCP 服务器的 PostgreSQL 数据库
    • db-django:Django 客户端的 PostgreSQL 数据库
    • mcp_server:运行在 http://localhost:8001 的 MCP 服务器
    • django_client:运行在 http://localhost:8000 的 Django 客户端
  5. 为 MCP 服务器创建一个管理员用户:
    bash
    docker-compose exec mcp_server python scripts/create_admin_user.py

    这将使用您在环境变量中指定的凭据创建一个管理员用户。

  6. 将 Django 客户端注册到 MCP 服务器:
    bash
    docker-compose exec django_client python register_oauth_client.py

    这将把 Django 客户端注册到 MCP 服务器,并更新 Django 客户端的 .env 文件中的客户端凭据。

  7. 访问应用程序:

    • MCP 服务器:http://localhost:8001
    • Django 客户端:http://localhost:8000
  8. 在 Django 客户端中创建一个用户帐户并开始使用应用程序。

初始测试

为了验证您的设置是否正确,请运行以下测试:

  1. MCP 服务器测试
    bash
    docker-compose exec mcp_server python -m pytest

    这将运行 MCP 服务器的所有单元测试,包括 OAuth 端点、管理员功能和记忆管理。

  2. Django 客户端测试
    bash
    docker-compose exec django_client python manage.py test

    这将测试 Django 客户端与 MCP 服务器的集成。

  3. 手动测试

    • 在 http://localhost:8000/register 处的 Django 客户端中创建一个用户帐户
    • 登录并通过 OAuth 连接到 MCP 服务器
    • 创建、检索和管理记忆
    • 测试语义搜索功能

安全注意事项

数据保护

  • 记忆文本内容在存储时使用 Python 的 Fernet 对称加密(AES-128 CBC 模式,PKCS7 填充)进行加密,而元数据保持可搜索性
  • 个人身份信息 (PII) 通过文本字段加密得到保护
  • 访问令牌的有效期为 1 小时,以限制暴露时间
  • 刷新令牌是长期有效的,但使用轮换机制:每次使用都会生成一个新的刷新令牌并使旧令牌失效
  • OAuth 令牌安全地存储在 Django 客户端的 PostgreSQL 数据库中

UUID 使用

系统中的所有标识符都使用 UUID v4 格式而不是顺序整数,原因如下:

  1. 安全性:UUID 不会泄露系统信息或记录数量
  2. 可扩展性:UUID 可以在没有数据库协调的情况下生成,支持分布式系统
  3. 不可猜测性:UUID 实际上是不可能被猜测的,防止枚举攻击
  4. 一致性:在整个系统中使用 UUID 简化了与其他服务的集成所有API中的ID(如user_id、memory_id、client_id等)必须采用UUID格式。

OAuth最佳实践

  • 所有OAuth通信在生产环境中必须使用HTTPS
  • 授权码是一次性的且有效期短(最长5分钟)
  • 即使是保密客户端,也要求使用PKCE以实现深度防御
  • 刷新令牌有效期长,但可以由用户或管理员撤销
  • 系统维护一个已撤销令牌的黑名单

文档

API文档

MCP服务器为所有端点提供了Swagger/OpenAPI文档:

  • 当服务器运行时,可以通过/docs访问Swagger UI
  • OpenAPI规范文件位于/openapi.json
  • 所有API端点都完全记录了请求/响应模式及示例

其他文档文件

  • TESTING.md:应用程序测试的全面指南

    • 描述了所有已实现的测试及其目的
    • 提供本地和CI/CD中运行测试的说明
    • 记录测试覆盖率并指出需要额外测试的区域
  • DEBUGGING.md:跟踪问题及其解决方案

    • 记录尚未修复的已知错误
    • 文档化之前解决过的错误及其解决方案
    • 提供常见问题的故障排除指导
  • PLANNING.md:跟踪实施站点所需任务的分解

    • 列出实施站点所需的主任务和子任务
    • 通过复选框标记任务是否已完成

部署

该项目包含用于本地开发的docker-compose.yml以及用于部署到Render的render.yaml蓝图。同一代码库既可以在Docker容器中本地运行,也可以部署到Render云服务上。

MCP服务器部署

  1. Docker部署(推荐用于生产环境):
    bash
    docker-compose up -d

    Docker Compose配置包括:

    • 容器间通信的网络配置
    • 持久数据存储的卷挂载
    • 来自.env文件的环境变量配置
    • 端口映射(Django客户端8000端口,MCP服务器8001端口)
    • 服务依赖项的健康检查
  2. Render云部署:
    使用随附的render.yaml蓝图部署到Render。

许可证

MIT

相关 MCP 服务