“Put GitHub releases in a table. Join them to my project inventory.”
That is a useful request for a coding agent. Release information lives behind an API; the versions your projects use live in a local file. But your question spans both: which projects have a different tag from the most recently published stable release?
Therefore, give DuckDB a way to read the API. With the VGI skill, an agent can build the program that fetches the releases, turns them into typed rows, and exposes them to SQL. DuckDB can join those rows to the CSV it already knows how to read.
We asked Codex to build this integration in a fresh project. It produced the worker, tests, and a live query. You can inspect the generated source and SQL results below. The local project inventory is sample data; the release information comes from GitHub.
If database extensions are new to you
An extension adds a capability to a database. It might let the database read a new kind of source or run a function it did not have before.
VGI—the Vector Gateway Interface—is an extension for DuckDB that connects it to a separate program called a worker. The worker can call an API, inspect files, or run a library. It describes the functions and tables it exposes, so you can use their results in SQL.
The agent builds that program. You keep the source and tests. Once it is built, DuckDB calls the worker directly; the coding agent does not need to answer each query.
If you already build extensions
Install VGI in stock DuckDB and implement your integration in a worker using one of six SDK languages. You can expose scalar functions, table functions, or a discoverable catalog. VGI handles the connection between the database and the separate worker process using typed Arrow data.
The agent produces the worker that runs behind the VGI extension. Its normal language tooling and libraries are available, and the skill supplies SDK guidance and a verifier that executes real SQL against it.
The first query reaches the API. The useful query combines sources.
For this build, we chose Python and asked for a table function over GitHub’s public releases API. The agent had to handle pagination, map fields to SQL types, report upstream failures, and test the behavior.
But returning a few releases is only the connection test. Therefore, the task also asks for a query joining the API data to a local project inventory.
GitHub has the releases. Your project inventory has the versions you use. The agent-built worker brings the API into DuckDB, so a query can join the two.
inventory.csv Sample local projects SQL result| project | installed_tag | published_tag | release_url |
|---|---|---|---|
| Analytics demo | v1.0.0 | v2.0.0 | Release notes ↗ |
| Reporting demo | v1.1.0 | v2.0.0 | Release notes ↗ |
Actual API results recorded 2026-11-06. Project names and installed tags are sample data. The query reports differing tags, not upgrade compatibility. This demo fetches at most three pages of five releases.
Inspect the query the agent wrote
-- Run after attaching github (see README.md). One bounded API scan, outside the inventory join.
-- Inventory is fictional. Different tags are review candidates, not guaranteed safe upgrades.
WITH fetched AS MATERIALIZED (
SELECT * FROM github.main.releases('duckdb', 'duckdb')
), latest AS (
SELECT tag_name, html_url
FROM fetched
WHERE prerelease = false AND published_at IS NOT NULL
ORDER BY CAST(published_at AS TIMESTAMPTZ) DESC
LIMIT 1
)
SELECT inventory.project,
inventory.installed_tag,
latest.tag_name AS published_tag,
latest.html_url AS release_url
FROM read_csv('inventory.csv', header = true, all_varchar = true) AS inventory
CROSS JOIN latest
WHERE inventory.owner = 'duckdb'
AND inventory.repo = 'duckdb'
AND inventory.installed_tag <> latest.tag_name
ORDER BY inventory.project;
Different tags are a reason to inspect the release notes, not an automatic upgrade recommendation. The example deliberately reports that difference without attempting to decide whether an upgrade is compatible.
The agent needs something it can prove
A plausible wrapper can return the wrong columns, silently stop after one page, or treat an API failure as an empty table. Therefore, the task needs more than “write a connector.” It needs specific results and tests that exercise the integration through DuckDB.
For new builds, the vgi-worker skill starts with the starter kit for your chosen language, adapts its worker and tests, and verifies the result in the requested engine. Deterministic fixtures make pagination, empty responses, and failures repeatable. A live API query checks that the integration reaches the real service too. The saved integration above was built before the starter kits were incorporated into the skill.
This is the useful change: the agent can write the integration and close the loop by running the query. You can inspect the code it leaves and rerun the same checks when the API or your requirements change.
What else could you ask for?
| Ask your agent | What you can query |
|---|---|
| “Scan this photo folder and expose its metadata.” | Camera models, dates, file sizes, and available GPS coordinates |
| “Join our support tickets to this customer CSV.” | Records from a service alongside your local business data |
| “Expose our validation library as SQL functions.” | The same rules your application uses, applied to columns of data |
| “Make this internal data service discoverable.” | Named tables and typed columns from a source your team owns |
These are starting prompts. The agent should ask for the source, fields, access requirements, and expected behavior. A local collector can keep its work local; a service integration needs explicit authentication and error handling.
Choose your agent and your language
- Codex
- Claude Code
- Cursor
- GitHub Copilot
- OpenCode
We have run native Codex and Claude Code evaluations. Skill installation has also been checked with Cursor, GitHub Copilot, and OpenCode. The skills use a portable format; installation compatibility is distinct from a completed agent build.
- C#
- Go
- Java
- Python
- Rust
- TypeScript
Python was the choice for this example. Your worker can use C#, Go, Java, Python, Rust, or TypeScript. A new project starts with your language choice; an existing worker keeps its conventions.
Small function builds have completed within five minutes in our evaluations, and some took longer. An API integration has more behavior to verify. We publish the measured runs and their limits rather than promising a universal completion time.
Stock DuckDB 2.0.0 can load VGI from the signed Query Farm extension repository. The quickstart has installation help and starting requests for APIs, local data, and existing libraries.