# hburgoyne
## 基本信息
- Slug: `hburgoyne-picard_mcp`
- Source: modelscope
- Publisher: @hburgoyne/picard_mcp
- Categories: knowledge-and-memory / vector-databases / rag-systems
- Hosted: No
- License: Unknown
- Source URL: https://www.modelscope.cn/mcp/servers/@hburgoyne/picard_mcp
## 简介
暂无描述。
## MCP Server 详情

# Picard MCP 服务器

## 概述

Picard MCP 是一个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 标准构建的完整内存管理系统。它由两个主要组件组成：提供安全内存存储和检索服务的 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_id`和`client_secret`）
  - 用户信息（用户名和电子邮件）
  - 如果用户不存在则创建用户的选项
- MCP服务器验证客户端凭证，并查找或创建相应的用户
- MCP服务器为用户颁发访问令牌和刷新令牌
- Django客户端安全地存储这些令牌，并使用它们进行API请求

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

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

#### 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_challenge` 和 `code_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_id`、`client_secret`、重定向URI和授权范围
   - **AuthorizationCode**: 管理临时授权码，并支持PKCE
   - **Token**: 存储访问令牌和刷新令牌，并跟踪过期时间

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

### 记忆管理系统

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

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

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

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

## 主要特性

### 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_ver…

