vector-mcp 2.1.1__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.1 → vector_mcp-2.1.2}/AGENTS.md +7 -5
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/PKG-INFO +2 -2
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/README.md +1 -1
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/pyproject.toml +1 -1
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/agent_server.py +1 -1
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/mcp_server.py +1 -1
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/epistemic_graph.py +62 -28
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/PKG-INFO +2 -2
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/.pre-commit-config.yaml +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/CHANGELOG.md +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/CLAUDE.md +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/LICENSE +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/MANIFEST.in +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/a2a.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/mcp_config.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/mkdocs.yml +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/opencode.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/requirements.txt +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/investigate_timeout.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/security_sanitizer.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/validate_a2a_agent.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/validate_agents.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/validate_all_dbs.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/scripts/verify_deps.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/setup.cfg +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/conftest.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/reproduce_chunking.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_action_discovery.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_agent_server.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_all_backends.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_auth.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_concept_parity.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_databases.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_init_dynamics.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_mcp_server.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_optional_dependencies.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_placeholder.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_protocol_compliance.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_pruning.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_retrievers.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_startup.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_vector_mcp.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/tests/test_vectordbs_mock.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/__main__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/auth.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/connectors/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/connectors/mcp_source_presets.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/mcp/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/mcp/mcp_collection_management.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/mcp/mcp_search.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/mcp_config.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/ontology/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/ontology/vector.ttl +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/prompts/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/prompts/main_agent.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/prompts/retrieval_specialist.json +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/chromadb_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/couchbase_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/epistemic_graph_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/llamaindex_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/mongodb_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/postgres_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/qdrant_retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/retriever/retriever.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/skills/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/skills/vector-backend-operations/SKILL.md +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/skills/vector-collection-management/SKILL.md +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/skills/vector-hybrid-search/SKILL.md +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vector_api.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/__init__.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/base.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/chromadb.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/couchbase.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/db_utils.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/mongodb.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/postgres.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp/vectordb/qdrant.py +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/SOURCES.txt +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/dependency_links.txt +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/entry_points.txt +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/requires.txt +0 -0
- {vector_mcp-2.1.1 → vector_mcp-2.1.2}/vector_mcp.egg-info/top_level.txt +0 -0
|
@@ -190,11 +190,13 @@ async def my_tool(param: str) -> str:
|
|
|
190
190
|
- **Couchbase**: Couchbase with REST API fallback and manual cosine similarity (container required, partially functional)
|
|
191
191
|
|
|
192
192
|
### Implementation Notes
|
|
193
|
-
- **Epistemic-Graph**: stores each chunk as an engine node (text
|
|
194
|
-
|
|
195
|
-
`SyncEpistemicGraphClient` (`.nodes.add` + `.graph.add_embedding`
|
|
196
|
-
`.graph.semantic_search`);
|
|
197
|
-
|
|
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`.
|
|
198
200
|
- **MongoDB**: Uses raw MongoClient instead of MongoDBAtlasVectorSearch to avoid authentication issues with local test containers. Implements manual cosine similarity calculation for semantic search.
|
|
199
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.
|
|
200
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,35 +274,66 @@ class EpistemicGraphVectorDB(VectorDB):
|
|
|
271
274
|
n_results: int = 10,
|
|
272
275
|
**kwargs: Any,
|
|
273
276
|
) -> QueryResults:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
+
"""
|
|
277
284
|
client = self._client_for(collection_name)
|
|
285
|
+
results: QueryResults = []
|
|
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
|
|
292
|
+
try:
|
|
293
|
+
hits = client.graph.discover(terms, q_emb, n_results) or []
|
|
294
|
+
except Exception as e:
|
|
295
|
+
logger.info(f"discover unavailable, using client scan: {e}")
|
|
296
|
+
results.append(self._lexical_scan(client, terms, n_results))
|
|
297
|
+
continue
|
|
298
|
+
query_result: list[tuple[Document, float]] = []
|
|
299
|
+
for item in hits[:n_results]:
|
|
300
|
+
if isinstance(item, dict):
|
|
301
|
+
node_id = str(item.get("id", ""))
|
|
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
|
|
308
|
+
else:
|
|
309
|
+
node_id, score, props = str(item), 0.0, None
|
|
310
|
+
if not node_id:
|
|
311
|
+
continue
|
|
312
|
+
query_result.append((self._props_to_doc(node_id, props), score))
|
|
313
|
+
results.append(query_result)
|
|
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``)."""
|
|
278
320
|
try:
|
|
279
321
|
listing = client.nodes.list() or []
|
|
280
322
|
except Exception as e:
|
|
281
|
-
logger.info(f"lexical
|
|
282
|
-
|
|
283
|
-
|
|
323
|
+
logger.info(f"lexical scan (list nodes): {e}")
|
|
324
|
+
return []
|
|
325
|
+
scored: list[tuple[Document, float]] = []
|
|
284
326
|
for entry in listing:
|
|
285
327
|
node_id = str(entry[0]) if isinstance(entry, list | tuple) else str(entry)
|
|
286
328
|
try:
|
|
287
329
|
props = client.nodes.properties(node_id) or {}
|
|
288
330
|
except Exception:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if not content:
|
|
299
|
-
continue
|
|
300
|
-
freq = sum(content.count(t) for t in terms)
|
|
301
|
-
if freq > 0:
|
|
302
|
-
scored.append((self._props_to_doc(node_id, props), float(freq)))
|
|
303
|
-
scored.sort(key=lambda x: x[1], reverse=True)
|
|
304
|
-
results.append(scored[:n_results])
|
|
305
|
-
return results
|
|
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.1 → 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
|