Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 200 additions & 0 deletions .github/workflows/hugegraph-mcp.yml
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 thread
UIengF marked this conversation as resolved.
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
Comment thread
UIengF marked this conversation as resolved.
4 changes: 2 additions & 2 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:

- name: Install dev dependencies
run: |
uv sync --extra dev
uv sync --extra dev --extra llm --extra python-client

- name: Check code formatting with Ruff
run: |
Expand Down Expand Up @@ -88,4 +88,4 @@ jobs:
run: uv run ty check hugegraph-llm/src hugegraph-python-client/src
continue-on-error: true
# TODO: extend scope to hugegraph-ml once heavy optional deps (DGL, PyTorch) are handled
# TODO: add graph-mcp once the module is introduced
# TODO: add graph-mcp after its type-check baseline is established
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ MANIFEST
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Exception: allow .spec/ directory to be tracked
!.spec/
!.spec/**

# Installer logs
pip-log.txt
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

- Python 3.10+ (required for hugegraph-llm)
- [uv](https://docs.astral.sh/uv/) 0.7+ (required for workspace management)
- HugeGraph Server 1.3+ (1.5+ recommended)
- HugeGraph Server 1.3+ for the LLM/client modules (1.5+ recommended); `hugegraph-mcp` requires 1.7.0+
- Docker (optional, for containerized deployment)

### Option 1: Docker Deployment (Recommended)
Expand All @@ -44,6 +44,11 @@ docker compose -f docker-compose-network.yml up -d
# - RAG Service: http://localhost:8001
```

The RAG service is published on the host port by default, and the HTTP API is unauthenticated by default. Before
using this deployment outside a trusted local environment, either enable the built-in Bearer authentication with
`ENABLE_LOGIN=true` and a strong, non-default `USER_TOKEN`, or configure reverse proxy authentication. Also restrict
access with a firewall or trusted network.

### Option 2: Source Installation

```bash
Expand All @@ -59,6 +64,7 @@ cd hugegraph-ai
# NOTE: If download is slow, uncomment mirror lines in pyproject.toml or use: uv config --global index.url https://pypi.tuna.tsinghua.edu.cn/simple
# Or create local uv.toml with mirror settings to avoid git diff (see uv.toml example in root)
uv sync --extra llm # Install LLM-specific dependencies
# For HugeGraph MCP, use: uv sync --extra mcp --extra dev
# Or install all optional dependencies: uv sync --all-extras

# 4. Activate virtual environment (recommended for easier commands)
Expand All @@ -70,6 +76,8 @@ python -m hugegraph_llm.demo.rag_demo.app
# Visit http://127.0.0.1:8001
```

The source launcher binds to `127.0.0.1` by default and warns when a non-loopback `--host` is selected.

### Basic Usage Examples

> [!NOTE]
Expand Down Expand Up @@ -98,6 +106,14 @@ Large language model integration for graph applications:
- **Natural Language Interface**: Query graphs using natural language
- **AI Agents**: Intelligent graph analysis and reasoning

### [hugegraph-mcp](./hugegraph-mcp)

Model Context Protocol server for safe, controlled HugeGraph access:

- **Stable Tool Contract**: Typed graph, schema, Gremlin, and extraction tools for MCP clients
- **Safe Writes**: Read-only defaults plus dry-run, persistent single-use confirmation, and target revalidation
- **Compatibility**: Default `v2_core` toolset with an opt-in `v1` compatibility mode

### [hugegraph-ml](./hugegraph-ml)

Graph machine learning with 20+ implemented algorithms:
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose-network.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ networks:
services:
# HugeGraph Server
hugegraph-server:
image: hugegraph/hugegraph
image: hugegraph/hugegraph:1.7.0
container_name: server
restart: unless-stopped
ports:
Expand Down
51 changes: 33 additions & 18 deletions hugegraph-llm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ docker-compose -f docker-compose-network.yml ps
# RAG Service: http://localhost:8001
```

The Compose configuration publishes the RAG service only on the host loopback interface by default.

### Option 2: Individual Docker Containers

For more control over individual components:
Expand All @@ -80,7 +82,7 @@ docker run -itd --name=server -p 8080:8080 --network hugegraph-net hugegraph/hug
docker pull hugegraph/rag:latest
docker run -itd --name rag \
-v /path/to/your/hugegraph-llm/.env:/home/work/hugegraph-llm/.env \
-p 8001:8001 --network hugegraph-net hugegraph/rag
-p 127.0.0.1:8001:8001 --network hugegraph-net hugegraph/rag

# 4. Monitor logs
docker logs -f rag
Expand Down Expand Up @@ -117,6 +119,12 @@ python -m hugegraph_llm.demo.rag_demo.app
python -m hugegraph_llm.demo.rag_demo.app --host 127.0.0.1 --port 18001
```

The Docker deployment publishes the RAG service on the host port by default, and the HTTP API is unauthenticated by
default. Before using this deployment outside a trusted local environment, either enable the built-in Bearer
authentication with `ENABLE_LOGIN=true` and a strong, non-default `USER_TOKEN`, or configure reverse proxy
authentication. Also restrict access with a firewall or trusted network. The source launcher can still be bound to
loopback explicitly with `--host 127.0.0.1`.

#### Additional Setup (Optional)

> [!NOTE]
Expand Down Expand Up @@ -181,6 +189,16 @@ The system supports both English and Chinese prompts. To switch languages:
> [!NOTE]
> Configuration changes are automatically saved when using the web interface. For manual changes, simply refresh the page to load updates.

### Legacy Thin API writes

The compatibility endpoints `POST /graph-import` and
`POST /vid-embeddings/refresh` are disabled by default. They are intended only
for authenticated internal callers. To enable them, set `ENABLE_LOGIN=true`,
replace the default `USER_TOKEN=4321` with a strong random secret, and set
`HUGEGRAPH_LLM_ENABLE_THIN_WRITES=true`. Send the configured `USER_TOKEN` as a
Bearer token. Prefer the HugeGraph MCP guarded write tools for user-facing
workflows.

**LLM Provider Support**: This project uses [LiteLLM](https://docs.litellm.ai/docs/providers) for multi-provider LLM support.

### Programmatic Examples (new workflow engine)
Expand All @@ -194,13 +212,13 @@ from hugegraph_llm.flows.scheduler import SchedulerSingleton

scheduler = SchedulerSingleton.get_instance()
res = scheduler.schedule_flow(
"rag_graph_only",
query="Tell me about Al Pacino.",
graph_only_answer=True,
vector_only_answer=False,
raw_answer=False,
gremlin_tmpl_num=-1,
gremlin_prompt=None,
"rag_graph_only",
query="Tell me about Al Pacino.",
graph_only_answer=True,
vector_only_answer=False,
raw_answer=False,
gremlin_tmpl_num=-1,
gremlin_prompt=None,
)

print(res.get("graph_only_answer"))
Expand All @@ -213,10 +231,7 @@ from hugegraph_llm.flows.scheduler import SchedulerSingleton

scheduler = SchedulerSingleton.get_instance()
res = scheduler.schedule_flow(
"rag_vector_only",
query="Summarize the career of Ada Lovelace.",
vector_only_answer=True,
vector_search=True
"rag_vector_only", query="Summarize the career of Ada Lovelace.", vector_only_answer=True, vector_search=True
)

print(res.get("vector_only_answer"))
Expand All @@ -229,12 +244,12 @@ from hugegraph_llm.flows.scheduler import SchedulerSingleton

scheduler = SchedulerSingleton.get_instance()
response = scheduler.schedule_flow(
"text2gremlin",
"find people who worked with Alan Turing",
2, # example_num
"hugegraph", # schema_input (graph name or schema)
None, # gremlin_prompt_input (optional)
["template_gremlin", "raw_gremlin"],
"text2gremlin",
"find people who worked with Alan Turing",
2, # example_num
"hugegraph", # schema_input (graph name or schema)
None, # gremlin_prompt_input (optional)
["template_gremlin", "raw_gremlin"],
)

print(response.get("template_gremlin"))
Expand Down
2 changes: 1 addition & 1 deletion hugegraph-llm/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ extend-exclude = []

# TODO: move this config in the root pyproject.toml & add more rules for it
[tool.ruff.lint]
extend-select = ["I"]
select = ["E4", "E7", "E9", "F", "I"]

[tool.ruff.format]
quote-style = "preserve"
Expand Down
Loading
Loading