grip-protocol 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: grip-protocol
3
+ Version: 0.1.0
4
+ Summary: Universal GraphRAG Interoperability Protocol (GRIP) — 27-tool MCP server, verifiable provenance, and standard contracts for knowledge graph RAG
5
+ Author: graphrag-protocol contributors
6
+ License: MIT
7
+ Keywords: graphrag,knowledge-graph,mcp,retrieval,graph,protocol,rag
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: pydantic>=2
19
+ Requires-Dist: python-dotenv
20
+ Requires-Dist: mcp>=2
21
+ Requires-Dist: fastapi
22
+ Requires-Dist: uvicorn
23
+ Requires-Dist: httpx
24
+ Provides-Extra: tigergraph
25
+ Requires-Dist: pyTigerGraph; extra == "tigergraph"
26
+ Provides-Extra: llm
27
+ Requires-Dist: google-genai; extra == "llm"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: ruff; extra == "dev"
31
+ Requires-Dist: mypy; extra == "dev"
32
+ Provides-Extra: rag
33
+ Requires-Dist: chromadb; extra == "rag"
34
+ Provides-Extra: eval
35
+ Requires-Dist: bert-score; extra == "eval"
36
+ Provides-Extra: all
37
+ Requires-Dist: pyTigerGraph; extra == "all"
38
+ Requires-Dist: google-genai; extra == "all"
39
+ Requires-Dist: chromadb; extra == "all"
40
+ Requires-Dist: bert-score; extra == "all"
41
+
42
+ # GraphRAG Protocol
43
+
44
+ **Universal GraphRAG Interoperability Protocol** — standard contracts + MCP server + adapters so *any agent can query any GraphRAG backend uniformly*.
45
+
46
+ Every GraphRAG engine (TigerGraph, Neo4j, LightRAG, LlamaIndex, FalkorDB, Microsoft GraphRAG) reinvents retrieval, subgraph serialization, provenance, and evaluation with incompatible interfaces. This protocol fills the missing middle layer between **GQL** (graph query standard at the bottom) and **MCP** (agent connectivity standard at the top): a uniform retrieval contract any backend can implement and any agent can call.
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ # 1. Create and activate a virtual environment
52
+ python -m venv .venv
53
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
54
+
55
+ # 2. Install the package (with dev dependencies)
56
+ pip install -e ".[dev]"
57
+
58
+ # 3. Copy the env template and fill in your backend credentials
59
+ cp .env.example .env
60
+ # E.g. TIGERGRAPH_HOST, TIGERGRAPH_GSQL_SECRET, GOOGLE_API_KEY
61
+
62
+ # 4. Inspect the protocol types
63
+ python -c "from mcp_server.protocol import SubgraphContext, RetrievalRequest; print('protocol OK')"
64
+
65
+ # 5. Start the MCP server (stdio transport — what agents launch)
66
+ python -m mcp_server.mcp_server # or the `graphrag-mcp` entrypoint
67
+
68
+ # 6. Start the HTTP dashboard server (FastAPI, binds 127.0.0.1:8000)
69
+ python -m mcp_server.server # or the `graphrag-server` entrypoint
70
+ ```
71
+
72
+ Requires Python 3.10+. Optional extras: `pip install -e ".[server,tigergraph,llm]"`.
73
+
74
+ ## Backends
75
+
76
+ **TigerGraph (Savanna) is the only backend this project targets.** The adapter
77
+ (`mcp_server/adapters/tigergraph_adapter.py`) talks to a live workspace over
78
+ pyTigerGraph REST++ and installs its GSQL queries idempotently on first use.
79
+ `mcp_server/adapters/fallback_adapter.py` is a clearly-labeled in-memory adapter
80
+ for tests and offline development — it is read-only, never presented as
81
+ TigerGraph, and never used to fabricate an answer.
82
+
83
+ ## Ingesting documents (Contract 4)
84
+
85
+ Writes are real TigerGraph upserts and every counter in the report is measured
86
+ from the backend (`getVertexCount` before/after, existence probes per entity):
87
+
88
+ ```bash
89
+ # Self-test: ingest a document, read it back, delete it again
90
+ .venv/bin/python scripts/smoke_construction.py
91
+ ```
92
+
93
+ Write operations (ingest / update / delete) require the admin token
94
+ (Contract 10, `GRAPHRAG_ADMIN_TOKEN`); without it they fail closed with 403.
95
+ Ingestion also publishes Contract 7 events at the mutation point, which the
96
+ dashboard consumes over SSE at `/stream/events`.
97
+
98
+ ## Running the tests
99
+
100
+ ```bash
101
+ pytest # hermetic unit suite (no creds, no network)
102
+ pytest -m integration # live TigerGraph + Gemini tests (self-skip without creds)
103
+ ruff check mcp_server/ hackathon/ tests/
104
+ ```
105
+
106
+
107
+ ## The 10 Contracts
108
+
109
+ | # | Contract | What it standardizes | Implementation |
110
+ |---|----------|----------------------|----------------|
111
+ | 1 | **Retrieval** | Standard request envelope + 7 operations (`local_search`, `global_search`, `hybrid_search`, `entity_lookup`, `path_search`, `neighborhood`, `community_members`) | `contracts/retrieval.py` — done, real |
112
+ | 2 | **Subgraph Context** | Uniform response: entities, relationships, paths, communities, text chunks | `protocol.py` — done, real |
113
+ | 3 | **Schema Discovery** | Backend-agnostic schema introspection for LLM planning | `contracts/schema_discovery.py` — done, real |
114
+ | 4 | **Construction** | Document → knowledge-graph ingestion pipeline | `contracts/construction.py` — done, real writes |
115
+ | 5 | **Provenance** | Citation & audit trail, incl. entities *visited but not cited* | `contracts/provenance.py` — done, real |
116
+ | 6 | **Federation** | Query multiple graphs + transparent result merging | `contracts/federation.py` — done, real fan-out |
117
+ | 7 | **Streaming** | Real-time graph change events | `contracts/streaming.py` — done, real pub/sub + SSE |
118
+ | 8 | **Prompt Formatting** | Context → LLM-ready, token-bounded text | `formatters/` — done (`PromptFormatConfig` model + schema) |
119
+ | 9 | **Evaluation** | Standard, backend-comparable metrics | `contracts/evaluation.py` — done; judge/BERTScore `null` when unavailable |
120
+ | 10 | **Authorization** | Per-operation permission model | `contracts/authorization.py` — done, enforced on writes |
121
+
122
+ JSON Schemas for all 10 contracts live in `schemas/`; `tests/test_schemas.py`
123
+ fails if any schema drifts from its Pydantic model.
124
+
125
+ ## Repo Layout
126
+
127
+ ```
128
+ graphrag-protocol/
129
+ ├── SPEC.md # Full protocol specification
130
+ ├── schemas/ # JSON Schema definitions (language-agnostic)
131
+ │ ├── retrieval-request.json # Contract 1
132
+ │ ├── subgraph-context.json # Contract 2
133
+ │ ├── graph-schema.json # Contract 3
134
+ │ ├── ingestion-config.json # Contract 4 (+ IngestionReport, Triple)
135
+ │ ├── provenance.json # Contract 5
136
+ │ ├── federation-config.json # Contract 6
137
+ │ ├── stream-event.json # Contract 7
138
+ │ ├── prompt-format-config.json# Contract 8
139
+ │ ├── evaluation-report.json # Contract 9
140
+ │ └── access-policy.json # Contract 10
141
+ ├── mcp_server/ # Reference implementation
142
+ │ ├── protocol.py # Canonical Pydantic v2 models (contracts 1-5, 8)
143
+ │ ├── protocol_extensions.py # Models for contracts 4, 6, 7, 9, 10
144
+ │ ├── contracts/ # Contract layer: retrieval, schema, provenance,
145
+ │ │ # construction, federation, streaming, evaluation, authorization
146
+ │ ├── adapters/ # TigerGraph (real) + labeled in-memory demo adapter
147
+ │ ├── formatters/ # Contract 8: Markdown / structured, token-bounded
148
+ │ ├── pipelines.py # Shared 3-pipeline runner (server + eval harness)
149
+ │ ├── mcp_server.py # MCP stdio server (27 tools)
150
+ │ └── server.py # FastAPI dashboard server (+ SSE event feed)
151
+ ├── frontend/ # Next.js 14 dashboard (query lab, graph, benchmark, ingest & stream)
152
+ ├── hackathon/ # TigerGraph dataset, GSQL loaders, evaluation harness
153
+ ├── scripts/ # Live smoke tests (construction, connection)
154
+ ├── tests/ # Hermetic unit suite + `integration` live tests
155
+ └── pyproject.toml
156
+ ```
157
+
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,30 @@
1
+ mcp_server/__init__.py,sha256=kpMwSBnU1MmywFOuYzWxuO82eybX1WpdDOebSUDSuQU,94
2
+ mcp_server/mcp_server.py,sha256=xCYU2GUkMneHHvHhlCKA3fd-nijTVYy3P-VXhabHbaY,24177
3
+ mcp_server/pipelines.py,sha256=mVFJYsl1AYi911DE3gLsU_RL4HbO6gFxda2067DfErU,7999
4
+ mcp_server/protocol.py,sha256=KnbOuqby_wMGvggFY4Nwi2CL6GrRug45TzYDDQD0bKU,13787
5
+ mcp_server/protocol_extensions.py,sha256=U53EljUeUjjLBTb_4hrHw9SZQ4rwbKnmnJvUnVfhvyc,10826
6
+ mcp_server/server.py,sha256=gKpqluEZzIkFJBaarsWD75KpHCtiX9NvKmLhDj-CTDM,12971
7
+ mcp_server/adapters/__init__.py,sha256=boO8TkJwBHEv1209ppF6P2IAN-tmJqVVcQClvZD9YvU,267
8
+ mcp_server/adapters/base.py,sha256=jjg_Kg53X388KVGqaxmljFswBLqtD2hu3Vv1S80Q7dQ,3580
9
+ mcp_server/adapters/fallback_adapter.py,sha256=CDcz82f37hvkM4f5X1VvEWGiXYsfzTGnv9g7rNv2FUo,13387
10
+ mcp_server/adapters/tigergraph_adapter.py,sha256=mrSu59f_aV2BmNKDSBDWIxV8rkTZaV0XYrjKPnvq470,44193
11
+ mcp_server/adapters/tigergraph_queries.py,sha256=CYN6IvV06CS70QwtXqVa_fmQtxeOK--2VSuzZfscQmE,9942
12
+ mcp_server/contracts/__init__.py,sha256=U7JJV7niqf8D9QyjoEqbOcOMM9y56KpfmD5LJbIwC9A,1226
13
+ mcp_server/contracts/authorization.py,sha256=6bPJen-Dk8cNmKhvPZvUZU4bxzHw9WtIYBw9qxMxIb0,5483
14
+ mcp_server/contracts/base.py,sha256=9ah8F_-hYnMSsaYhcuJHnSWLy93Hbr_cwkXNd215dwE,6464
15
+ mcp_server/contracts/construction.py,sha256=ahxzruDEbZjJbroSSNjxqKY0dVcgbyD2r33LO0GJk6M,23159
16
+ mcp_server/contracts/evaluation.py,sha256=fv9JsA_KJcySrCE6yB4I0raR_9Y1yLwQ7jvxB6rip7A,14779
17
+ mcp_server/contracts/federation.py,sha256=V759uY_bWmkLAXO67mUbPMcaO4JHOj0cPziGWFwP5e8,16433
18
+ mcp_server/contracts/provenance.py,sha256=iHFxWPOEnsjgIs5cvqrXR6qP0bzwv3cS_OCFfo4oimo,10253
19
+ mcp_server/contracts/retrieval.py,sha256=7klYU3gl738-tewd9A2SEp3omi2bXwa1M6z-k2ABRBY,18922
20
+ mcp_server/contracts/schema_discovery.py,sha256=vIDFAdsDLkdfhhm0PkRUEkb1lrTfRkdjvpr-1ECXSS4,7939
21
+ mcp_server/contracts/streaming.py,sha256=IRX3iiICndZeVk0tBEM7VAPrRzYc_cfx3a3KGqhY5Ew,9129
22
+ mcp_server/formatters/__init__.py,sha256=vF-GVHPa9nPU599Tnr1DqlbixWGSiStfoNZ95r1XeaY,275
23
+ mcp_server/formatters/base.py,sha256=LsgTtVBQx601NyYSgDagm2LVBGgAEDIJLz7udrwziZI,1414
24
+ mcp_server/formatters/markdown_formatter.py,sha256=AKQQvbIGLHM3Qg5F1Ei7ZTx2jgWkgK9T01wgVh3Mvi0,7410
25
+ mcp_server/formatters/structured_formatter.py,sha256=QGepnWF_aa9EU5gU1VgAbh0o-eP3JFsg-KUwW4LV0Ss,7621
26
+ grip_protocol-0.1.0.dist-info/METADATA,sha256=9hwNaMzG6or98FuVC0bIjmWqas4-qkPMgvdjvqO5_hw,8037
27
+ grip_protocol-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
28
+ grip_protocol-0.1.0.dist-info/entry_points.txt,sha256=CHzLXBNV52hovbeZEUjQYLWRPV1gOygsBTkPdzPSpEo,210
29
+ grip_protocol-0.1.0.dist-info/top_level.txt,sha256=R49ZBwHkJvJ-AJ8o9wy6MuCs0rvZpyCEuvdwhI4PpHs,11
30
+ grip_protocol-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ graphrag-mcp = mcp_server.mcp_server:main
3
+ graphrag-server = mcp_server.server:main
4
+ grip = mcp_server.mcp_server:main
5
+ grip-mcp = mcp_server.mcp_server:main
6
+ grip-server = mcp_server.server:main
@@ -0,0 +1 @@
1
+ mcp_server
mcp_server/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """graphrag-protocol: Universal GraphRAG Interoperability Protocol."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,7 @@
1
+ """Backend adapters for the GraphRAG Protocol."""
2
+
3
+ from .base import BaseGraphRAGAdapter
4
+ from .fallback_adapter import DemoGraphRAGAdapter
5
+ from .tigergraph_adapter import TigerGraphAdapter
6
+
7
+ __all__ = ["BaseGraphRAGAdapter", "DemoGraphRAGAdapter", "TigerGraphAdapter"]
@@ -0,0 +1,128 @@
1
+ """Abstract GraphRAG backend adapter interface."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import Any
7
+
8
+ from mcp_server.protocol import (
9
+ GraphSchema,
10
+ Provenance,
11
+ SubgraphContext,
12
+ )
13
+
14
+
15
+ class BaseGraphRAGAdapter(ABC):
16
+ """Abstract adapter every GraphRAG backend must implement.
17
+
18
+ Extends the retrieval contract with schema discovery, provenance
19
+ extraction, and health reporting. Concrete adapters (TigerGraph,
20
+ Neo4j, LightRAG, vector stores, ...) translate these standard
21
+ operations onto their native query APIs.
22
+ """
23
+
24
+ @abstractmethod
25
+ def local_search(
26
+ self,
27
+ query: str,
28
+ entity_hints: list[str] | None = None,
29
+ depth: int = 2,
30
+ top_k: int = 10,
31
+ filters: dict[str, Any] | None = None,
32
+ ) -> SubgraphContext:
33
+ """Precise, entity-centric retrieval around matched entities.
34
+
35
+ Seeds from ``entity_hints`` (or entities matched from ``query``),
36
+ expands up to ``depth`` hops, and returns the most relevant
37
+ entities, relationships, and supporting text chunks.
38
+ """
39
+ ...
40
+
41
+ @abstractmethod
42
+ def global_search(
43
+ self,
44
+ query: str,
45
+ community_level: int = 2,
46
+ top_communities: int = 10,
47
+ ) -> SubgraphContext:
48
+ """Broad, corpus-level retrieval via community summaries."""
49
+ ...
50
+
51
+ @abstractmethod
52
+ def hybrid_search(
53
+ self,
54
+ query: str,
55
+ vector_weight: float = 0.5,
56
+ graph_weight: float = 0.5,
57
+ top_k: int = 10,
58
+ depth: int = 2,
59
+ ) -> SubgraphContext:
60
+ """Combined vector-similarity + graph-structure retrieval."""
61
+ ...
62
+
63
+ @abstractmethod
64
+ def entity_lookup(
65
+ self,
66
+ entity_id: str | None = None,
67
+ entity_name: str | None = None,
68
+ entity_type: str | None = None,
69
+ depth: int = 1,
70
+ ) -> SubgraphContext:
71
+ """Fetch a specific entity and its immediate context."""
72
+ ...
73
+
74
+ @abstractmethod
75
+ def path_search(
76
+ self,
77
+ source: str,
78
+ target: str,
79
+ max_hops: int = 4,
80
+ ) -> SubgraphContext:
81
+ """Find paths between two entities."""
82
+ ...
83
+
84
+ @abstractmethod
85
+ def neighborhood(
86
+ self,
87
+ entity_id: str,
88
+ depth: int = 2,
89
+ edge_types: list[str] | None = None,
90
+ ) -> SubgraphContext:
91
+ """Expand outward from an entity within ``depth`` hops."""
92
+ ...
93
+
94
+ @abstractmethod
95
+ def community_members(
96
+ self,
97
+ community_id: str,
98
+ include_summary: bool = True,
99
+ ) -> SubgraphContext:
100
+ """List member entities of a community (optionally with summary)."""
101
+ ...
102
+
103
+ @abstractmethod
104
+ def get_schema(self, graph_id: str | None = None) -> GraphSchema:
105
+ """Introspect the graph schema.
106
+
107
+ Returns vertex/edge types, attributes, cardinalities, and
108
+ graph-level statistics in the standard GraphSchema form.
109
+ """
110
+ ...
111
+
112
+ @abstractmethod
113
+ def get_provenance(self, context: SubgraphContext) -> Provenance:
114
+ """Extract the citation and audit trail for a retrieval context.
115
+
116
+ Reconstructs source documents, traversal steps, and visited-but-
117
+ not-cited entities from the adapter's internal execution state.
118
+ """
119
+ ...
120
+
121
+ @abstractmethod
122
+ def health_check(self) -> dict:
123
+ """Report backend connectivity and health.
124
+
125
+ Returns a dict with at least ``status`` ("ok"/"error"), and
126
+ typically ``backend`` and ``version`` keys.
127
+ """
128
+ ...