Picard MCP 服务器
概述
Picard MCP 是一个基于模型上下文协议 (MCP)标准构建的完整内存管理系统。它由两个主要组件组成:一个提供安全内存存储和检索服务的 MCP 服务器,以及一个演示如何与 MCP 服务器集成的 Django 客户端应用程序。该系统允许用户在控制访问权限的同时存储、检索和管理他们的内存,并允许基于存储的内存进行语义搜索和 AI 查询。
MCP 合规性
此实现遵循模型上下文协议 (MCP) 标准,该标准允许 LLM 应用程序以标准化方式与服务器交互。MCP 服务器公开:
- 资源:向 LLM 提供数据(内存内容)的只读端点
- 工具:执行操作的功能端点(内存创建、更新、查询)
- 身份验证:OAuth 2.0 实现,用于安全访问受保护的资源
关键组件
- MCP 服务器:基于 FastAPI 的模型上下文协议实现,提供以下功能:
- 支持 PKCE 的 OAuth 2.0 身份验证和授权
- 带有向量嵌入的内存存储
- 基于权限的内存访问控制
- 基于内存的查询的 LLM 集成
- Django 客户端:演示与 MCP 服务器集成的 Web 应用程序:
- 用户注册和身份验证
- OAuth 2.0客户端实现
- 内存创建、检索和管理 UI
- 基于角色的查询界面
系统架构
总体架构
Picard MCP 系统遵循客户端-服务器架构,具有以下组件:
- MCP 服务器:处理内存存储、检索和 AI 操作的核心后端服务
- 采用 FastAPI(FastMCP)构建,提供高性能和异步支持
- 使用带有 pgvector 扩展的 PostgreSQL 进行向量存储和语义搜索
- 为用户、记忆(带有向量嵌入)、OAuth 客户端和令牌实现数据模型
- 使用 SQLAlchemy ORM 和 Alembic 迁移进行数据库管理
- 实施 OAuth 2.0 以实现安全身份验证和授权
- 与 OpenAI API 集成以实现记忆嵌入 (text-embedding-3-small)
- 在可用的情况下使用 LangChain 进行 LLM 操作
- 提供有状态和无状态操作模式
- 支持流式 HTTP 传输,以实现更好的可扩展性
- Django 客户端:演示与 MCP 服务器集成的 Web 应用程序
- 提供用户注册、身份验证和配置文件管理
- 实现 OAuth 2.0 客户端与 MCP 服务器进行安全通信
- 提供用户友好的内存管理和查询界面
- 使用独立于 MCP 服务器的 PostgreSQL 数据库
- Docker 基础设施:容器化部署,易于设置和扩展
- MCP 服务器(端口 8001)、Django 客户端(端口 8000)和 PostgreSQL 数据库的独立容器
- 配置网络以实现安全的容器间通信
- 用于持久数据存储的卷安装
- 兼容本地 Docker 部署和渲染云部署
身份验证方法
该系统提供两种主要的身份验证方法:
1. 直接连接用户上下文令牌流程(推荐)
这种简化的方法允许用户仅使用 Django 客户端进行一次身份验证,从而避免了单独的 MCP 服务器身份验证:
- 客户注册:
- Django 客户端使用
/api/admin/clients/register
端点向 MCP 服务器注册 - 注册需要管理员身份验证,包括客户端名称、重定向 URI 和请求的范围
- MCP 服务器发布基于 UUID 的客户端 ID 和加密安全的客户端密钥
- 客户端凭据应安全存储,并且永远不会在客户端代码中暴露
- Django 客户端使用
- 用户身份验证流程:
- 用户仅通过 Django 客户端进行身份验证
- 当用户发起与 MCP 服务器的连接时,Django 客户端会向 MCP 的
/api/user-tokens/user-token
端点发出服务器端请求 - 该请求包括:
- 客户端凭证(client_id 和 client_secret)
- 用户信息(用户名和电子邮件)
- 如果不存在则创建用户的选项
- MCP 服务器验证客户端凭据并查找或创建相应的用户
- MCP 服务器为用户发放访问和刷新令牌
- Django 客户端安全地存储这些令牌并将其用于 API 请求
- API访问:
- 客户端���所有 API 请求的授权标头中包含访问令牌(
Authorization: Bearer {token}
) - MCP 服务器验证令牌签名、有效期和受众声明
- MCP 服务器为每个端点强制执行基于范围的权限
- 当访问令牌过期时,客户端使用刷新令牌获取新的访问令牌
- 客户端���所有 API 请求的授权标头中包含访问令牌(
- 安全功能:
- 只有机密客户端才能使用此方法,从而提供服务器到服务器的安全性
- 针对每个令牌请求验证客户端凭据
- 令牌使用后会被列入黑名单,以防止重放攻击
- 刷新令牌使用轮换:每次使用都会生成一个新的刷新令牌并使旧令牌无效
2. 使用 PKCE 的标准 OAuth 2.0 授权码流程(遗留)
该系统还支持带有 PKCE 的标准 OAuth 2.0 授权码流程,以增强安全性,遵循 RFC 6749 和 RFC 7636 标准。此方法要求用户同时在客户端和 MCP 服务器上进行身份验证:
- 授权流程:
- 用户通过 Django 客户端发起登录
- 客户端生成加密安全的随机
state
参数以进行 CSRF 保护 - 客户端生成随机 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_challenge
和code_challenge_method=S256
)
- MCP 服务器对用户进行身份验证(如果尚未进行身份验证)
- MCP 服务器验证所有参数,并使用短期授权码重定向回客户端
- 代币兑换:
- 客户端验证返回的
state
参数与授权请求中发送的状态参数匹配 - 客户端通过
/token
端点交换访问和刷新令牌的授权码 - MCP 服务器发出 JWT 访问令牌、刷新令牌、到期时间和授予范围
- 客户端验证返回的
- API访问:
- 与直接连接方法相同
数据库模型
MCP 服务器使用 SQLAlchemy ORM 及其以下关键模型:
- 用户模型:
- 使用电子邮件、用户名和散列密码存储用户信息
- 包括帐户状态的布尔标志(is_active、is_superuser)
- 通过一对多关系链接到记忆
- 具有向量存储的内存模型:
- 使用 pgvector 扩展来存储和查询向量嵌入(1536 维)
- 支持可选加密的文本内容
- 包括权限控制(私人/公共)
- 支持限时记忆的到期日期
- 通过外键关系与用户关联
- OAuth 模型:
- OAuthClient :存储客户端应用程序详细信息,包括 client_id、client_secret、重定向 URI 和授权范围
- AuthorizationCode :使用 PKCE 支持管理临时授权码
- 令牌:存储访问和刷新令牌,并跟踪到期时间
该系统使用 Alembic 进行数据库迁移,确保模式版本控制和轻松更新。
内存管理系统
Picard MCP 的核心功能围绕内存管理,包含以下组件:
- 内存存储:
- 记忆以文本形式存储,并附带相关元数据
- 向量嵌入(使用 text-embedding-3-small 模型)支持语义搜索功能
- 权限控制谁可以访问每个内存
- 时间戳跟踪创建、修改和到期
- 内存文本处于静态加密状态,但元数据仍可搜索
- 所有标识符均使用 UUID 格式,而不是连续整数,以实现可扩展性
- 使用 OpenAI 的嵌入模型将每个记忆转换为向量嵌入
- 嵌入支持语义搜索和相似性匹配
- 带有 pgvector 扩展的 PostgreSQL 提供高效的向量存储和检索
- 权限管理:
- 每个内存都有一个权限级别(私有或公共)
- 私人记忆只有主人才能访问
- 其他用户可以访问公共记忆以进行角色查询
- 系统设计为可扩展以适应未来的权限类型(例如,用于统计/汇总用途)
- 特定用户或群组可以访问共享记忆
- 内存所有者可以随时修改权限
- 记忆检索:
- 用户可以通过筛选和排序选项检索自己的记忆
- 语义搜索允许根据含义(而不仅仅是关键词)查找记忆
- 向量相似度(余弦)可以在数据库中找到相关的记忆
- 根据查询相关性返回 Top-N 最相似的记忆
- 权限检查确保用户只能访问授权的记忆
- LLM 集成:
- 记忆可以用作 LLM 查询的上下文
- 用户可以根据自己的公开记忆创建角色
- 其他用户可以查询这些角色,以获得记忆中的信息
- 系统自动处理上下文管理和提示工程
主要特点
MCP 服务器功能
- OAuth 2.0身份验证:
- 授权码流与 PKCE 配合使用,增强安全性
- 基于范围的权限系统(
memories:read
、memories:write
、memories:admin
) - 支持刷新令牌的令牌管理
- 客户注册和管理
- 内存管理:
- 创建、读取、更新和删除记忆
- 用于语义搜索的向量嵌入
- 基于权限的访问控制
- 批量操作以实现高效的内存管理
- 用户管理:
- 用户注册和身份验证
- 配置文件管理和设置
- 活���追踪和分析
- 系统管理的管理员控制
- 人工智能集成:
- 用于嵌入和 LLM 查询的 OpenAI API 集成
- 根据用户记忆创建角色
- 上下文感知查询处理
- 可定制的 AI 参数和设置
Django 客户端功能
- 用户界面:
- 简洁、响应迅速的桌面和移动设备设计
- 直观的内存管理界面
- 高级搜索和过滤选项
- 角色创建和查询界面
- OAuth客户端实现:
- 安全令牌存储和管理
- 自动令牌刷新
- 基于范围的功能可用性
- 错误处理和恢复
- 记忆工具:
- 创建具有富文本支持的内存
- 批量导入导出
- 权限管理接口
- 标记和分类
MCP 接口
MCP 资源
- 内存资源:
memories://{memory_id}
- 返回具有权限检查的特定内存的内容
- 参数:memory_id(UUID)
- 响应:带有元数据的内存内容
- 用户回忆资源:
users://{user_id}/memories
- 返回具有权限检查的特定用户的记忆列表
- 参数:user_id(UUID),可选过滤器
- 响应:内存摘要列表
MCP 工具
- 提交记忆工具:创建新记忆
- 参数:文本(字符串)、权限(字符串)
- 返回:使用 UUID 创建的内存详细信息
- 更新记忆工具:更新现有记忆
- 参数:memory_id(UUID)、text(字符串)
- 返回:更新的内存详细信息
- 删除记忆工具:删除记忆
- 参数:memory_id(UUID)
- 返回:成功确认
- 查询记忆工具:对记忆进行语义搜索
- 参数:查询(字符串)、限制(整数)
- 返回:相关记忆列表
- 查询用户:根据记忆查询用户的角色
- 参数: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
- 描述:使用可选的筛选功能检索记忆
- 身份验证:持有者令牌
- 请求:可选的过滤参数(user_id、权限、过期状态)
- 响应:用户可访问的记忆列表
- 示例请求:
- 提交内存:
/api/tools
(工具:submit_memory
)- 方法:POST
- 描述:创建新的记忆
- 身份验证:持有者令牌
- 请求:内存文本、权限级别和到期日期(ISO 8601 格式,例如“2025-12-31T23:59:59Z”)
- 响应:已创建内存详细信息,包括 UUID 标识符
- 示例请求:
- 检索记忆:
/api/tools
(工具:retrieve_memories
)- 方法:POST
- 描述:获取已认证用户的所有记忆
- 身份验证:持有者令牌
- 响应:具有 UUID 标识符的内存对象列表
- 示例请求:
- 更新内存:
/api/tools
(工具:update_memory
)- 方法:POST
- 描述:更新现有内存
- 身份验证:持有者令牌
- 请求:内存 ID、更新内容以及可选更新的到期日期(ISO 8601 格式)
- 响应:更新了内存详细信息
- 示例请求:
- 修改权限:
/api/tools
(工具:modify_permissions
)- 方法:POST
- 描述:更新内存权限级别
- 身份验证:持有者令牌
- 请求:内存UUID和新的权限级别
- 响应:更新了内存详细信息
- 示例请求:
- 查询用户:
/api/tools
(工具:query_user
)- 方法:POST
- 描述:根据记忆查询用户的角色(对其他用户公开,对自己公开+私人)
- 身份验证:持有者令牌
- 请求:用户UUID和查询提示
- 响应:包含未过期记忆的 JSON,可以是所有有效记忆,也可以是与查询最相似的前 N 个记忆
- 响应:基于用户记忆的人工智能生成的响应
- 示例请求:
设置和部署
先决条件
- Docker 和 Docker Compose
- Python 3.10+
- OpenAI API 密钥
完整的安装指南
- 克隆存储库:
- 为两个组件创建环境文件:
- 编辑环境文件来设置您的配置:
- 在
mcp_server/.env
中:设置数据库凭据、OpenAI API 密钥和管理员凭据 - 在
django_client/.env
中:设置数据库凭据和 OAuth 设置
- 在
- 使用 Docker Compose 启动服务:这将启动以下服务:
db-mcp
:MCP 服务器的 PostgreSQL 数据库db-django
:Django 客户端的 PostgreSQL 数据库mcp_server
:运行于http://localhost:8001 的MCP 服务器django_client
:在http://localhost:8000上运行的 Django 客户端
- 为 MCP 服务器创建管理员用户:这将创建一个具有环境变量中指定的凭据的管理员用户。
- 将 Django 客户端注册到 MCP 服务器:这将向 MCP 服务器注册 Django 客户端,并使用客户端凭据更新 Django 客户端的
.env
文件。 - 访问应用程序:
- MCP 服务器: http://localhost:8001
- Django 客户端: http://localhost:8000
- 在 Django 客户端中创建用户帐户并开始使用该应用程序。
初步测试
要验证您的设置是否正常工作,请运行以下测试:
- MCP 服务器测试:这将运行 MCP 服务器的所有单元测试,包括 OAuth 端点、管理功能和内存管理。
- Django 客户端测试:这将测试 Django 客户端与 MCP 服务器的集成。
- 手动测试:
- 在 Django 客户端的http://localhost:8000/register中创建用户帐户
- 通过 OAuth 登录并连接到 MCP 服务器
- 创建、检索和管理记忆
- 测试语义搜索功能
安全注意事项
数据保护
- 内存文本内容使用 Python 的 Fernet 对称加密(CBC 模式下的 AES-128 和 PKCS7 填充)进行静态加密,同时元数据仍然可搜索
- 个人身份信息 (PII) 通过文本字段加密进行保护
- 访问令牌的有效期为 1 小时,以限制暴露
- 刷新令牌是长期有效的,但使用轮换:每次使用都会生成一个新的刷新令牌并使旧令牌无效
- OAuth 令牌安全地存储在 Django 客户端的 PostgreSQL 数据库中
UUID 用法
系统中的所有标识符都使用 UUID v4 格式而不是连续整数,原因如下:
- 安全性:UUID 不会暴露系统信息或记录计数
- 可扩展性:无需数据库协调即可生成 UUID,从而实现分布式系统
- 不可猜测性:UUID 几乎不可能被猜测,从而防止枚举攻击
- 一致性:在整个系统中使用 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 :跟踪问题及其解决方案
- 记录尚未修复的已知错误
- 记录之前解决的 bug 及其解决方案
- 提供常见问题的故障排除指导
- PLANNING.md :跟踪实施网站所需的任务细分
- 列出实施网站所需的任务和子任务
- 使用复选框记录任务是否已完成
部署
该项目包含用于本地开发的docker-compose.yml
文件和用于部署到 Render 的render.yaml
蓝图。相同的代码库既可以在本地 Docker 容器中运行,也可以部署到 Render 云服务中运行。
MCP 服务器部署
- Docker 部署(推荐用于生产):Docker Compose 配置包括:
- 容器间通信的网络配置
- 用于持久数据存储的卷挂载
- .env 文件中的环境变量配置
- 端口映射(Django 客户端为 8000,MCP 服务器为 8001)
- 服务依赖关系的健康检查
- 渲染云部署:使用包含的
render.yaml
蓝图部署到渲染。
执照
麻省理工学院
This server cannot be installed
remote-capable server
The server can be hosted and run remotely because it primarily relies on remote services or has no dependency on the local environment.
基于 Django 的模型上下文协议 (MCP) 实现,用于管理政治偏好和未来愿景。
Related MCP Servers
- AsecurityAlicenseAqualityModel Context Protocol (MCP) is a new, standardized protocol for managing context between large language models (LLMs) and external systems. In this repository, we provide an installer as well as an MCP Server for Upstash Developer API's.Last updated -165827TypeScriptMIT License
- AsecurityFlicenseAqualityA Model Context Protocol (MCP) server that optimizes token usage by caching data during language model interactions, compatible with any language model and MCP client.Last updated -4JavaScript
- -securityFlicense-qualityA Model Context Protocol service that wraps Django's migration commands as MCP endpoints, making it easy to manage migrations across multiple services and integrate with CI/CD pipelines.Last updated -Python
- -securityFlicense-qualityA Python-based implementation of the Model Context Protocol that enables communication between a model context management server and client through a request-response architecture.Last updated -Python