Declarative query language for KERI credential graphs. Thin wrappers over keripy — no reimplementation.
- Resolution IS Verification — If a SAID resolves, cryptographic integrity is guaranteed
- Don't Duplicate, Integrate — Thin wrappers over keripy, not a parallel stack
pip install kgqlfrom kgql import KGQL
# Initialize with any keripy Habery/Regery/Verifier
kgql = KGQL(hby=hby, rgy=rgy, verifier=verifier)
# Resolve a credential by SAID
result = kgql.resolve("ESAID...")
# Query by issuer
creds = kgql.by_issuer("EAID...")
# Execute a KGQL query string
result = kgql.query(
"MATCH (c:Credential) WHERE c.issuer = $aid",
variables={"aid": "EAID..."}
)
# Verify a credential chain
result = kgql.verify("ESAID...")
# Traverse edges
result = kgql.traverse("ESAID...", "delegator")Resolve a single credential by SAID:
RESOLVE $said
Query credentials by attributes:
MATCH (c:Credential) WHERE c.issuer = $aid
MATCH (c:Credential) WHERE c.schema = $schema_said
MATCH (c:Credential) WHERE c.subject = $aid
Verify a credential chain:
VERIFY $said
Follow credential edges:
TRAVERSE FROM $said FOLLOW edge
TRAVERSE FROM $said FOLLOW delegator
query(kgql_string, variables)— Execute any KGQL queryresolve(said)— Resolve single credentialby_issuer(aid)/by_subject(aid)— Query by participantverify(said)— Verify credential chaintraverse(from_said, edge_type)— Follow edgesverify_end_to_end_chain(said)— Full delegation chain verification
Parses KGQL query strings into AST:
from kgql.parser import KGQLParser
parser = KGQLParser()
ast = parser.parse("RESOLVE $said", variables={"said": "ESAID..."})Maps AST operations to keripy method calls:
from kgql.translator import QueryPlanner
planner = QueryPlanner()
plan = planner.plan(ast)Protocol-agnostic edge resolution:
EdgeResolver— Abstract interface for any protocolACDCEdgeResolver— KERI/ACDC credential edges (reads the"e"field)PatternSpaceEdgeResolver— Concept/pattern ontology graph edgesEdgeResolverRegistry— Multi-protocol resolver registryRegerWrapper— Thin wrapper over keripy RegerVerifierWrapper— Thin wrapper over keripy Verifier
from kgql.wrappers import create_default_registry
# Registry with ACDC + PatternSpace resolvers
registry = create_default_registry()
# Resolve an edge from a credential
edge = registry.resolve_edge(credential, "iss")
print(edge.target_said)
# Or from a concept/pattern node
edge = registry.resolve_edge(
{"slug": "keri-runtime-singleton"},
"references",
protocol_hint="pattern-space",
)Implementing a custom resolver:
from kgql.wrappers import EdgeResolver, EdgeRef
class MyProtocolResolver(EdgeResolver):
@property
def protocol(self) -> str:
return "my-protocol"
def get_edge(self, content, edge_name):
# Extract edge from your protocol's format
...
def list_edges(self, content):
# List available edges
...
registry.register(MyProtocolResolver())Schema-driven credential indexing (inspired by Phil Feairheller's KERIA Seeker pattern):
from kgql.indexer import create_query_engine
engine = create_query_engine({"ESchema...": person_schema})
results = engine.query(
credentials,
{
"personLegalName": "Alice", # Implicit $eq
"LEI": {"$begins": "US"}, # Prefix match
"age": {"$gte": 30}, # Comparison
"-s": "ESchema...", # Schema filter
},
)Operators: $eq, $begins, $lt, $gt, $lte, $gte, $contains
Model Context Protocol server for LLM tool integration:
python -m kgql.mcpConfigure in any MCP-compatible client:
{
"mcpServers": {
"kgql": {
"command": "python3",
"args": ["-m", "kgql.mcp"]
}
}
}Tools: kgql_resolve, kgql_query, kgql_verify_chain, kgql_by_schema, kgql_traverse
KGQL Query String
│
▼
KGQLParser ──→ AST
│
▼
QueryPlanner ──→ ExecutionPlan
│
▼
KGQL ──→ Execute via wrappers
│
▼
EdgeResolverRegistry
├── ACDCEdgeResolver (KERI/ACDC)
├── PatternSpaceEdgeResolver (ontology)
└── [your resolver]
│
▼
keripy
Habery / Regery / Verifier
keri>=1.2.0— Core KERI implementationhio>=0.6.14— HIO async framework (Deck integration)lark>=1.1.0— Parser generator for KGQL grammarkeri-governance>=0.1.0— Governance engine (constraint algebra, frameworks, patterns)
Apache 2.0