I write custom DKAN AI modules and the
React frontends that consume them
Exploring how AI can lower the barrier between open data and
the people who need it
Off the clock: guitar, Aikido.
The promise
Open data is a simple promise
Governments and institutions publish what they know — and let anyone
use it.
In the U.S., it's often the law. Federal agencies have been
required to publish data open by default since a
2013 executive order, codified permanently by the
OPEN Government Data Act in 2019.
data.govcity & county portalshealth agenciestransit & environment
The infrastructure got good — fast APIs, reliable
catalogs, (sometimes) careful metadata.
That's not the problem anymore.
The promise · what good looks like
The bar the community set: FAIR
Findable
Rich metadata in searchable catalogs; stable identifiers.
Accessible
Retrievable over standard, open protocols — plain HTTP APIs.
Interoperable
Shared formats and vocabularies — CSV, JSON, DCAT.
Reusable
Open licenses, provenance, documentation — data dictionaries.
Written for machines as much as people — which is
about to matter.
FAIR gets data to the doorstep. It still doesn't answer a
question.
The gap
The answer is in here somewhere
Somewhere in a 12-million-row CSV is the number
a reporter, a researcher, or a neighbor came for.
Getting there takes real work:
knowing which question to ask
understanding what the numbers mean
making sense of the answer
That gap is where most people stop.
The gap, precisely
"Published" ≠ "answered"
A dataset is publishedA person got their answer
Everything after this slide is about closing
the gap.
DKAN in four minutes
What DKAN is
The Drupal distribution for open-data catalogs,
in active use since 2013. Inspired by CKAN (another open-data
catalog platform), built on Drupal.
Maintained by CivicActions. Many public agencies
run their data portals on it.
DKAN 4 shipped on Drupal.org in March 2026 —
composer require drupal/dkan, like any module.
Why you should care even if you'll never run DKAN:
it's a clean, real-world example of structured public data with an
API — exactly the shape AI agents are good at.
×
DKAN in four minutes
Two halves: Metastore & Datastore
Metastore
The records describing the data. CRUD over
metadata (DCAT, the standard open-data metadata format): titles,
descriptions, distributions, schemas.
→ tells you what exists.
Datastore
The rows themselves, made queryable via the
DatastoreQuery endpoint.
→ lets you compute on it.
The AI tools discover through the metastore and
answer through the datastore.
DKAN in four minutes
Anatomy of a dataset page
Everything up top is the metastore: title,
topics, description, publisher, distributions
The table is the datastore: 2,969 rows —
sortable, searchable, queryable
"Also available via the API" — everything a
human sees here, a tool can fetch
A bounded query language: filters, sorts, pagination, and
aggregates (sum/count/avg/min/max + groupings).
Deliberately bounded: no window functions,
subqueries, self-joins, CTEs. Remember this — the bound becomes
a safety feature later.
Why AI + open data
The three jobs an end-user actually does
1
Discover the schema
"What's even in here?"
2
Form the query
"How do I ask for it?"
3
Pick the right visualization
"What does this look like?"
These are exactly the three things that
stop people.
Why AI + open data
…map directly onto AI strengths
The user's job
What AI is good at
Discover the schema
↔
reading & structuring unfamiliar fields
Form the query
↔
translating intent into a formal query language
Pick the right visualization
↔
matching data shape to a chart
The pairing isn't a gimmick — AI models are strong at exactly the
interpretive layer people get stuck on. The
deterministic catalog underneath keeps them honest.
How we'll close it
Two ways to close the gap
A · End-user UX
A chat box on the site.
dkan_ai_query
for the visitor
B · Agent access
Expose the whole site to an AI agent.
dkan_mcp_server
for the developer / operator
Same goal, two audiences — though A quietly depends on B:
dkan_ai_query builds on a submodule that ships inside
dkan_mcp_server.
How we'll close it · the Drupal AI Initiative
Drupal has names for these two ways
Inside AI
People use AI inside Drupal — assistants,
in-product workflows, page building.
dkan_ai_query is Inside AI for open data.
Outside AI
Agents use Drupal from outside — connect,
inspect, change, verify.
dkan_mcp_server is Outside AI for open data.
The bridge between them: dkan_query_tools — one
protocol-neutral service layer that both workstreams consume.
Drupal AI Initiative, June 2026: one roadmap, two workstreams.
Demo 1 · dkan_ai_query
Meet the chat widget
"Ask in plain English —
which parks had the most bear sightings? — and get an
answer and a table, grounded in real queries. Ask for a chart
and you'll get one, inline."
It never guesses column names, and never does math in its
head
— every number routes through a tool.
Demo 1 · under the hood
The charts are model-authored
The AI writes the full chart definition via a
create_chart tool. The tool only returns a
placeholder — the real chart is captured on the server and drawn
with a charting library (Vega-Lite).
Intent
Mark
comparison
bar
trend
line
distribution
histogram
proportion
arc
correlation
point
Chart-type selection is the model's job — "matching data shape to a
chart," the AI-strengths mapping in practice.
Demo 2 · dkan_mcp_server
From a chat box to an agent
Now hand the whole site to an agent.
MCP — Model Context Protocol. A standard way for
an AI client (Claude Code) to discover and call tools.
Anthropic's open standard (Nov 2024); now under the Linux
Foundation's Agentic AI Foundation.
Tens of thousands of public MCP servers. This module makes
DKAN one of them.
● Live demo
An agent explores the site like a new hire
Claude Code, connected over stdio (its terminal, not the network) ·
drush dkan-mcp-server:serve
List the DKAN tools you have access to. As we go, tell me which
ones you use.
What's on this site?
What do we know about bears?
Break sightings down by bear weight
How did this data get onto the site?
Demo 2 · what it exposes
38 tools, in groups
38
25 read13 write
One #[Tool] attribute plugin each. Tools are
thin — they forward to plain Drupal services.
Group
#
metastore (catalog)
9
datastore (query)
8
harvest
7
write
10
status / search / resource
4
3 of the "harvest" group's tools are also writes
(register/run/deregister) — that's where the 13 comes from.
Demo 2 · permissions in action
Same server, two connections
Read-only (anonymous)
tools/list → 25 tools
the 13 writes are invisible
Write role
tools/list → all 38
and delete_dataset works
Any MCP-aware client works out of the box — the
gate, not the client, decides what's visible.
Architecture · for the developers
Where the AI actually lives
dkan_ai_query
The AI model lives here — via the Drupal
AI module + AI Agents.
This module is an agent.
dkan_mcp_server
No AI model at all. A pure tool server.
This module serves an agent.
Keys live in the Drupal key module, never in code.
Architecture · for the developers
Built on the Drupal AI ecosystem
dkan_ai_query
Built on ai + ai_agents —
the AI Initiative's foundation modules.
Works with any provider module — swap by
settings, not code:
AnthropicOpenAIlocal — LM Studio / Ollama…
dkan_mcp_server
Built on contrib mcp_server + the
official MCP PHP SDK.
Protocol, transports, JSON-RPC — all upstream. This module adds
only the DKAN tools and the
access gate.
The DKAN modules are a domain layer on community
foundations — no bespoke LLM plumbing, no bespoke protocol code.
Architecture · for the developers
Build once, expose twice
Chat widget
Inside AI — the agent loop runs in Drupal
(ai_agents).
MCP client
Outside AI — the loop runs in the client; the
server only serves tools.