Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/appicons/io.pilot.mysql.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions scripts/gen-apps.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const CATEGORIES = [
const CAT_HUE = Object.fromEntries(CATEGORIES.map((c) => [c.id, c.hue]));

const CATMAP = {
'io.pilot.postgres': 'data', 'io.pilot.duckdb': 'data', 'io.pilot.sqlite': 'data', 'io.pilot.redis': 'data', 'io.pilot.sixtyfour': 'data', 'io.pilot.orthogonal': 'data',
'io.pilot.postgres': 'data', 'io.pilot.duckdb': 'data', 'io.pilot.sqlite': 'data', 'io.pilot.mysql': 'data', 'io.pilot.redis': 'data', 'io.pilot.sixtyfour': 'data', 'io.pilot.orthogonal': 'data',
'io.pilot.cosift': 'ai', 'io.telepat.ideon-free': 'ai',
'io.pilot.plainweb': 'web', 'io.pilot.otto': 'web', 'io.pilot.bowmark': 'web',
'io.pilot.smol': 'infra', 'io.pilot.miren': 'infra', 'io.pilot.docker': 'infra',
Expand All @@ -46,6 +46,7 @@ const ICON_MAP = {
'io.pilot.postgres': { brand: 'postgresql', hex: '#4169E1' },
'io.pilot.duckdb': { brand: 'duckdb', hex: '#FFF000' },
'io.pilot.sqlite': { brand: 'sqlite', hex: '#003B57' },
'io.pilot.mysql': { brand: 'mysql', hex: '#4479A1' },
'io.pilot.redis': { brand: 'redis', hex: '#FF4438' },
'io.pilot.docker': { brand: 'docker', hex: '#2496ED' },
'io.pilot.cosift': { image: 'png', fit: 'contain', bg: '#ffffff' },
Expand Down Expand Up @@ -87,15 +88,15 @@ function iconFor(id, hue) {
// ---------- presentation config ----------
const APP_IDS = [
'io.pilot.agentphone',
'io.pilot.postgres', 'io.pilot.duckdb', 'io.pilot.sqlite', 'io.pilot.redis', 'io.pilot.sixtyfour',
'io.pilot.postgres', 'io.pilot.duckdb', 'io.pilot.sqlite', 'io.pilot.mysql', 'io.pilot.redis', 'io.pilot.sixtyfour',
'io.pilot.cosift', 'io.telepat.ideon-free', 'io.pilot.plainweb', 'io.pilot.otto',
'io.pilot.smol', 'io.pilot.miren', 'io.pilot.docker', 'io.pilot.aegis',
'io.pilot.slipstream', 'io.pilot.wallet', 'io.pilot.bowmark', 'io.pilot.orthogonal',
];
const FEATURED = ['io.pilot.postgres', 'io.pilot.duckdb', 'io.pilot.docker'];
const LINUX_ONLY = new Set(['io.pilot.docker']);
const PROTECTION_FALLBACK = {
'io.pilot.postgres': 'guarded', 'io.pilot.duckdb': 'guarded', 'io.pilot.sqlite': 'guarded', 'io.pilot.redis': 'guarded',
'io.pilot.postgres': 'guarded', 'io.pilot.duckdb': 'guarded', 'io.pilot.sqlite': 'guarded', 'io.pilot.mysql': 'guarded', 'io.pilot.redis': 'guarded',
'io.pilot.docker': 'guarded', 'io.pilot.miren': 'shareable', 'io.pilot.otto': 'guarded',
'io.pilot.wallet': 'guarded', 'io.pilot.slipstream': 'shareable', 'io.telepat.ideon-free': 'guarded',
'io.pilot.aegis': 'guarded',
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppIcon.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const isImg = app.icon.mode === 'image';
const pad = isImg && app.icon.fit === 'contain';
const mask = app.icon.file ? `-webkit-mask-image:url(${app.icon.file});mask-image:url(${app.icon.file})` : '';
---
<div class={`app-icon sz-${size}${isImg ? ' is-image' : ''}${pad ? ' pad' : ''}`} style={`--c:${app.icon.color}`} data-ink={app.icon.ink} aria-hidden="true">
<div class={`app-icon sz-${size}${isImg ? ' is-image' : ''}${pad ? ' pad' : ''}`} style={`--c:${app.icon.color}`} data-ink={app.icon.ink} data-app={app.id} aria-hidden="true">
{isImg
? <img class="logo-img" src={app.icon.img} alt="" loading="lazy" style={`object-fit:${app.icon.fit};object-position:${app.icon.pos}`} />
: <span class="logo" style={mask}></span>}
Expand Down
60 changes: 59 additions & 1 deletion src/data/app-methods.json
Original file line number Diff line number Diff line change
Expand Up @@ -849,5 +849,63 @@
"name": "orthogonal.help",
"summary": "The self-describing discovery contract: every method with params, cost note, and latency class. Local, free, no backend call."
}
]
],
"io.pilot.mysql": [
{
"name": "mysql.initialize",
"summary": "Initialize a new MySQL data directory (system tables + an insecure `root@localhost` with an empty password) \u2014 the one-time setup before the first start. This is `mysqld --initialize-insecure --datadir=<datadir>`. The bundle's basedir/plugin-dir/error-messages are wired in automatically."
},
{
"name": "mysql.start",
"summary": "Start a local MySQL server from a data directory, listening on 127.0.0.1:<port>. Runs detached (`--daemonize`) and returns once the server is accepting connections. This is `mysqld --daemonize --datadir=<datadir> --socket=<datadir>/mysql.sock --port=<port> --bind-address=127.0.0.1 --mysqlx=OFF --pid-file=<datadir>/mysqld.pid --log-error=<datadir>/mysqld.err`."
},
{
"name": "mysql.stop",
"summary": "Stop the local server listening on <port> (a clean shutdown). This is `mysqladmin -h 127.0.0.1 -P <port> -u root shutdown`."
},
{
"name": "mysql.ping",
"summary": "Check whether the server on <port> is up and accepting connections (liveness probe). This is `mysqladmin -h 127.0.0.1 -P <port> -u root ping`."
},
{
"name": "mysql.createdb",
"summary": "Create a database on the running server (no-op if it already exists). This is `mysql -h 127.0.0.1 -P <port> -u root -e \"CREATE DATABASE IF NOT EXISTS <dbname>\"`."
},
{
"name": "mysql.query",
"summary": "Run SQL against a database and return an aligned ASCII table \u2014 the default, human-readable shape. May contain multiple `;`-separated statements. This is `mysql -h 127.0.0.1 -P <port> -u root -D <database> --table -e <sql>`."
},
{
"name": "mysql.query_tsv",
"summary": "Same as mysql.query but returns tab-separated values (header + rows) via `--batch` \u2014 the machine-parseable shape. This is `mysql -h 127.0.0.1 -P <port> -u root -D <database> --batch -e <sql>`."
},
{
"name": "mysql.databases",
"summary": "List the databases on the server (`SHOW DATABASES`). This is `mysql -h 127.0.0.1 -P <port> -u root --table -e \"SHOW DATABASES\"`."
},
{
"name": "mysql.tables",
"summary": "List the tables in a database (`SHOW TABLES`). This is `mysql -h 127.0.0.1 -P <port> -u root -D <database> --table -e \"SHOW TABLES\"`."
},
{
"name": "mysql.dump",
"summary": "Dump a database as SQL (schema + data) with mysqldump \u2014 a portable logical backup the agent can save or replay. This is `mysqldump -h 127.0.0.1 -P <port> -u root --no-tablespaces <database>`."
},
{
"name": "mysql.exec",
"summary": "Run any bundled MySQL tool with a verbatim argv \u2014 the full surface beyond the curated methods. Payload is {\"args\":[tool, ...]} where tool is one of `mysql`, `mysqld`, `mysqladmin`, `mysqldump`, `mysqlshow`, plus optional {\"stdin\":\"...\"} piped to the process. Examples: {\"args\":[\"mysql\",\"--protocol=TCP\",\"-h\",\"127.0.0.1\",\"-P\",\"13306\",\"-u\",\"root\",\"-D\",\"app\",\"--vertical\",\"-e\",\"SELECT * FROM t\\\\G\"]}; {\"args\":[\"mysqlshow\",\"--protocol=TCP\",\"-h\",\"127.0.0.1\",\"-P\",\"13306\",\"-u\",\"root\",\"app\"]}; {\"args\":[\"mysql\",\"--protocol=TCP\",\"-h\",\"127.0.0.1\",\"-P\",\"13306\",\"-u\",\"root\",\"-D\",\"app\"],\"stdin\":\"SOURCE /work/schema.sql;\"}."
},
{
"name": "mysql.mysql_help",
"summary": "Return the full `mysql` client help \u2014 every command-line option \u2014 captured from the delivered binary. The reference for what mysql.query / mysql.exec accept."
},
{
"name": "mysql.version",
"summary": "Print the delivered MySQL version, e.g. \"mysql Ver 9.7.1 for \u2026 (conda-forge)\". This is `mysql --version`."
},
{
"name": "mysql.help",
"summary": "Discovery: every method with its params, kind, and latency class \u2014 the self-describing contract."
}
]
}
46 changes: 46 additions & 0 deletions src/data/app-overrides.json
Original file line number Diff line number Diff line change
Expand Up @@ -885,5 +885,51 @@
"publishedAt": "2026-07-07",
"grants": [],
"inCatalogue": true
},
"io.pilot.mysql": {
"name": "MySQL",
"tagline": "Run a real MySQL server from an agent \u2014 full client/server SQL, no cloud account, no provisioning",
"description": "# MySQL \u2014 the world's most popular open-source SQL database, native CLI for agents\n\nThis app installs the official **MySQL 9.7.1** server (`mysqld`) **and** client tools (`mysql`,\n`mysqladmin`, `mysqldump`, `mysqlshow`) on the host and fronts them as typed methods. The bundle is the\nupstream MySQL suite (sha-pinned per OS/arch, fetched from the Pilot artifact registry at install) plus a\ntiny `mysqlctl` dispatcher that makes the server relocatable \u2014 it finds its plugins and error messages\nwherever the bundle is staged.\n\nMySQL is a **real client/server RDBMS** \u2014 the database behind a huge share of the web. Unlike a hosted\nMySQL, there is **no cloud account, no credentials to provision, and no network egress**: the agent runs\n`mysql.initialize` once to lay down a data directory, `mysql.start` to bring up a server on\n`127.0.0.1:<port>`, and then creates databases and runs SQL \u2014 all locally, in its own sandbox. It is the\ntransactional, server-grade complement to the embedded `io.pilot.sqlite` and the analytics-focused\n`io.pilot.duckdb`, and a sibling to `io.pilot.postgres`.\n\n## Why an agent wants this\n\n- **A full local MySQL, zero provisioning.** No RDS, no `docker run`, no credentials. `initialize` \u2192\n `start` \u2192 `createdb` \u2192 `query`, all on `127.0.0.1`.\n- **Real server semantics.** Transactions, InnoDB, foreign keys, triggers, stored routines, JSON columns,\n window functions, full-text indexes \u2014 the actual MySQL engine, not an emulation.\n- **The MySQL dialect + wire protocol.** Test and run exactly what your production MySQL will see: same SQL,\n same `mysqldump` format, same client tools.\n- **Durable + portable.** The data directory is a real MySQL instance the agent can stop, restart, back up\n with `mysql.dump`, or hand off.\n- **Agent-friendly output.** `mysql.query` returns an aligned table; `mysql.query_tsv` returns tab-separated\n values for clean parsing.\n\n## Methods\n\n- `mysql.initialize` \u2014 create a new data directory (system tables + insecure `root`). Run once.\n- `mysql.start` / `mysql.stop` \u2014 bring a server on `127.0.0.1:<port>` up (detached) / down (clean shutdown).\n- `mysql.ping` \u2014 is the server accepting connections?\n- `mysql.createdb` \u2014 create a database.\n- `mysql.query` \u2014 run SQL, get an aligned table. `mysql.query_tsv` \u2014 same, as TSV.\n- `mysql.databases` / `mysql.tables` \u2014 list databases / tables.\n- `mysql.dump` \u2014 mysqldump a database to portable SQL.\n- `mysql.exec` \u2014 run any bundled tool with a verbatim argv (+ optional stdin) for anything the curated\n methods don't cover (`--vertical`, `mysqlshow`, `SOURCE script.sql`, a different output mode, \u2026).\n- `mysql.mysql_help` \u2014 the full `mysql` client help. `mysql.version` \u2014 the delivered version.\n `mysql.help` \u2014 the self-describing method list.\n\n## How to use it (typical flow)\n\n1. **Initialize once:** `mysql.initialize` `{ \"datadir\": \"/work/mysql-data\" }`.\n2. **Start the server:** `mysql.start` `{ \"datadir\": \"/work/mysql-data\", \"port\": \"13306\" }` (then `mysql.ping`).\n3. **Create a database:** `mysql.createdb` `{ \"port\": \"13306\", \"dbname\": \"app\" }`.\n4. **Run SQL:** `mysql.query` `{ \"port\": \"13306\", \"database\": \"app\", \"sql\": \"CREATE TABLE t(id INT PRIMARY KEY, v TEXT); INSERT INTO t VALUES (1,'hi'); SELECT * FROM t;\" }`.\n5. **Back up / stop:** `mysql.dump` `{ \"port\": \"13306\", \"database\": \"app\" }`, then `mysql.stop` `{ \"port\": \"13306\" }`.\n\n## Configuration & connection\n\n- **Connection** is always local: `127.0.0.1:<port>`, user `root`. After `initialize` the root password is\n empty; set one with `mysql.exec` (`ALTER USER 'root'@'localhost' IDENTIFIED BY '\u2026'`) and pass it to later\n calls via the **`MYSQL_PWD`** environment variable (opted into `env_passthrough`).\n- **Data directory** \u2014 each `datadir` is an independent MySQL instance; run several on different ports.\n- **X protocol** is disabled (`--mysqlx=OFF`) for a lean local footprint; the classic protocol is on.\n- **Anything else** \u2014 `mysql.exec` gives you the raw tools: `--vertical`/`--html`/`--xml` output, `mysqlshow`,\n `SOURCE` a script over stdin, or `mysqld`/`mysqladmin` flags the curated methods don't expose.\n\n## Good to know\n\n- On a non-zero exit (SQL error) the reply is `{stdout, stderr, exit}` so the caller sees everything the\n tool produced.\n- Runs on **macOS and Linux** (arm64 + amd64); binaries come from the Pilot artifact registry, sha-pinned on\n install. The server must not run as OS root \u2014 the Pilot daemon runs unprivileged, which is exactly right.\n- MySQL Community Server is **GPL-2.0** licensed. `mysql.help` lists every method with its latency class.\n\n## MySQL client help (`mysql.mysql_help`)\n```\n/tmp/mysql-reloc/mysql-9.7.1-darwin-arm64/bin/mysql Ver 9.7.1 for macos15.7 on arm64 (conda-forge)\nCopyright (c) 2000, 2026, Oracle and/or its affiliates.\n\nOracle is a registered trademark of Oracle Corporation and/or its\naffiliates. Other names may be trademarks of their respective\nowners.\n\nUsage: /tmp/mysql-reloc/mysql-9.7.1-darwin-arm64/bin/mysql [OPTIONS] [database]\n -?, --help Display this help and exit.\n -I, --help Synonym for -?\n --auto-rehash Enable automatic rehashing. One doesn't need to use\n 'rehash' to get table and field completion, but startup\n and reconnecting may take a longer time. Disable with\n --disable-auto-rehash.\n (Defaults to on; use --skip-auto-rehash to disable.)\n -A, --no-auto-rehash \n No automatic rehashing. One has to use 'rehash' to get\n table and field completion. This gives a quicker start of\n mysql and disables rehashing on reconnect.\n --auto-vertical-output \n Automatically switch to vertical output mode if the\n result is wider than the terminal width.\n -B, --batch Don't use history file. Disable interactive behavior.\n (Enables --silent.)\n --bind-address=name IP address to bind to.\n --binary-as-hex Print binary data as hex. Enabled by default for\n interactive terminals.\n --character-sets-dir=name \n Directory for character set files.\n --column-type-info Display column type information.\n --commands Enable or disable processing of local mysql commands.\n -c, --comments Preserve comments. Send comments to the server. The\n default is --comments (keep comments), disable with\n --skip-comments.\n (Defaults to on; use --skip-comments to disable.)\n -C, --compress Use compression in server/client protocol.\n -#, --debug[=#] This is a non-debug version. Catch this and exit.\n --debug-check This is a non-debug version. Catch this and exit.\n -T, --debug-info This is a non-debug version. Catch this and exit.\n -D, --database=name Database to use.\n --default-character-set=name \n Set the default character set.\n --delimiter=name Delimiter to be used.\n --enable-cleartext-plugin \n Enable/disable the clear text authentication plugin.\n -e, --execute=name Execute command and quit. (Disables --force and history\n file.)\n -E, --vertical Print the output of a query (rows) vertically.\n -f, --force Continue even if we get an SQL error.\n --histignore=name A colon-separated list of patterns to keep statements\n from getting logged into syslog and mysql history.\n -G, --named-commands \n Enable named commands. Named commands mean this program's\n internal commands; see mysql> help . When enabled, the\n named commands can be used from any line of the query,\n otherwise only from the first line, before an enter.\n Disable with --disable-named-commands. This option is\n disabled by default.\n -i, --ignore-spaces Ignore space after function names.\n --init-command=name Single SQL Command to execute when connecting to MySQL\n```\n",
"vendor": "Pilot Protocol",
"vendorUrl": "https://pilotprotocol.network",
"license": "GPL-2.0",
"sourceUrl": "https://github.com/mysql/mysql-server",
"homepage": "https://www.mysql.com",
"version": "9.7.1",
"categoriesRaw": [
"database",
"data",
"sql"
],
"keywords": [
"mysql",
"sql",
"database",
"rdbms",
"oltp",
"innodb",
"server",
"query",
"transactional",
"relational"
],
"bundleBytes": 5359647,
"installedBytes": 9634438,
"changelog": [
{
"version": "9.7.1",
"notes": [
"Released v9.7.1"
]
}
],
"minPilotVersion": "1.0.0",
"runtimes": [
"go"
],
"protection": "guarded",
"publishedAt": null,
"grants": [],
"inCatalogue": true
}
}
Loading
Loading