内容
# 图形内存MCP服务器
图形内存(GraphMem)是一个使用Ruby on Rails框架实现的模型上下文协议(MCP)服务器,用于基于图形的内存管理。它使AI助手和其他客户端能够通过标准化的接口创建、检索、搜索和管理知识实体及其关系。
[](lib/graph_mem/version.rb)
[](Gemfile)
[](Gemfile)
## 概述
图形内存提供持久化、结构化的存储,用于知识实体、它们的关系和观察。它被设计为一个MCP服务器,使AI助手能够在会话之间维护内存,构建特定领域的知识图谱,并有效地引用过去的交互。
### 单用户设计
图形内存被设计为一个**单用户、本地网络服务器**。没有身份验证层 - 服务器信任所有传入的请求。
**每代理项目上下文:** 多个MCP客户端可以并发连接而不会相互覆盖作用范围。每个代理通过在MCP配置中设置`X-MCP-Client`头部来标识自己:
```json
{
"mcpServers": {
"graph_mem": {
"url": "http://localhost:3030/mcp/sse",
"headers": { "X-MCP-Client": "Agent-1" }
}
}
}
```
上述示例假设使用容器设置,该设置硬编码为端口3030。(APP_PORT当前在Dockerfile和docker-compose.yml中硬编码)
通过`set_context`设置的上下文存储在数据库中每个`client_id`,并且在服务器重启后仍然存在。没有设置头部的代理共享`"default"`客户端存储桶(向后兼容的单代理行为)。
身份验证和多租户隔离目前不在考虑范围内;头部是合作范围键,而不是安全边界。
**关键功能:**
- **矢量语义搜索** 通过MariaDB 11.8原生VECTOR支持 + Ollama嵌入
- **项目上下文范围** - 通过`X-MCP-Client`每个代理,重启后仍然存在
- **实体类型规范化** 以防止图谱碎片化
- **自动去重** 在实体创建时
- **混合搜索** 结合文本标记化和矢量相似性(带有上下文增强)
- **Docker Compose** 部署,支持自动启动
- **局域网范围嵌入** 架构,使用集中式Ollama主机
## 技术栈
* **Ruby**: 3.4.1+
* **Rails**: 8.1.2+
* **MCP实现**: [fast-mcp](https://github.com/yjacquin/fast-mcp) gem
* **数据库**: MariaDB 11.8+(需要VECTOR支持)
* **嵌入**: Ollama with nomic-embed-text(768维度)
## 功能
### 规则和技能
图形内存包含可安装的用户规则和技能:
- 规则:docs/global_and_knowledge_graph_management_rules.md
- 技能:.cursor/skills/graph-mem-mcp-toolset/SKILL.md
### MCP工具
图形内存公开以下MCP工具:
#### 实体管理
* `create_entity` -- 创建新的实体,自动检查重复
* `get_entity` -- 通过ID检索实体,包含观察和关系
* `update_entity` -- 修改实体名称、类型、别名、描述
* `delete_entity` -- 删除实体和所有关联数据
* `search_entities` -- 混合文本 + 矢量语义搜索,相关性排名
* `list_entities` -- 实体分页列表
#### 观察管理
* `create_observation` -- 向现有实体添加观察
* `delete_observation` -- 删除观察
#### 关系管理
* `create_relation` -- 创建实体之间的类型化关系
* `delete_relation` -- 删除关系
* `find_relations` -- 通过实体或类型查找关系
* `get_subgraph_by_ids` -- 获取指定实体的连接子图
* `search_subgraph` -- 跨实体和观察搜索,分页
#### 上下文和工作流
* `set_context` -- 将后续操作范围限定到项目(每个`X-MCP-Client`)
* `get_context` -- 检查活动项目上下文
* `clear_context` -- 删除项目范围
* `bulk_update` -- 原子批量创建实体、观察和关系
* `suggest_merges` -- 通过矢量相似性查找潜在重复实体
* `merge_entities` -- 将源实体合并到目标实体(转移观察和关系)
* `dream_state_status` -- 报告后台图谱压缩状态(运行/暂停/光标)
* `get_maintenance_reports` -- 读取维护/压缩报告,包括`compaction_review`队列
#### 实用工具
* `get_version` -- 服务器版本
* `get_current_time` -- 服务器时间,ISO 8601格式
### 梦态压缩
后台**梦态**作业(`DreamStateCompactionJob`,通过Solid Queue `recurring.yml`调度)定期压缩知识图谱:
- **孤儿阶段** -- 将高置信度的孤儿节点附加到匹配的`Project`根节点
- **树遍历阶段** -- 去除重复的观察并自动合并非常相似的实体(余弦距离 < 0.10)
- **审查队列** -- 低置信度的合并和孤儿匹配写入`maintenance_reports`(`compaction_review`),可通过`get_maintenance_reports`读取
该作业是**合作暂停的**:在运行压缩时,变异的MCP工具会请求暂停,以便实时流量优先。 使用`dream_state_status`检查光标位置和统计数据,并使用`get_maintenance_reports`审查和操作队列中的建议。 暂停的运行将在下一个调度的触发器上恢复。
### MCP资源
* `memory_entities` -- 查询实体,支持筛选、排序和关系包含
* `memory_observations` -- 访问观察,支持高级筛选
* `memory_relations` -- 查询关系,支持双向实体包含
* `memory_graph` -- 从任何实体开始的图遍历
### REST API
`/api/v1`下提供完整的REST API,用于直接集成。Swagger文档可在`/api-docs`访问。
### 图形可视化
交互式Cytoscape.js图形可视化在服务器根目录( `/`),具有上下文菜单、拖放操作和数据管理功能。
## 快速入门(使用Docker)
**前提条件:** Ollama必须在主机上运行,并至少有一个嵌入模型被拉取:
```bash
# 安装Ollama(https://ollama.com)然后拉取默认嵌入模型
ollama pull nomic-embed-text
```
> `app`容器使用`network_mode: host`,因此它共享主机的网络栈。`localhost:11434`可以直接访问Ollama,无需额外的桥接/防火墙配置。应用程序直接绑定到主机端口3030。
```bash
# 克隆并进入项目
git clone https://github.com/steveoro/graph_mem.git
cd graph_mem
# 复制示例配置并设置主密钥
cp .env.example .env
# 编辑.env:设置RAILS_MASTER_KEY(来自config/master.key)和DB_PASSWORD
# 启动栈(MariaDB 11.8 + Rails生产模式)
docker compose up -d
# 种子规范实体类型
docker compose exec app bin/rails db:seed
# 验证Ollama连接
docker compose exec app bin/rails embeddings:check
# 回填嵌入
docker compose exec app bin/rails embeddings:backfill
# 在存储库拉取后更新容器
docker compose down && docker compose up -d --build
```
应用程序可在`http://localhost:3030`访问。Swagger API文档在`http://localhost:3030/api-docs`。
应用程序端口(3030)在Dockerfile和docker-compose.yml中硬编码,因为服务依赖于主机网络来访问嵌入服务提供的`ollama`。这允许在不同机器上使用更简单的容器设置,而无需使用iptables或防火墙篡改。
该容器化应用程序是一个**单用户服务器**,没有身份验证层 - 它被设计为在本地机器上运行和/或仅通过受信任的局域网访问。**请不要将此服务暴露给公共互联网。**
## 局域网共享
要允许运行`graph_mem`的本地Ubuntu服务器与嵌入处理运行为服务的`ollama`共享,请记住,如果您使用`ufw`(假设您的局域网设置为192.168.0.0/24):
```bash
sudo ufw allow from 192.168.0.0/24 to any port 3030 proto tcp comment "GraphMem from LAN"
sudo ufw allow from 192.168.0.0/24 to any port 11434 proto tcp comment "Ollama from LAN"
```
这样,图形内存界面将在`http://<graph_mem_server_ip>:3030/`上可访问,而MCP服务器将在`http://<graph_mem_server_ip>:3030/mcp/sse`上可用。
## 原生开发设置
对于本地开发,在本地主机上使用MariaDB运行应用程序。
1. **前提条件:**
* Ruby 3.4.1+(通过RVM或rbenv)
* MariaDB 11.8+(用于矢量搜索)
* Ollama带有嵌入模型
2. **安装依赖项:**
```bash
bundle install
```
3. **数据库设置:**
```bash
cp config/database.example.yml config/database.yml
# 编辑config/database.yml以设置您的MariaDB凭证
bin/rails db:prepare
bin/rails db:seed
```
4. **拉取嵌入模型:**
```bash
ollama pull nomic-embed-text
```
5. **回填嵌入:**
```bash
bin/rails embeddings:backfill
```
6. **启动开发服务器:**
```bash
bin/dev
```
## 设置MCP客户端
### 光标
编辑Cursor的`mcp.json`:
**选项A -- SSE传输(推荐Docker):**
```json
{
"mcpServers": {
"graph_mem": {
"url": "http://localhost:3030/mcp/sse"
}
}
}
```
**选项B -- stdio传输(原生开发/实时应用更改):**
```json
{
"mcpServers": {
"graph_mem": {
"command": "/bin/bash",
"args": ["/绝对路径/to/graph_mem/bin/mcp_graph_mem_runner.sh"],
"env": { "RAILS_ENV": "development" }
}
}
}
```
**选项C -- 通过Docker的stdio:**
```json
{
"mcpServers": {
"graph_mem": {
"command": "/bin/bash",
"args": ["/绝对路径/to/graph_mem/bin/docker-mcp"]
}
}
}
```
### 风暴
编辑Windsurf的`mcp_config.json`使用与Cursor的`mcp.json`类似的方法。通常SSE容器不会产生任何问题。
### 反重力
SSE不适用于反重力 - 反重力使用较新的Streamable HTTP传输(POST/DELETE直接发送到serverUrl),而当前的FastMCP gem(v1.6.0)仅支持较旧的SSE双端协议(GET /sse + POST /messages)。但stdio工作正常。
假设`graph_mem-app-1`是正在运行的容器名称,请编辑`mcp_servers.json`:
```json
{
"mcpServers": {
"graph_mem": {
"command": "/usr/bin/docker",
"args": [
"exec",
"-i",
"graph_mem-app-1",
"bash",
"-c",
"'bin/bundle exec ruby bin/mcp_stdio_runner.rb'"
// 开发时,请更改下面的env并将命令替换为bash,第一个参数"-c"和第二个参数:
// "cd /home/steve/Projects/graph_mem && exec /usr/share/rvm/wrappers/ruby-3.4.1@graph_mem/bundle exec ruby bin/mcp_stdio_runner.rb"
],
"env": {
"RAILS_ENV": "production"
}
}
}
}
```
### 克劳德代码
通常,stdio和SSE都应该有效,因为所有3个选项都突出显示。
编辑Claude的`mcp_servers.json`并选择其中一个。
### 局域网访问(多台机器)
参见[架构](docs/architecture.md)以获取详细信息。
请记住,当前版本的GraphMem专门为单用户使用而设计,即每个安装程序仅限1个AI用户:目前每个对话都没有会话存储,因此多个AI代理连接并使用同一个正在运行的GraphMem实例可能会相互覆盖工作(如果有人重置另一个人的上下文阀门,则可能会阻止“上下文阀门”按预期工作,从而导致上下文膨胀)。
但是,什么也不阻止您在生成的内存图谱之间共享相同的内存图谱,只要GraphMem将由单个AI用户一次使用。
因此,当在本地服务器上运行GraphMem并从LAN上的其他机器访问时:
**1. 在运行主机上公开Ollama**
默认情况下,Ollama仅侦听`127.0.0.1`。创建systemd drop-in覆盖(在Ollama软件包升级后存活):
```bash
sudo mkdir -p /etc/systemd/system/ollama.service.d
echo '[Service]
Environment="OLLAMA_HOST=0.0.0.0"' | sudo tee /etc/systemd/system/ollama.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart ollama```
验证它绑定到所有接口:
```bash
ss -tlnp | grep 11434
# 应该显示*:11434而不是127.0.0.1:11434
```
**2. 配置OLLAMA_URL**
在运行GraphMem的主机上,`OLLAMA_URL=http://localhost:11434`(默认值)有效
因为`app`容器使用主机网络。
如果Ollama在另一个**不同**的机器上运行,请在`.env`中设置:
```
OLLAMA_URL=http://<ollama-host-ip>:11434
```
**3. 从其他LAN机器连接MCP客户端**
指向工作站的SSE端点:
```json
{ "url": "http://<workstation-ip>:3030/mcp/sse" }
```
## 嵌入管理
### 操作员仪表盘
在`/operator/login`登录后,打开**嵌入**,从首页仪表盘或前往`/operator/embeddings`。该页面显示覆盖率、索引状态、解析配置(带有源徽章:应用设置/ENV/默认值)、连接测试、回填/再生作业和添加/删除ANN索引操作。
嵌入服务设置位于**系统设置 → 嵌入**(`/operator/settings?tab=embeddings`)。配置按以下顺序解析:
| 优先级 | 源 |
|---|---|
| 1 | 应用设置(操作员UI)- 空字符串或`0`维度默认为ENV |
| 2 | 环境变量(`OLLAMA_URL`, `EMBEDDING_MODEL`, `EMBEDDING_PROVIDER`, `EMBEDDING_DIMS`)|
| 3 | 内置默认值(`http://localhost:11434`, `nomic-embed-text`, `ollama`, 768) |
ENV变量仍然是Docker和部署清单的正确选择;UI覆盖它们时,它们会生效。启用**计划回填**以运行`EmbeddingScheduledBackfillJob`每天(参见`config/recurring.yml`)。查看 [docs/operator/embeddings.md](docs/operator/embeddings.md)以获取推荐的操作员工作流。
### 测试Ollama连接
在回填或再生嵌入之前,请验证应用程序是否可以访问您的Ollama实例:
```bash
# Docker
docker compose exec app bin/rails embeddings:check
# 原生开发
bin/rails embeddings:check
```
发送单个测试嵌入通过`EmbeddingService`使用解析配置(应用设置→ENV→默认值)
```bash
# 校验Ollama是否可达并列出可用模型
docker compose exec app curl -sf http://localhost:11434/api/tags
# 测试原始嵌入请求
docker compose exec app curl -sf http://localhost:11434/api/embed \
-d '{"model":"nomic-embed-text","input":"hello"}'
```
### Rake 任务
| 任务 | 描述 |
|---|---|
| `embeddings:check` | 烟雾测试Ollama连接性和配置 |
| `embeddings:backfill` | 为缺少嵌入的记录生成嵌入 |
| `embeddings:regenerate` | 就地重新计算所有嵌入(例如,在切换模型后) |
| `embeddings:add_indexes` | 在所有行都填充完毕后添加`VECTOR INDEX`(HNSW,余弦) |
| `embeddings:drop_indexes` | 删除索引并恢复列为可空 |
### 切换嵌入模型
要更改模型(例如,从`nomic-embed-text`更改为其他模型):
1. 在Ollama主机上拉取新模型:`ollama pull <model-name>`
2. 在**系统设置 → 嵌入**或通过`.env`中的`EMBEDDING_MODEL` / `EMBEDDING_DIMS`更新模型(如果不同)
3. 验证连接性:`bin/rails embeddings:check`或操作员**测试连接**按钮
4. 重新计算所有向量:`bin/rails embeddings:regenerate`或操作员**重新生成所有**操作
## 数据库备份和恢复
备份由**系统设置**(`/operator/settings`, 会话登录)和rake任务管理。转储按时间戳、环境范围进行,并根据`backup_keep_max`保留:
```bash
# Dump current database to <backup_folder>/<YYYYMMDDHHMM>_<env>.sql.bz2
bin/rails db:dump
# List backups for the current environment
bin/rails db:list_backups
# Restore from newest backup, or a specific file
bin/rails db:restore
FILE=202601011200_production.sql.bz2 bin/rails db:restore
```
Solid Queue中的`DatabaseBackupJob`(当系统设置中的**启用计划备份**开启时)会定时运行备份计划。生产计划:1pm和5pm GMT(`config/recurring.yml`)。使用操作员仪表盘中的**作业**查看队列状态。
在`/operator/login`登录。操作员凭证:`operator` / `changeme`(用`OPERATOR_USERNAME` / `OPERATOR_PASSWORD`或Rails凭证下的`operator:`覆盖)。
## 环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
| `OLLAMA_URL` | `http://localhost:11434` | Ollama API基准URL(被应用设置中的`embedding_url`覆盖时有效) |
| `EMBEDDING_MODEL` | `nomic-embed-text` | Ollama嵌入模型名称 |
| `EMBEDDING_PROVIDER` | `ollama` | `ollama`或`openai_compatible` |
| `EMBEDDING_DIMS` | `768` | 向量维度(必须与模型匹配) |
| `DB_PASSWORD` | `my_password` | MariaDB root密码 |
| `DB_NAME` | `graph_mem` | 数据库名称 |
| `DB_PORT` | `3307` | MariaDB主机端口(Docker) |
| `RAILS_MASTER_KEY` | -- | Rails凭证密钥(Docker需要) |
| `DATABASE_URL` | -- | 完整的数据库URL(覆盖单个数据库设置) |
| `DB_BACKUP_HOST_PATH` | `./db/backup` | 数据库备份文件夹的完整路径(默认为无效:docker-compose不会展开特殊字符) |
| `OPERATOR_USERNAME` | `operator` | 操作员登录用户名 |
| `OPERATOR_PASSWORD` | `changeme` | 操作员登录密码(生产环境请更改) |
## 文档
* [操作员嵌入指南](docs/operator/embeddings.md)
* [MCP工具参考](docs/mcp_tools.md)
* [应用设置参考](docs/app_settings_reference.md)
* [架构](docs/architecture.md)
* [开发指南](docs/development.md)
* [故障排除](docs/troubleshooting.md)
* [内存实体资源](docs/memory_entity_resource.md)
* [内存观察资源](docs/memory_observation_resource.md)
* [内存关系资源](docs/memory_relation_resource.md)
* [内存图资源](docs/memory_graph_resource.md)
## 贡献
欢迎提交拉取请求。对于重大更改,请先打开一个问题来讨论您想要更改的内容。请确保根据需要更新测试。没有适当测试用例的拉取请求不会被接受。
## 许可证
该项目作为开源软件在[LGPL-3.0 License](https://opensource.org/licenses/LGPL-3.0)许可下提供。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器