SuperAPI AI Directory

mdsql

Data & analytics

View repository

Updated 10-15 23:46

About this skill

mdsql

mdsql runs SQL over the frontmatter of a tree of markdown files. Each file is a row in a docs table (one column per frontmatter key); the file's own content is never queried, only its frontmatter. A running app is never required — files on disk are the only source of truth.

Before anything else

Confirm mdsql is installed (mdsql --list or which mdsql; if missing, npm install -g mdsql) and that a config exists. Discovery walks up from cwd looking for mdsql.config.json, same as git looks for .git — you don't need to cd to the project root, and --config <path> bypasses discovery entirely. If no config exists yet in the tree you're being asked to query, run mdsql init at its root to write a starter config, then tailor the queries.

See what's queryable

mdsql --list

Prints the named queries defined in mdsql.config.json, sorted. Read that file directly if you need to see the SQL, not just the names.

Run a query

mdsql <name> [params...] --format json

Prefer --format json when consuming output as an agent — it's structured and avoids parsing a padded text table. --format table (the default) is for humans at a terminal.

Named queries may contain ? placeholders; positional arguments after the name bind to them in order. The parameter count is checked strictly — passing the wrong number of arguments is a usage error (exit 2), never a silent empty result.

mdsql by-tag urgent --format json

has() semantics

The one custom SQL function, for frontmatter fields that are arrays or free text:

field type has(field, value) means
JSON array (e.g. tags) array membership
string substring match
NULL (key absent) always false

Adding a named query

Edit mdsql.config.json directly — it's plain JSON, not something mdsql itself writes:

{
  "scan": { "include": ["**/*.md"] },
  "queries": {
    "my-query": "SELECT path, title FROM docs WHERE has(tags, ?) ORDER BY path"
  }
}

scan.include globs and query results are both relative to the config file's own directory, regardless of your cwd. Reserved columns (don't use as frontmatter key names): path, _mtime, _size.

Exit codes

0 success · 1 a real error (bad config, SQL error — the SQLite message is printed verbatim) · 2 usage error (missing query name, unknown query name, wrong parameter count).

When results look stale

mdsql rebuild deletes the local .mdsql/ cache and re-crawls every file from scratch. Every query already reconciles the cache against the filesystem on open, so this is rarely needed — use it if you doubt the cache rather than trying to debug it. mdsql status shows the doc count, db path, and whether a background mdsql watch process is running (it's an optional pre-warmer, not a correctness requirement).