-
Notifications
You must be signed in to change notification settings - Fork 5
docs: canonicalize AGENTS.md as the agent guide and freshen against code #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jack-arturo
wants to merge
3
commits into
main
Choose a base branch
from
docs/agents-md-canonical
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+149
−110
Draft
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| # AGENTS.md | ||
|
|
||
| This file provides guidance to coding agents (Claude Code, Cursor, Codex, and others) when working with code in this repository. | ||
|
|
||
| ## Commands | ||
|
|
||
| ### Build & Development | ||
| - **Build TypeScript**: `npm run build` - Compiles TypeScript to JavaScript in `dist/` (also runs `postbuild` to `chmod +x dist/index.js`) | ||
| - **Development mode**: `npm run dev` - Runs with tsx watch for hot reload | ||
| - **Start compiled**: `npm start` or `node dist/index.js` - Run the compiled server | ||
| - **Smoke test**: `npm test` - Prints a build-ok message (no real test suite yet) | ||
|
|
||
| ### Code Quality | ||
| - **Lint**: `npm run lint` - Check ESLint issues | ||
| - **Fix lint**: `npm run lint:fix` - Auto-fix ESLint issues | ||
| - **Format**: `npm run format` - Format with Prettier | ||
| - **Check format**: `npm run format:check` - Verify Prettier formatting | ||
|
|
||
| ### Testing & Debugging | ||
| - **Enable debug logs**: Set `DEBUG=mcp-local-wp` environment variable | ||
| - **Test connection**: After building, run `node dist/index.js` to verify MySQL connection | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Core Components | ||
|
|
||
| 1. **`src/index.ts`** - MCP server entry point | ||
| - Sets up StdioServerTransport for agent communication | ||
| - Registers the MCP tools and routes `CallToolRequest`s | ||
| - Auto-detects Local by Flywheel or falls back to environment variables | ||
| - Reads `MYSQL_ALLOW_WRITES` at startup to decide whether to expose the write tool (`src/index.ts:18`) | ||
|
|
||
| 2. **`src/local-detector.ts`** - Local by Flywheel auto-detection and site selection | ||
| - `selectSite()` implements the 5-level priority order (`src/local-detector.ts:315`) | ||
| - Loads/parses Local's `sites.json` for site metadata (name, path, domain, port) | ||
| - Scans running processes for mysqld with Local paths; filesystem fallback by socket mtime | ||
| - `listAvailableSites()` enumerates configured sites and running status (`src/local-detector.ts:413`) | ||
|
|
||
| 3. **`src/mysql-client.ts`** - MySQL connection management | ||
| - Wraps mysql2/promise for async operations | ||
| - `executeReadOnlyQuery()` validates read-only statements (`src/mysql-client.ts:46`) | ||
| - `executeWriteQuery()` validates gated write statements (`src/mysql-client.ts:76`) | ||
| - Blocks multi-statement queries for security | ||
| - Supports parameter binding with `?` placeholders | ||
|
|
||
| 4. **`src/types.ts`** - TypeScript interfaces | ||
| - `LocalSiteInfo`: socket path, port, site ID, config path | ||
| - `MySQLConnectionConfig`: connection parameters | ||
| - `WriteResult`: affectedRows, optional insertId/changedRows | ||
| - `LocalSiteEntry` / `LocalSitesConfig` / `SiteSelectionResult`: site metadata + selection context | ||
|
|
||
| ### MCP Tools | ||
|
|
||
| The server registers **4 tools by default**. A **5th tool, `mysql_write`, is registered only when `MYSQL_ALLOW_WRITES=true`** (`src/index.ts:134`). | ||
|
|
||
| **mysql_query**: | ||
| - Executes read-only SQL queries | ||
| - Parameters: `sql` (string), optional `params` (array) | ||
| - Enforces single statement, read-only operations (SELECT/SHOW/DESCRIBE/DESC/EXPLAIN) | ||
|
|
||
| **mysql_schema**: | ||
| - Inspects database structure via INFORMATION_SCHEMA | ||
| - No params: lists all tables with engine/row counts/sizes | ||
| - With `table` param: shows columns and indexes | ||
|
|
||
| **mysql_current_site**: | ||
| - Returns the currently connected Local site (name, ID, path, domain, socket, port) and the `selectionMethod` used | ||
|
|
||
| **mysql_list_sites**: | ||
| - Lists all configured Local sites and whether each is running | ||
|
|
||
| **mysql_write** (only when `MYSQL_ALLOW_WRITES=true`): | ||
| - Executes INSERT/UPDATE/DELETE; schema operations (CREATE/DROP/ALTER/TRUNCATE) are blocked | ||
| - UPDATE and DELETE require a non-empty `params` array (at least one bound parameter); the guard does not verify that a WHERE clause is present | ||
| - Subqueries (SELECT) are rejected inside write statements | ||
|
|
||
| ### Security Model | ||
|
|
||
| - **Read path**: regex validates the first token is one of SELECT/SHOW/DESCRIBE/DESC/EXPLAIN (`src/mysql-client.ts:46`) | ||
| - **Gated write path**: writes are off unless `MYSQL_ALLOW_WRITES=true`. When enabled, only INSERT/UPDATE/DELETE are allowed; UPDATE/DELETE require a non-empty `params` array (at least one bound parameter; a WHERE clause is not verified); subqueries are blocked (`src/mysql-client.ts:76`) | ||
| - **Single statement only**: more than one non-empty statement (split on `;`) is rejected | ||
| - **Parameter binding**: uses mysql2's parameterized queries to prevent injection | ||
| - **Local-only design**: prioritizes Unix socket connections | ||
| - **Identifier safety**: table names used in schema introspection are restricted to `[A-Za-z0-9_]` | ||
|
|
||
| ## Local by Flywheel Integration | ||
|
|
||
| The server solves Local's dynamic path problem where site IDs (like `lx97vbzE7`) change on restart. | ||
|
|
||
| ### Site selection priority (`selectSite()`) | ||
|
|
||
| 1. `SITE_ID` env var — direct site ID lookup in `sites.json` | ||
| 2. `SITE_NAME` env var — case-insensitive site-name lookup | ||
| 3. CWD detection — current working directory matched against a site's path | ||
| 4. Process detection — running mysqld with a Local `--defaults-file` argument | ||
| 5. Filesystem fallback — newest running socket under Local's run directory | ||
|
|
||
| If none of the above resolve, the server falls back to plain environment variables. | ||
|
|
||
| Typical Local paths: | ||
| - Config: `~/Library/Application Support/Local/run/{siteId}/conf/mysql/my.cnf` | ||
| - Socket: `~/Library/Application Support/Local/run/{siteId}/mysql/mysqld.sock` | ||
| - Sites metadata: `~/Library/Application Support/Local/sites.json` | ||
| - Database name: `local` | ||
| - Credentials: `root`/`root` | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| ### Connection fallback (used when Local isn't detected or for custom setups) | ||
| - `MYSQL_HOST` - Default: localhost | ||
| - `MYSQL_PORT` - Default: 3306 | ||
| - `MYSQL_USER` - Default: root | ||
| - `MYSQL_PASS` - Default: root | ||
| - `MYSQL_DB` - Default: local | ||
| - `MYSQL_SOCKET_PATH` - Unix socket path (optional) | ||
|
|
||
| ### Behavior | ||
| - `MYSQL_ALLOW_WRITES` - Set to `true` to expose the `mysql_write` tool (default: writes disabled) | ||
| - `DEBUG` - Include `mcp-local-wp` to enable debug logging | ||
|
|
||
| ### Site selection / Local paths | ||
| - `SITE_ID` - Explicit Local site ID (highest priority) | ||
| - `SITE_NAME` - Local site name for lookup | ||
| - `LOCAL_RUN_DIR` - Override Local's run directory | ||
| - `LOCAL_SITES_JSON` - Override path to Local's `sites.json` | ||
|
|
||
| On Windows, default Local paths resolve via `%LOCALAPPDATA%` / `%APPDATA%`. | ||
|
|
||
| ## Development Workflow | ||
|
|
||
| 1. Ensure Local by Flywheel is running with an active site | ||
| 2. Make changes to TypeScript source files | ||
| 3. Run `npm run dev` for development with hot reload | ||
| 4. For production: `npm run build` then test with `npm start` | ||
| 5. Use `npm run lint:fix` and `npm run format` before committing | ||
|
|
||
| ## WordPress Database Patterns | ||
|
|
||
| Common WordPress tables and their purposes: | ||
| - `wp_posts` - Posts, pages, attachments, custom post types | ||
| - `wp_postmeta` - Custom fields and post metadata | ||
| - `wp_options` - Site settings and plugin options | ||
| - `wp_users` - User accounts | ||
| - `wp_usermeta` - User metadata and capabilities | ||
| - `wp_terms`, `wp_term_taxonomy`, `wp_term_relationships` - Taxonomies (categories, tags) | ||
| - `wp_comments`, `wp_commentmeta` - Comments and metadata | ||
|
|
||
| Note: Table prefix may vary (default is `wp_` but could be custom). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,110 +1 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Commands | ||
|
|
||
| ### Build & Development | ||
| - **Build TypeScript**: `npm run build` - Compiles TypeScript to JavaScript in `dist/` | ||
| - **Development mode**: `npm run dev` - Runs with tsx watch for hot reload | ||
| - **Start compiled**: `npm start` or `node dist/index.js` - Run the compiled server | ||
|
|
||
| ### Code Quality | ||
| - **Lint**: `npm run lint` - Check ESLint issues | ||
| - **Fix lint**: `npm run lint:fix` - Auto-fix ESLint issues | ||
| - **Format**: `npm run format` - Format with Prettier | ||
| - **Check format**: `npm run format:check` - Verify Prettier formatting | ||
|
|
||
| ### Testing & Debugging | ||
| - **Enable debug logs**: Set `DEBUG=mcp-local-wp` environment variable | ||
| - **Test connection**: After building, run `node dist/index.js` to verify MySQL connection | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Core Components | ||
|
|
||
| 1. **`src/index.ts`** - MCP server entry point | ||
| - Sets up StdioServerTransport for Claude/Cursor communication | ||
| - Implements two tools: `mysql_query` and `mysql_schema` | ||
| - Auto-detects Local by Flywheel or falls back to environment variables | ||
|
|
||
| 2. **`src/local-detector.ts`** - Local by Flywheel auto-detection | ||
| - Scans running processes for mysqld with Local paths | ||
| - Extracts socket path from process arguments | ||
| - Parses my.cnf for port configuration | ||
| - Returns LocalSiteInfo with connection details | ||
|
|
||
| 3. **`src/mysql-client.ts`** - MySQL connection management | ||
| - Wraps mysql2/promise for async operations | ||
| - Validates queries are read-only (SELECT/SHOW/DESCRIBE/EXPLAIN) | ||
| - Blocks multi-statement queries for security | ||
| - Supports parameter binding with `?` placeholders | ||
|
|
||
| 4. **`src/types.ts`** - TypeScript interfaces | ||
| - LocalSiteInfo: socket path, port, site ID, config path | ||
| - MySQLConnectionConfig: connection parameters | ||
|
|
||
| ### MCP Tools | ||
|
|
||
| **mysql_query**: | ||
| - Executes read-only SQL queries | ||
| - Parameters: `sql` (string), optional `params` (array) | ||
| - Enforces single statement, read-only operations | ||
|
|
||
| **mysql_schema**: | ||
| - Inspects database structure via INFORMATION_SCHEMA | ||
| - No params: lists all tables with row counts | ||
| - With `table` param: shows columns and indexes | ||
|
|
||
| ### Security Model | ||
|
|
||
| - **Read-only enforcement**: Regex validates queries start with SELECT/SHOW/DESCRIBE/EXPLAIN | ||
| - **Single statement only**: Semicolons blocked except at end | ||
| - **Parameter binding**: Uses mysql2's parameterized queries to prevent injection | ||
| - **Local-only design**: Prioritizes Unix socket connections | ||
|
|
||
| ## Local by Flywheel Integration | ||
|
|
||
| The server solves Local's dynamic path problem where site IDs (like `lx97vbzE7`) change on restart: | ||
|
|
||
| 1. Process detection finds running mysqld with `--defaults-file` argument | ||
| 2. Extracts site directory from config path (e.g., `/Users/.../Local/run/lx97vbzE7/`) | ||
| 3. Constructs socket path: `{siteDir}/mysql/mysqld.sock` | ||
| 4. Falls back to environment variables if Local isn't detected | ||
|
|
||
| Typical Local paths: | ||
| - Config: `~/Library/Application Support/Local/run/{siteId}/conf/mysql/my.cnf` | ||
| - Socket: `~/Library/Application Support/Local/run/{siteId}/mysql/mysqld.sock` | ||
| - Database name: `local` | ||
| - Credentials: `root`/`root` | ||
|
|
||
| ## Environment Variables (Fallback) | ||
|
|
||
| When Local isn't detected or for custom setups: | ||
| - `MYSQL_HOST` - Default: localhost | ||
| - `MYSQL_PORT` - Default: 3306 | ||
| - `MYSQL_USER` - Default: root | ||
| - `MYSQL_PASS` - Default: root | ||
| - `MYSQL_DB` - Default: local | ||
| - `MYSQL_SOCKET_PATH` - Unix socket path (optional) | ||
|
|
||
| ## Development Workflow | ||
|
|
||
| 1. Ensure Local by Flywheel is running with an active site | ||
| 2. Make changes to TypeScript source files | ||
| 3. Run `npm run dev` for development with hot reload | ||
| 4. For production: `npm run build` then test with `npm start` | ||
| 5. Use `npm run lint:fix` and `npm run format` before committing | ||
|
|
||
| ## WordPress Database Patterns | ||
|
|
||
| Common WordPress tables and their purposes: | ||
| - `wp_posts` - Posts, pages, attachments, custom post types | ||
| - `wp_postmeta` - Custom fields and post metadata | ||
| - `wp_options` - Site settings and plugin options | ||
| - `wp_users` - User accounts | ||
| - `wp_usermeta` - User metadata and capabilities | ||
| - `wp_terms`, `wp_term_taxonomy`, `wp_term_relationships` - Taxonomies (categories, tags) | ||
| - `wp_comments`, `wp_commentmeta` - Comments and metadata | ||
|
|
||
| Note: Table prefix may vary (default is `wp_` but could be custom). | ||
| @AGENTS.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.