knowlytix-kal
KAL — Knowledge Adapter Layer: a backend-agnostic mesh for knowledge graphs.
KAL is a small typed Python protocol that any knowledge graph can implement (relational store, native graph database, RDF endpoint), plus a federation router that presents many adapters as one logical view. The data crossing the protocol boundary — typed nodes, triples, literals, queries, and query results — carries first-class verification metadata (confidence, status, per-engine scores, evaluator identity), not as opaque payload but as load-bearing fields.
Status
v0.14.0 — alpha.
Concrete backend adapters (Postgres, Wikidata SPARQL, JSONL, in-memory vector node-store, Neo4j property graph), the connection registry, credential management, the MCP server tool surface, MCP-client ingestion (batch + live query-time synthesis), source governance (revoke-by-source / quarantine), and the standalone Alembic migration chain are all in place. See CHANGELOG.md for the per-release narrative.
Install
pip install knowlytix-kal
The default install is a pure library — pydantic>=2 is the only runtime dependency. No FastAPI, no SQLAlchemy, no DB drivers.
Quick start
from knowlytix.kal import (
AdapterCapabilities,
ConflictStrategy,
FederationRouter,
KALQuery,
KALTriple,
KnowledgeAdapter,
)
from knowlytix.kal.adapters import MockKnowledgeAdapter
from knowlytix.kal.registry import AdapterRegistry
# Construct an in-memory mock adapter for testing.
mock = MockKnowledgeAdapter("mock-1")
# Register it on a fresh registry, build a federation router.
registry = AdapterRegistry()
registry.register(mock)
router = FederationRouter(registry)
# Federated query — fans out to every registered adapter.
result = await router.query_triples(KALQuery())
print(result.triples)
print(result.errors) # per-adapter failures, if any
Run KAL locally
For a production-shaped Postgres + pgvector backend on your laptop, a
minimal docker-compose.yml ships with this package. The image is
pgvector/pgvector:pg17 and credentials are kal_dev:kal_dev — dev
only; never reuse in any non-local context.
docker compose up -d postgres
The compose binds host port 5432. If you already run a system Postgres
on that port, or if you run knowly's own dev compose (which binds 5433
on the host), this will fail with a bind error — either stop the
existing service or add a docker-compose.override.yml to remap the
port.
Once the container is healthy (about 25 seconds — docker compose ps
shows (healthy)), apply the KAL migrations. The migration runner
uses the sync Postgres driver, so install the [dev] extras (which
add psycopg2-binary) before invoking Alembic:
pip install 'knowlytix-kal[dev]'
KAL_DATABASE_URL=postgresql://kal_dev:kal_dev@localhost:5432/kal_dev \
alembic -c knowlytix/kal/migrations/alembic.ini upgrade head
The vector and pg_trgm extensions are enabled on the first
container start (via docker/init.sql) and migration 003 also issues
CREATE EXTENSION IF NOT EXISTS for both — so the same alembic upgrade head invocation works against managed-Postgres targets that
don't go through this compose file.
Tear down with docker compose down (add -v to also drop the data
volume).
Expose KAL to an LLM agent via MCP
knowlytix-kal[mcp] ships a KalMcpServer that wraps a FederationRouter and exposes its four read methods (query_triples, get_node, query_adjacent_triples, search_similar_nodes) as typed Model Context Protocol tools. Read-only by design (paper §3.6).
pip install 'knowlytix-kal[mcp]'
Stdio mode (local agents — Claude Desktop, Cursor, local CLI agents):
import asyncio
from knowlytix.kal import FederationRouter
from knowlytix.kal.mcp import KalMcpServer
from knowlytix.kal.registry import AdapterRegistry
registry = AdapterRegistry()
# … register adapters here …
router = FederationRouter(registry)
server = KalMcpServer(router, tenant_id="tenant-a")
server.run_stdio() # blocks
Streamable HTTP mode (remote agents — hosted-agent platforms, multi-tenant deployments where the MCP client and the KAL server live in different processes / machines):
import asyncio
from knowlytix.kal import FederationRouter
from knowlytix.kal.mcp import KalMcpServer, TokenTenantResolver
from knowlytix.kal.registry import AdapterRegistry
registry = AdapterRegistry()
# … register adapters here …
router = FederationRouter(registry)
server = KalMcpServer(
router,
allowed_hosts=["mcp.example.com"], # DNS-rebinding protection
)
resolver = TokenTenantResolver({
"<bearer-token-a>": "tenant-a",
"<bearer-token-b>": "tenant-b",
})
asyncio.run(server.run_http_async(resolver))
Tenant scope is never a tool argument — stdio binds the tenant at server construction; HTTP resolves per request from the bearer-token map. Production HTTP deployments should front the server with their own gateway (Cloudflare Access, API gateway, mTLS) for defense in depth; the bearer-token check is the inner-most ring.
End-to-end walkthrough with Claude Desktop config snippets, tool reference, and troubleshooting: docs/MCP_QUICKSTART.md. A production-shaped reference implementation lives at scripts/run_kal_mcp_server.py.
What's in this package
knowlytix.kal.protocol— theKnowledgeAdapterProtocol +AdapterCapabilitiesknowlytix.kal.types—KALTriple,KALNode,KALLiteral,KALQuery,KALQueryResult,VerificationMetadata,TripleProvenanceknowlytix.kal.federation—FederationRouter,ConflictStrategyknowlytix.kal.registry—AdapterRegistryknowlytix.kal.errors—AdapterError/AdapterWriteError/ etc.knowlytix.kal.tenant_index—TenantIndexfor federation tenant scopingknowlytix.kal.adapters.mock—MockKnowledgeAdapter(test fixture + dev mock)knowlytix.kal.adapters.jsonl—JsonlKnowledgeAdapter(read-only file-backed triple-store; oneKALTripleper line)knowlytix.kal.adapters.vector_node—VectorNodeKnowledgeAdapter(read-only file-backed node-store for cosine similarity;.jsonl+.npy+.encoderfiles)knowlytix.kal.adapters.mcp—McpKnowledgeAdapter(read-only live query-time synthesis from an external MCP source; §7.3 Pattern 2). Optional, requires[mcp]extrasknowlytix.kal.mcp—KalMcpServer+TokenTenantResolver(optional, requires[mcp]extras)knowlytix.kal.sources.mcp—McpIngestConnector+McpClientSession+ theClaimExtractorseam: consume an external MCP server as a data source (pull → extract → typed triples). Optional, requires[mcp]extras
Demos & walkthroughs
notebooks/kal_federation_walkthrough.ipynb— Jupyter walkthrough of registry / federation / partial failure / conflict strategies / §5.8 vertical axis. Mock-only; no Postgres needed.docs/MCP_QUICKSTART.md— wiring KAL into Claude Desktop / Cursor / remote agents over MCP, with tool reference + troubleshooting.docs/NEO4J_QUICKSTART.md— projecting a Neo4j property graph throughNeo4jKnowledgeAdapter(direct, connection registry, federation), with capabilities + limits.
Documentation
docs/QUICKSTART.md— short tour of the package surface.docs/paper/KAL_whitepaper.pdf— the design specification (§1–§9).
License
Apache-2.0. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file knowlytix_kal-1.0.0.tar.gz.
File metadata
- Download URL: knowlytix_kal-1.0.0.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2961806e64c61161e407f705710cea0620900f667210dab609f56ea979d53787
|
|
| MD5 |
1a327fcc4bdc6ab4f14750327a048489
|
|
| BLAKE2b-256 |
1bf5fbbf220a3d96119d347f4c9b8224bbad0c02cb432abb52ea8e51701b6e99
|
Provenance
The following attestation bundles were made for knowlytix_kal-1.0.0.tar.gz:
Publisher:
publish-pypi.yml on knowlytix/KAL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knowlytix_kal-1.0.0.tar.gz -
Subject digest:
2961806e64c61161e407f705710cea0620900f667210dab609f56ea979d53787 - Sigstore transparency entry: 2072889844
- Sigstore integration time:
-
Permalink:
knowlytix/KAL@a02b50ac1f02269995f03f14583790397164e2bf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/knowlytix
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@a02b50ac1f02269995f03f14583790397164e2bf -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file knowlytix_kal-1.0.0-py3-none-any.whl.
File metadata
- Download URL: knowlytix_kal-1.0.0-py3-none-any.whl
- Upload date:
- Size: 190.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbfede48ea31f9421d19f7d0e20a2a89b33e33c57707a30fb6d455eaca85f857
|
|
| MD5 |
bf2ee60ddfdf36ab97b9fd8f9df5cc6f
|
|
| BLAKE2b-256 |
1326a5015bf20a948f50592e03f7bae58511c16755f2dfa1c6f8c1720919a640
|
Provenance
The following attestation bundles were made for knowlytix_kal-1.0.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on knowlytix/KAL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knowlytix_kal-1.0.0-py3-none-any.whl -
Subject digest:
cbfede48ea31f9421d19f7d0e20a2a89b33e33c57707a30fb6d455eaca85f857 - Sigstore transparency entry: 2072889921
- Sigstore integration time:
-
Permalink:
knowlytix/KAL@a02b50ac1f02269995f03f14583790397164e2bf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/knowlytix
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@a02b50ac1f02269995f03f14583790397164e2bf -
Trigger Event:
workflow_dispatch
-
Statement type: