Skip to content

Serve JSON-RPC

tonic serve --stdio speaks newline-delimited JSON-RPC 2.0 over standard input and output.

{"jsonrpc":"2.0","id":1,"method":"targets.list","params":{}}
{"jsonrpc":"2.0","id":1,"result":{"targets":[]}}
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "target \"warehouse\" not found",
"data": {
"code": "TONIC_TARGET_NOT_FOUND"
}
}
}

Stable service error codes include TONIC_TARGET_REQUIRED, TONIC_TARGET_NOT_FOUND, TONIC_INVALID_CONTEXT, TONIC_INVALID_SQL, TONIC_SESSION_NOT_FOUND, TONIC_TRANSACTION_REQUIRED, TONIC_PERMISSION_DENIED, TONIC_UNSUPPORTED, TONIC_INVALID_STATEMENT, and TONIC_EXECUTION_ERROR.

{"jsonrpc":"2.0","id":1,"method":"targets.list","params":{}}
{
"targets": [
{
"name": "warehouse",
"backend": "snowflake",
"context": {
"database": "ANALYTICS",
"schema": "PUBLIC",
"warehouse": "COMPUTE_WH",
"role": "ANALYST"
}
}
]
}

targets.ping accepts {"target":"warehouse"} and returns the resolved target summary.

{
"jsonrpc": "2.0",
"id": 2,
"method": "query.executeInline",
"params": {
"target": "warehouse",
"sql": "select 1 as id",
"context": {"schema": "PUBLIC"},
"autocommit": "on"
}
}

Inline execution is request-scoped. The session opens for the request and closes before the response returns.

query.planArtifact parses source text and resolves statement metadata without executing SQL.

query.executeArtifact executes either the whole artifact or one 1-based statement index.

{
"text": "-- tonic-file: target=warehouse\nselect 1;",
"path": "/repo/query.sql",
"target": "fallback-target",
"context": {"schema": "PUBLIC"},
"autocommit": "on",
"statement": 1
}

For service requests, text is the source of truth. path is diagnostic metadata only.

Open a session:

{"target":"warehouse","context":{"schema":"PUBLIC"},"autocommit":"off"}

The result includes a process-local session ID such as sess_1.

Execute one statement on a session:

{"session":"sess_1","sql":"update jobs set touched_at = current_timestamp where id = 1"}

Close a session:

{"session":"sess_1"}

Statement errors do not automatically close a reusable session. Closing a session rolls back any open transaction best-effort.

Inspect methods mirror the CLI and all accept refresh where applicable:

  • inspect.catalogs
  • inspect.namespaces
  • inspect.tables
  • inspect.views
  • inspect.columns
  • inspect.viewDefinition
  • inspect.ddl

Example:

{
"target": "warehouse",
"catalog": "ANALYTICS",
"namespace": "PUBLIC",
"includeAll": false,
"refresh": true
}