You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add parameterized query support to run_sql and expand db docs
- MCP run_sql tool and CLI projects sql now accept optional params array
- When params provided, sends JSON body { sql, params } instead of text/plain
- CLI accepts --params '[1, "hello"]' flag with JSON validation
- SKILL.md expanded with db.sql() return type, parameterized examples,
and full db.from() chainable API documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
try{params=JSON.parse(paramsRaw);}catch{console.error(JSON.stringify({status: "error",message: "Invalid JSON for --params. Expected a JSON array, e.g. '[42, \"hello\"]'"}));process.exit(1);}
136
+
if(!Array.isArray(params)){console.error(JSON.stringify({status: "error",message: "--params must be a JSON array, e.g. '[42, \"hello\"]'"}));process.exit(1);}
The `@run402/functions` Lambda runtime has expanded `db.sql()` to accept params and `db.from()` with a full chainable API. The SKILL.md documentation only shows a minimal 2-line example.
8
+
9
+
This repo's MCP tool (`run-sql.ts`) and CLI (`projects.mjs`) currently send plain text only. They need a JSON path for params.
10
+
11
+
## Goals / Non-Goals
12
+
13
+
**Goals:**
14
+
- MCP `run_sql` and CLI `projects sql` support optional parameterized queries
15
+
- SKILL.md documents the full `db.sql()` and `db.from()` API matching llms.txt
- Changing the API endpoint behavior (already done in run402)
20
+
- Adding params support to `rest_query` (uses PostgREST, not raw SQL)
21
+
- Changing the response format (already returns `{ status, schema, rows, rowCount }`)
22
+
23
+
## Decisions
24
+
25
+
**1. JSON body when params present, plain text otherwise**
26
+
27
+
When `params` is provided and non-empty, send `Content-Type: application/json` with `{ sql, params }`. When omitted, keep existing `text/plain` with raw SQL body. This maintains backward compatibility and avoids unnecessary format changes.
28
+
29
+
Alternative: Always send JSON. Rejected because it changes behavior for all callers and the API still has the text/plain path documented.
30
+
31
+
**2. CLI `--params` as JSON array string**
32
+
33
+
The CLI accepts `--params '[1, "hello"]'` as a JSON string that gets parsed. This matches common CLI patterns (e.g., `aws --cli-input-json`). Alternative: positional args after `--` separator. Rejected as harder to parse and ambiguous with mixed types.
34
+
35
+
**3. SKILL.md docs mirror llms.txt structure**
36
+
37
+
Copy the expanded db.sql() and db.from() documentation directly from the llms.txt diff. This keeps the two sources consistent and avoids documentation drift.
38
+
39
+
## Risks / Trade-offs
40
+
41
+
-[Params type safety] CLI params arrive as a JSON string — invalid JSON will fail at parse time. → Mitigation: validate with `JSON.parse()` and give a clear error message.
42
+
-[SKILL.md size] Adding ~15 lines of API docs. → Acceptable; this is the primary reference for agents using functions.
The run402 API now supports parameterized queries on `POST /projects/v1/admin/:id/sql` (accepts JSON `{ sql, params }`) and the `@run402/functions` Lambda runtime has expanded `db.sql(query, params?)` and `db.from(table)` APIs. The MCP tool, CLI command, and SKILL.md documentation are out of sync with these backend capabilities.
4
+
5
+
## What Changes
6
+
7
+
-**MCP `run_sql` tool**: Add optional `params` array to schema. When provided, send `Content-Type: application/json` with `{ sql, params }` instead of plain text.
8
+
-**CLI `projects sql` command**: Add `--params` flag accepting a JSON array string. Same JSON body behavior.
9
+
-**SKILL.md**: Expand "DB access inside functions" section to document `db.sql()` return type, parameterized query support, and full `db.from()` chainable API (matching llms.txt).
10
+
- OpenClaw inherits CLI changes automatically via shims.
11
+
12
+
## Capabilities
13
+
14
+
### New Capabilities
15
+
-`parameterized-sql`: Add parameterized query support to the `run_sql` MCP tool and CLI `projects sql` command
16
+
-`functions-db-docs`: Expand SKILL.md documentation for `db.sql()` and `db.from()` runtime helpers
17
+
18
+
### Modified Capabilities
19
+
20
+
## Impact
21
+
22
+
-`src/tools/run-sql.ts` — schema + handler changes (JSON body path)
23
+
-`src/tools/run-sql.test.ts` — new test cases for params
24
+
-`cli/lib/projects.mjs` — `sqlCmd` changes for `--params` flag
25
+
-`SKILL.md` — expanded DB section (~15 lines replacing 2)
26
+
-`sync.test.ts` — no surface changes (same tool names), but verify tests pass
The MCP `run_sql` tool schema SHALL accept an optional `params` field of type array. When `params` is provided and non-empty, the tool SHALL send the request as `Content-Type: application/json` with body `{ "sql": "<sql>", "params": [...] }`. When `params` is omitted or empty, the tool SHALL send `Content-Type: text/plain` with the raw SQL string as body (existing behavior).
5
+
6
+
#### Scenario: Parameterized query via MCP
7
+
-**WHEN**`run_sql` is called with `sql: "SELECT * FROM users WHERE id = $1"` and `params: [42]`
8
+
-**THEN** the tool sends a POST to `/projects/v1/admin/:id/sql` with `Content-Type: application/json` and body `{"sql":"SELECT * FROM users WHERE id = $1","params":[42]}`
9
+
10
+
#### Scenario: Plain SQL via MCP (backward compat)
11
+
-**WHEN**`run_sql` is called with `sql: "SELECT 1"` and no `params`
12
+
-**THEN** the tool sends a POST with `Content-Type: text/plain` and body `SELECT 1`
13
+
14
+
#### Scenario: Empty params array treated as no params
15
+
-**WHEN**`run_sql` is called with `sql: "SELECT 1"` and `params: []`
16
+
-**THEN** the tool sends a POST with `Content-Type: text/plain` and body `SELECT 1`
17
+
18
+
### Requirement: CLI projects sql accepts --params flag
19
+
The CLI `projects sql` command SHALL accept an optional `--params` flag whose value is a JSON array string. When provided, the CLI SHALL parse the JSON and send the request as `application/json` with `{ sql, params }`. Invalid JSON SHALL cause the command to exit with an error message.
20
+
21
+
#### Scenario: Parameterized query via CLI
22
+
-**WHEN** user runs `run402 projects sql <id> "SELECT * FROM t WHERE id = $1" --params '[42]'`
23
+
-**THEN** the CLI sends a JSON body with sql and params to the API
The MCP `run_sql` tool schema SHALL accept an optional `params` field of type array. When `params` is provided and non-empty, the tool SHALL send the request as `Content-Type: application/json` with body `{ "sql": "<sql>", "params": [...] }`. When `params` is omitted or empty, the tool SHALL send `Content-Type: text/plain` with the raw SQL string as body (existing behavior).
3
+
4
+
#### Scenario: Parameterized query via MCP
5
+
-**WHEN**`run_sql` is called with `sql: "SELECT * FROM users WHERE id = $1"` and `params: [42]`
6
+
-**THEN** the tool sends a POST to `/projects/v1/admin/:id/sql` with `Content-Type: application/json` and body `{"sql":"SELECT * FROM users WHERE id = $1","params":[42]}`
7
+
8
+
#### Scenario: Plain SQL via MCP (backward compat)
9
+
-**WHEN**`run_sql` is called with `sql: "SELECT 1"` and no `params`
10
+
-**THEN** the tool sends a POST with `Content-Type: text/plain` and body `SELECT 1`
11
+
12
+
#### Scenario: Empty params array treated as no params
13
+
-**WHEN**`run_sql` is called with `sql: "SELECT 1"` and `params: []`
14
+
-**THEN** the tool sends a POST with `Content-Type: text/plain` and body `SELECT 1`
15
+
16
+
### Requirement: CLI projects sql accepts --params flag
17
+
The CLI `projects sql` command SHALL accept an optional `--params` flag whose value is a JSON array string. When provided, the CLI SHALL parse the JSON and send the request as `application/json` with `{ sql, params }`. Invalid JSON SHALL cause the command to exit with an error message.
18
+
19
+
#### Scenario: Parameterized query via CLI
20
+
-**WHEN** user runs `run402 projects sql <id> "SELECT * FROM t WHERE id = $1" --params '[42]'`
21
+
-**THEN** the CLI sends a JSON body with sql and params to the API
0 commit comments