vector-mcp 2.1.0__tar.gz → 2.1.2__tar.gz
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.
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/AGENTS.md +12 -1
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/PKG-INFO +2 -2
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/README.md +1 -1
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/pyproject.toml +1 -1
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/agent_server.py +1 -1
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/mcp_server.py +1 -1
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/epistemic_graph.py +56 -14
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/PKG-INFO +2 -2
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/.pre-commit-config.yaml +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/CHANGELOG.md +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/CLAUDE.md +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/LICENSE +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/MANIFEST.in +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/a2a.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/mcp_config.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/mkdocs.yml +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/opencode.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/requirements.txt +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/investigate_timeout.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/security_sanitizer.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/validate_a2a_agent.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/validate_agents.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/validate_all_dbs.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/scripts/verify_deps.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/setup.cfg +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/conftest.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/reproduce_chunking.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_action_discovery.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_agent_server.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_all_backends.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_auth.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_concept_parity.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_databases.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_init_dynamics.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_mcp_server.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_optional_dependencies.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_placeholder.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_protocol_compliance.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_pruning.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_retrievers.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_startup.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_vector_mcp.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/tests/test_vectordbs_mock.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/__main__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/auth.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/connectors/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/connectors/mcp_source_presets.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/mcp/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/mcp/mcp_collection_management.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/mcp/mcp_search.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/mcp_config.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/ontology/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/ontology/vector.ttl +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/prompts/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/prompts/main_agent.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/prompts/retrieval_specialist.json +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/chromadb_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/couchbase_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/epistemic_graph_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/llamaindex_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/mongodb_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/postgres_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/qdrant_retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/retriever/retriever.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/skills/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/skills/vector-backend-operations/SKILL.md +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/skills/vector-collection-management/SKILL.md +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/skills/vector-hybrid-search/SKILL.md +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vector_api.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/__init__.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/base.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/chromadb.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/couchbase.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/db_utils.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/mongodb.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/postgres.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/vectordb/qdrant.py +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/SOURCES.txt +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/dependency_links.txt +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/entry_points.txt +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/requires.txt +0 -0
- {vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp.egg-info/top_level.txt +0 -0
|
@@ -179,13 +179,24 @@ async def my_tool(param: str) -> str:
|
|
|
179
179
|
## Vector Database Backends
|
|
180
180
|
|
|
181
181
|
### Supported Backends
|
|
182
|
-
- **
|
|
182
|
+
- **Epistemic-Graph** (**DEFAULT**): the native local AI-native engine — durable
|
|
183
|
+
(redb-authoritative) with a native ANN/HNSW index, so semantic search is the engine's
|
|
184
|
+
O(log N) vector search. Zero external infra (autostarts). Selected when `db_type` is
|
|
185
|
+
unspecified (override with `VECTOR_DB_TYPE`).
|
|
186
|
+
- **ChromaDB**: Local filesystem-based vector database (no container required). Opt-in via the `[chromadb]` extra.
|
|
183
187
|
- **PostgreSQL/PGVector**: PostgreSQL with pgvector extension (container required)
|
|
184
188
|
- **MongoDB**: MongoDB with manual cosine similarity calculation (container required)
|
|
185
189
|
- **Qdrant**: Qdrant vector database (container required)
|
|
186
190
|
- **Couchbase**: Couchbase with REST API fallback and manual cosine similarity (container required, partially functional)
|
|
187
191
|
|
|
188
192
|
### Implementation Notes
|
|
193
|
+
- **Epistemic-Graph**: stores each chunk as an engine node (text in the indexed
|
|
194
|
+
`description` property, plus metadata) with its embedding in the engine's native ANN
|
|
195
|
+
index via `SyncEpistemicGraphClient` (`.nodes.add` + `.graph.add_embedding`). Semantic
|
|
196
|
+
search is `.graph.semantic_search` (native ANN); lexical/keyword search is the engine's
|
|
197
|
+
one-round-trip `.graph.discover` (keyword overlap + semantic, scalable — a client-side
|
|
198
|
+
term scan is only a fallback for an engine too old for `discover`). A collection maps to
|
|
199
|
+
an engine graph (`graph_name`); embeddings come from the shared `create_embedding_model`.
|
|
189
200
|
- **MongoDB**: Uses raw MongoClient instead of MongoDBAtlasVectorSearch to avoid authentication issues with local test containers. Implements manual cosine similarity calculation for semantic search.
|
|
190
201
|
- **Couchbase**: Uses simple client approach with REST API fallback to bypass SDK authentication issues. Implements manual cosine similarity calculation for semantic search. Core search functionality working (10/14 tests passing), CRUD operations limited by N1QL service configuration.
|
|
191
202
|
- **PostgreSQL**: Uses native PGVector with proper JSONB querying for get_documents_by_ids.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vector-mcp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Integrate RAG into AI Agents via MCP Server. Supports multiple Vector database technologies.
|
|
5
5
|
Author-email: Audel Rouhi <knucklessg1@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -83,7 +83,7 @@ Dynamic: license-file
|
|
|
83
83
|

|
|
84
84
|

|
|
85
85
|
|
|
86
|
-
*Version: 2.1.
|
|
86
|
+
*Version: 2.1.2*
|
|
87
87
|
|
|
88
88
|
---
|
|
89
89
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vector-mcp"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.2"
|
|
8
8
|
description = "Integrate RAG into AI Agents via MCP Server. Supports multiple Vector database technologies."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
classifiers = [ "Development Status :: 5 - Production/Stable", "License :: Public Domain", "Environment :: Console", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3",]
|
|
@@ -30,9 +30,12 @@ with optional_import_block():
|
|
|
30
30
|
|
|
31
31
|
logger = get_logger(__name__)
|
|
32
32
|
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
# The chunk text is stored under the engine's standard ``description`` property: it is
|
|
34
|
+
# the field the engine keyword-indexes and that ``graph.discover`` hydrates, so lexical
|
|
35
|
+
# search runs engine-side (scalable) instead of an O(N) client scan. Everything not in
|
|
36
|
+
# the reserved set is treated as user metadata.
|
|
37
|
+
_TEXT_KEY = "description"
|
|
38
|
+
_RESERVED_KEYS = {_TEXT_KEY, "label", "id", "_similarity", "name", "type", "score"}
|
|
36
39
|
|
|
37
40
|
|
|
38
41
|
@require_optional_import(["epistemic_graph", "agent_utilities"], "epistemic-graph")
|
|
@@ -107,7 +110,7 @@ class EpistemicGraphVectorDB(VectorDB):
|
|
|
107
110
|
@staticmethod
|
|
108
111
|
def _props_to_doc(node_id: str, props: dict | None) -> Document:
|
|
109
112
|
props = dict(props or {})
|
|
110
|
-
content = props.
|
|
113
|
+
content = props.get(_TEXT_KEY, "") or ""
|
|
111
114
|
meta = {k: v for k, v in props.items() if k not in _RESERVED_KEYS}
|
|
112
115
|
return Document(id=node_id, content=content, metadata=meta, embedding=None)
|
|
113
116
|
|
|
@@ -173,7 +176,7 @@ class EpistemicGraphVectorDB(VectorDB):
|
|
|
173
176
|
embedding = doc.get("embedding")
|
|
174
177
|
if embedding is None:
|
|
175
178
|
embedding = self._embed(text)
|
|
176
|
-
client.nodes.add(doc_id, {
|
|
179
|
+
client.nodes.add(doc_id, {_TEXT_KEY: text, "label": "Document", **meta})
|
|
177
180
|
client.graph.add_embedding(doc_id, [float(x) for x in embedding])
|
|
178
181
|
|
|
179
182
|
def update_documents(
|
|
@@ -271,27 +274,66 @@ class EpistemicGraphVectorDB(VectorDB):
|
|
|
271
274
|
n_results: int = 10,
|
|
272
275
|
**kwargs: Any,
|
|
273
276
|
) -> QueryResults:
|
|
277
|
+
"""Keyword search over the engine's scalable index.
|
|
278
|
+
|
|
279
|
+
Routes through the engine's one-round-trip ``discover`` op — it ranks nodes by
|
|
280
|
+
keyword overlap over the indexed text (the chunk text lives in ``description``)
|
|
281
|
+
AND semantic similarity, returning a hydrated top-k. Falls back to a client-side
|
|
282
|
+
term scan only if the engine is too old to support ``discover``.
|
|
283
|
+
"""
|
|
274
284
|
client = self._client_for(collection_name)
|
|
275
285
|
results: QueryResults = []
|
|
276
286
|
for query in queries:
|
|
287
|
+
terms = list(dict.fromkeys(t for t in query.lower().split() if t))
|
|
288
|
+
try:
|
|
289
|
+
q_emb = self._embed(query, is_query=True)
|
|
290
|
+
except Exception:
|
|
291
|
+
q_emb = [] # discover degrades to a bounded keyword-only scan
|
|
277
292
|
try:
|
|
278
|
-
hits = client.graph.
|
|
293
|
+
hits = client.graph.discover(terms, q_emb, n_results) or []
|
|
279
294
|
except Exception as e:
|
|
280
|
-
logger.info(f"
|
|
281
|
-
|
|
295
|
+
logger.info(f"discover unavailable, using client scan: {e}")
|
|
296
|
+
results.append(self._lexical_scan(client, terms, n_results))
|
|
297
|
+
continue
|
|
282
298
|
query_result: list[tuple[Document, float]] = []
|
|
283
299
|
for item in hits[:n_results]:
|
|
284
300
|
if isinstance(item, dict):
|
|
285
301
|
node_id = str(item.get("id", ""))
|
|
286
|
-
score = float(item.get("score",
|
|
302
|
+
score = float(item.get("score", 0.0) or 0.0)
|
|
303
|
+
# discover hydrates text in-band; fetch full props for metadata.
|
|
304
|
+
try:
|
|
305
|
+
props = client.nodes.properties(node_id) or item
|
|
306
|
+
except Exception:
|
|
307
|
+
props = item
|
|
287
308
|
else:
|
|
288
|
-
node_id, score = str(item),
|
|
309
|
+
node_id, score, props = str(item), 0.0, None
|
|
289
310
|
if not node_id:
|
|
290
311
|
continue
|
|
291
|
-
try:
|
|
292
|
-
props = client.nodes.properties(node_id)
|
|
293
|
-
except Exception:
|
|
294
|
-
props = None
|
|
295
312
|
query_result.append((self._props_to_doc(node_id, props), score))
|
|
296
313
|
results.append(query_result)
|
|
297
314
|
return results
|
|
315
|
+
|
|
316
|
+
def _lexical_scan(
|
|
317
|
+
self, client: Any, terms: list[str], n_results: int
|
|
318
|
+
) -> list[tuple[Document, float]]:
|
|
319
|
+
"""Fallback term-frequency scan (only when the engine lacks ``discover``)."""
|
|
320
|
+
try:
|
|
321
|
+
listing = client.nodes.list() or []
|
|
322
|
+
except Exception as e:
|
|
323
|
+
logger.info(f"lexical scan (list nodes): {e}")
|
|
324
|
+
return []
|
|
325
|
+
scored: list[tuple[Document, float]] = []
|
|
326
|
+
for entry in listing:
|
|
327
|
+
node_id = str(entry[0]) if isinstance(entry, list | tuple) else str(entry)
|
|
328
|
+
try:
|
|
329
|
+
props = client.nodes.properties(node_id) or {}
|
|
330
|
+
except Exception:
|
|
331
|
+
continue
|
|
332
|
+
content = str(props.get(_TEXT_KEY, "") or "").lower()
|
|
333
|
+
if not content:
|
|
334
|
+
continue
|
|
335
|
+
freq = sum(content.count(t) for t in terms)
|
|
336
|
+
if freq > 0:
|
|
337
|
+
scored.append((self._props_to_doc(node_id, props), float(freq)))
|
|
338
|
+
scored.sort(key=lambda x: x[1], reverse=True)
|
|
339
|
+
return scored[:n_results]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vector-mcp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Integrate RAG into AI Agents via MCP Server. Supports multiple Vector database technologies.
|
|
5
5
|
Author-email: Audel Rouhi <knucklessg1@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -83,7 +83,7 @@ Dynamic: license-file
|
|
|
83
83
|

|
|
84
84
|

|
|
85
85
|
|
|
86
|
-
*Version: 2.1.
|
|
86
|
+
*Version: 2.1.2*
|
|
87
87
|
|
|
88
88
|
---
|
|
89
89
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vector_mcp-2.1.0 → vector_mcp-2.1.2}/vector_mcp/skills/vector-collection-management/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|