Shared library of DKAN catalog and datastore query tool classes used by AI-agent and MCP-server modules.
Provides three Drupal services that wrap DKAN's metastore, datastore, and search APIs in agent-friendly method signatures:
| Service ID | Class | Purpose |
|---|---|---|
dkan_query_tools.metastore |
MetastoreTools |
List/get datasets and distributions |
dkan_query_tools.datastore |
DatastoreTools |
Query datastore tables, schema, stats, joins, column search |
dkan_query_tools.search |
SearchTools |
Keyword search via DKAN's /api/1/search endpoint |
dkan_mcp— exposes these methods as MCP tools.dkan_drupal_ai_query— wraps each method in a Drupal AI FunctionCall plugin.dkan_nl_query— deprecated in favor ofdkan_drupal_ai_query; previously invoked these from a bespoke LLM agentic loop.
- Drupal 10.2+ or 11
- DKAN (
metastore,datastoremodules enabled)
-
Add as a Composer dependency. Use either a VCS repository (recommended for shared sites) or a local path repo (for development inside this monorepo):
VCS:
{ "repositories": { "dkan_query_tools": { "type": "vcs", "url": "https://github.com/dcgoodwin2112/dkan_query_tools.git" } }, "require": { "dcgoodwin2112/dkan_query_tools": "dev-main" } }Path repo:
{ "repositories": { "dkan_query_tools_local": { "type": "path", "url": "./docroot/modules/custom/dkan_query_tools", "options": { "symlink": true } } }, "require": { "dcgoodwin2112/dkan_query_tools": "@dev" } } -
Resolve and install:
composer update dcgoodwin2112/dkan_query_tools
-
Enable the module:
drush en dkan_query_tools
The three services become available immediately:
$datastore = \Drupal::service('dkan_query_tools.datastore');
$rows = $datastore->queryDatastore(resourceId: 'abc__1700000000', limit: 10);DatastoreTools carries the bulk of the query surface. The full method
list is in src/Tool/DatastoreTools.php; the
ones that matter for agent-style consumers:
| Method | Purpose |
|---|---|
queryDatastore() |
Structured query (filters, sort, pagination, aggregation). Returns rows + sanity_flags. |
queryDatastoreJoin() |
Two-resource join with the same response shape. |
getDatastoreSchema() |
Field names and types for one resource. Per-column dictionary_title / dictionary_description / dictionary_type and root-level dictionary_url are merged in when the distribution links a data dictionary. Pass includeDictionary: false to skip the lookup. |
getDataDictionary() |
On MetastoreTools. Resolve a dataset UUID or resource_id to its linked data dictionary item(s); returns curated field titles, descriptions, and declared types. |
getDatastoreStats() |
Min/max/null/distinct stats per column. |
sampleRows() |
Deterministic first-N rows for grounding. |
distinctValues() |
Code-list discovery for one column. |
searchColumns() |
Catalog-wide column search (on SearchTools). |
queryDatastore() and queryDatastoreJoin() never throw on
user-driven errors — they return structured error payloads that an
agent can read and self-correct from. See
docs/tool-responses.md for the full contract.
- docs/tool-responses.md — success / error /
sanity-flag shapes returned by
DatastoreToolsquery methods. - docs/database-roles.md — read-only MariaDB role for agent query execution.
Use the module-local PHPUnit runner:
cd docroot/modules/custom/dkan_query_tools && vendor/bin/phpunitUnit tests use standalone stubs in tests/stubs/ (no Drupal bootstrap). The
test bootstrap registers only this module's PSR-4 namespaces — it does not load
the module's vendor/autoload.php — so the suite also runs under the site-level
PHPUnit binary (../../../../vendor/bin/phpunit) without mixing PHPUnit major
versions.