forked from apache/hugegraph-ai
-
Notifications
You must be signed in to change notification settings - Fork 5
feat(mcp): Add HugeGraph MCP server #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
UIengF
wants to merge
13
commits into
main
Choose a base branch
from
graph-mcp
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
843355a
feat(mcp): add HugeGraph MCP V1 core and guarded workflows
ef6c70c
chore(mcp): add V1 tests, docs, skills, and CI
3dedc6b
feat(mcp): add and harden P0a graph toolset
8dac401
fix(mcp): complete remaining defect hardening
6911886
fix(mcp): align public contract and documentation
25700ff
style(mcp): preserve module import grouping
1f53172
fix(mcp): close review safety and schema gaps
34c1252
fix(mcp): gate AI before schema resolution
49244cd
Merge branch 'main' into graph-mcp
imbajin 47ee602
style(mcp): satisfy CI lint checks
b67e9e1
style: format markdown code examples
db59551
ci: stabilize Ruff lint selection
8337d45
fix(mcp): clarify validation and usage
imbajin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| # | ||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
| # | ||
|
|
||
| name: HugeGraph-MCP CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - "main" | ||
| - "release-*" | ||
| paths: | ||
| - "hugegraph-mcp/**" | ||
| - "hugegraph-python-client/**" | ||
| - "pyproject.toml" | ||
| - "uv.lock" | ||
| - ".github/workflows/hugegraph-mcp.yml" | ||
| pull_request: | ||
| paths: | ||
| - "hugegraph-mcp/**" | ||
| - "hugegraph-python-client/**" | ||
| - "pyproject.toml" | ||
| - "uv.lock" | ||
| - ".github/workflows/hugegraph-mcp.yml" | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.10", "3.11", "3.12"] | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Python ${{ matrix.python-version }} | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
|
|
||
| - name: Install uv | ||
| run: | | ||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||
|
|
||
| - name: Cache dependencies | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| ~/.cache/uv | ||
| key: ${{ runner.os }}-mcp-uv-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml', 'uv.lock') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-mcp-uv-${{ matrix.python-version }}- | ||
|
|
||
| - name: Install MCP dependencies | ||
| run: | | ||
| # The root workspace includes hugegraph-llm (<3.12). Install the | ||
| # MCP packages directly so every matrix entry exercises its stated | ||
| # interpreter instead of silently falling back to Python 3.11. | ||
| uv venv --python "${{ matrix.python-version }}" .mcp-venv | ||
| uv pip install --python .mcp-venv/bin/python \ | ||
| -e ./hugegraph-python-client \ | ||
| -e ./hugegraph-mcp \ | ||
| "pytest~=8.0.0" \ | ||
| "ruff>=0.11.0" | ||
| .mcp-venv/bin/python --version | ||
|
|
||
| - name: Verify isolated wheel install | ||
| if: matrix.python-version == '3.10' | ||
| run: | | ||
| rm -rf wheelhouse isolated-mcp-venv | ||
| uv build --wheel --out-dir wheelhouse hugegraph-python-client | ||
| uv build --wheel --out-dir wheelhouse hugegraph-mcp | ||
| python -m venv isolated-mcp-venv | ||
| isolated-mcp-venv/bin/python -m pip install \ | ||
| --find-links wheelhouse \ | ||
| wheelhouse/hugegraph_python_client-*.whl \ | ||
| wheelhouse/hugegraph_mcp-*.whl | ||
| isolated-mcp-venv/bin/python - <<'PY' | ||
| from importlib.metadata import version | ||
| from types import SimpleNamespace | ||
| from unittest.mock import Mock | ||
|
|
||
| import hugegraph_mcp | ||
| import pyhugegraph | ||
| from hugegraph_mcp.server import main | ||
| from pyhugegraph.api.auth import AuthManager | ||
| from pyhugegraph.utils.huge_config import HGraphConfig | ||
| from pyhugegraph.utils.huge_requests import HGraphSession | ||
|
|
||
| assert version("hugegraph-python-client") == "1.7.0" | ||
| assert version("hugegraph-mcp") == "0.1.0" | ||
|
|
||
| class CaptureSession: | ||
| cfg = SimpleNamespace(graphspace="GS", gs_supported=True) | ||
|
|
||
| def request(self, path, method="GET", **_kwargs): | ||
| self.path = path | ||
| return {"ok": True} | ||
|
|
||
| capture = CaptureSession() | ||
| AuthManager(capture).list_users() | ||
| assert capture.path == "/graphspaces/GS/auth/users" | ||
|
|
||
| config = HGraphConfig( | ||
| "http://127.0.0.1:8080", "admin", "pwd", "g", graphspace="GS" | ||
| ) | ||
| session = HGraphSession(config, session=Mock()) | ||
| assert session.resolve("schema") == ( | ||
| "http://127.0.0.1:8080/graphspaces/GS/graphs/g/schema" | ||
| ) | ||
| PY | ||
|
|
||
| - name: Check MCP formatting | ||
| run: | | ||
| .mcp-venv/bin/ruff format --check hugegraph-mcp/hugegraph_mcp hugegraph-mcp/tests | ||
|
|
||
| - name: Lint MCP | ||
| run: | | ||
| .mcp-venv/bin/ruff check hugegraph-mcp/hugegraph_mcp hugegraph-mcp/tests | ||
|
|
||
| - name: Run MCP tests | ||
| run: | | ||
| .mcp-venv/bin/python -m pytest hugegraph-mcp -m "not live and not integration and not llm" | ||
|
|
||
| real-hugegraph-write-path: | ||
|
Comment on lines
+46
to
+147
|
||
| runs-on: ubuntu-latest | ||
| services: | ||
| hugegraph: | ||
| image: hugegraph/hugegraph:1.7.0 | ||
| env: | ||
| PASSWORD: admin | ||
| options: >- | ||
| --health-cmd="curl -f http://localhost:8080/versions || exit 1" | ||
| --health-interval=10s | ||
| --health-timeout=5s | ||
| --health-retries=12 | ||
| ports: | ||
| - 8080:8080 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Python 3.10 | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.10" | ||
|
|
||
| - name: Install uv | ||
| run: | | ||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||
|
|
||
| - name: Cache dependencies | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| ~/.cache/uv | ||
| key: ${{ runner.os }}-mcp-real-hugegraph-uv-${{ hashFiles('**/pyproject.toml', 'uv.lock') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-mcp-real-hugegraph-uv- | ||
|
|
||
| - name: Install MCP dependencies | ||
| run: | | ||
| uv sync --extra mcp --extra dev | ||
|
|
||
| - name: Run real HugeGraph write-path tests | ||
| working-directory: hugegraph-mcp | ||
| env: | ||
| RUN_MCP_REAL_HUGEGRAPH_TESTS: "1" | ||
| HUGEGRAPH_URL: http://127.0.0.1:8080 | ||
| HUGEGRAPH_GRAPH_PATH: DEFAULT/hugegraph | ||
| HUGEGRAPH_USER: admin | ||
| HUGEGRAPH_PASSWORD: admin | ||
| HUGEGRAPH_MCP_READONLY: "false" | ||
| HUGEGRAPH_MCP_ALLOW_AI: "false" | ||
| run: | | ||
| uv run pytest tests/integration/test_real_write_path.py -m real_hugegraph | ||
|
Copilot marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| # HugeGraph MCP 需求 | ||
|
|
||
| ## 1. 范围与边界 | ||
|
|
||
| HugeGraph MCP 是独立的 `hugegraph-mcp` Python 包,通过 FastMCP 的 stdio | ||
| transport 向 MCP 客户端提供 HugeGraph 与 HugeGraph-AI 能力。它是薄适配层, | ||
| 不复制 HugeGraph 或 HugeGraph-AI 的业务内核。 | ||
|
|
||
| 本版本只要求 MCP tools,不提供 MCP resources、HTTP/SSE transport 或内置图算法。 | ||
| 服务通过 `hugegraph-mcp` 命令启动,运行时配置全部来自环境变量。 | ||
|
|
||
| 验收标准: | ||
|
|
||
| 1. `uv run --project hugegraph-mcp hugegraph-mcp` 能启动 stdio MCP 服务。 | ||
| 2. 服务连接 HugeGraph Server 1.7.0 或更高版本,并支持 graphspace 路由。 | ||
| 3. 高层工具返回统一 envelope,至少包含 `ok`、`data`、`error`、 | ||
| `warnings`、`next_actions` 和 `meta`。 | ||
| 4. 连接、权限、校验和执行错误转换为结构化错误,不向客户端暴露未处理异常。 | ||
|
|
||
| ## 2. 对外工具契约 | ||
|
|
||
| 默认工具集是 `v2_core`,共注册 13 个工具: | ||
|
|
||
| - 普通工具:`inspect_graph_tool`、`inspect_schema_tool`、 | ||
| `query_graph_data_tool`、`generate_gremlin_tool`、 | ||
| `execute_gremlin_read_tool`、`extract_graph_data_tool`、 | ||
| `design_schema_tool`、`apply_schema_tool`、 | ||
| `mutate_graph_properties_tool`、`import_graph_data_tool`、 | ||
| `delete_graph_data_tool` | ||
| - 默认受管理模式阻断的工具:`execute_gremlin_write_tool`、 | ||
| `refresh_vid_embeddings_tool` | ||
|
|
||
| `HUGEGRAPH_MCP_TOOLSET=v1` 提供 10 工具兼容模式:隐藏 | ||
| `inspect_schema_tool`、`query_graph_data_tool` 和 | ||
| `mutate_graph_properties_tool`,同时禁止 | ||
| `apply_schema_tool(mode="apply")`。未设置或设置为除精确 `v1` 之外的值时, | ||
| 使用 `v2_core`。工具集在进程启动时确定。 | ||
|
|
||
| 验收标准: | ||
|
|
||
| 1. `tools/list` 在默认配置下返回准确的 13 工具集合。 | ||
| 2. `HUGEGRAPH_MCP_TOOLSET=v1` 时返回准确的 10 工具集合。 | ||
| 3. `inspect_graph_tool` 返回 `mcp_tool_contract_version=2.0` 和当前 | ||
| `toolset`。 | ||
| 4. 原内部聚合接口 `query_graph_tool`、`manage_schema_tool` 和 | ||
| `manage_graph_data_tool` 不作为 MCP 工具注册。 | ||
|
|
||
| ## 3. 读取与 AI 能力 | ||
|
|
||
| 读取能力必须是有边界且可审计的: | ||
|
|
||
| 1. `inspect_graph_tool` 返回服务状态、schema 摘要、数据计数、readonly 与 | ||
| AI 可用状态。 | ||
| 2. `inspect_schema_tool` 返回 schema 对象、关系和索引标签,并支持类型和名称 | ||
| 过滤。 | ||
| 3. `query_graph_data_tool` 只提供类型化的点边查询和显式 limit,不以 Gremlin | ||
| 全图扫描作为隐式回退。 | ||
| 4. `execute_gremlin_read_tool` 在执行前进行保守只读校验;无法确认只读时拒绝。 | ||
| 5. `generate_gremlin_tool` 默认只生成查询;请求执行时仍必须通过只读校验。 | ||
| 6. HugeGraph-AI 调用仅在 `HUGEGRAPH_MCP_ALLOW_AI=true` 时允许;生成和抽取 | ||
| 结果本身不得隐式写图。 | ||
|
|
||
| ## 4. 普通写操作安全 | ||
|
|
||
| `import_graph_data_tool`、`delete_graph_data_tool`、 | ||
| `mutate_graph_properties_tool` 和 schema apply 的真实写入必须遵循: | ||
|
|
||
| `dry_run -> 审查 preview -> plan_hash/nonce/expires_at -> confirm -> 重验 -> 写入` | ||
|
|
||
| 验收标准: | ||
|
|
||
| 1. 默认 `HUGEGRAPH_MCP_READONLY=true`;只读模式下 preview 不可确认,真实写入 | ||
| 被拒绝。 | ||
| 2. `plan_hash` 绑定工具、mode、目标 URL、graphspace、graph、readonly、 | ||
| payload digest、nonce、过期时间,以及适用时的 live schema 或目标快照。 | ||
| 3. confirm 只接受由服务端 dry-run 签发且仍有效的相同计划;payload、目标、 | ||
| schema、权限或连接目标变化时拒绝。 | ||
| 4. 服务使用 `HUGEGRAPH_MCP_STATE_DIR` 下的 SQLite 确认账本持久化签发计划和 | ||
| 已消费 nonce 摘要,在首次写副作用前原子消费。 | ||
| 5. 相同计划跨进程重启以及共享状态目录的 worker 之间最多使用一次;状态目录 | ||
| 不可安全写入时 fail closed。 | ||
| 6. 删除只支持精确点或边目标,不支持条件批量或级联删除;点有关联边时拒绝。 | ||
| 7. 批量写入发生部分成功时返回 `partial` 或等价结构化错误,并给出已执行项、 | ||
| 失败项和恢复建议。 | ||
|
|
||
| `execute_gremlin_write_tool` 是唯一 break-glass 例外,不使用上述确认链。 | ||
| 它必须同时满足 `HUGEGRAPH_MCP_ADMIN_MODE=true` 和 | ||
| `HUGEGRAPH_MCP_READONLY=false`,并只应部署在隔离的可信管理 transport。 | ||
|
|
||
| ## 5. Schema 管理 | ||
|
|
||
| `design_schema_tool` 只提供设计建议。`apply_schema_tool` 支持 | ||
| `design`、`validate`、`dry_run` 和 `apply` mode。 | ||
|
|
||
| 验收标准: | ||
|
|
||
| 1. `v2_core` 的确认 apply 只允许 `create_property_key`、 | ||
| `create_vertex_label` 和 `create_edge_label`。 | ||
| 2. `create_index_label` 可以使用 `validate` 校验,但 P0a `dry_run` 和真实 | ||
| `apply` 必须拒绝。 | ||
| 3. remove、drop、append、eliminate、rebuild 及其他破坏性 schema 操作必须拒绝。 | ||
| 4. 同批依赖按实际 apply 顺序校验;失败后不得谎报全量成功。 | ||
| 5. `v1` 中 `validate` 和 `dry_run` 保持兼容,真实 `apply` 返回 | ||
| `FEATURE_DISABLED`。 | ||
|
|
||
| ## 6. 配置与安全默认值 | ||
|
|
||
| 必须支持 README 中列出的 HugeGraph、HugeGraph-AI、toolset、readonly、 | ||
| admin、timeout 和 state directory 环境变量。 | ||
|
|
||
| 验收标准: | ||
|
|
||
| 1. Boolean 仅接受忽略大小写和首尾空白的 `1/true/yes/on` 与 | ||
| `0/false/no/off`。 | ||
| 2. 空值或非法 boolean 发出 warning 并使用安全默认值:readonly 开启,AI 和 | ||
| admin 关闭。 | ||
| 3. 状态目录优先级为 `HUGEGRAPH_MCP_STATE_DIR`、 | ||
| `$XDG_STATE_HOME/hugegraph-mcp`、`~/.local/state/hugegraph-mcp`。 | ||
| 4. POSIX 上状态目录权限为 `0700`,账本文件权限为 `0600`。 | ||
| 5. 密码、token、Authorization header 和其他敏感字段不得出现在 envelope、 | ||
| warning 或错误详情中。 | ||
|
|
||
| ## 7. 验证 | ||
|
|
||
| 1. `uv run --project hugegraph-mcp pytest hugegraph-mcp/tests -m "not integration and not live and not real_hugegraph and not llm"` | ||
| 通过。 | ||
| 2. `uv run --directory hugegraph-mcp ruff format --check hugegraph_mcp tests` | ||
| 通过。 | ||
| 3. 在一次性 HugeGraph 1.7.0+ 图上按 | ||
| `hugegraph-mcp/docs/p0a-integration-checklist.md` 验证真实 create-only | ||
| schema apply、数据写入/读取/属性变更/删除及 replay 拒绝。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.