# Tools

Inspect what is in the workspace without changing anything.

- `describe_capabilities` - the QC API knowledge pack. Fetch once per session. Unguarded.
- `list_files(directory?)` - recursive directory listing, depth-limited.
- `read_file(path)` - file contents.
- `search_files(pattern, glob?)` - regex search across the workspace.
- `find_workspace_file(name)` - fuzzy filename lookup.
- `list_strategies()` / `list_indicators()` - everything the discovery service has parsed, including invalid entries with their parse error.
- `workspace_info()` - workspace path, available data files, active strategy/indicator counts.
- `workspace_search(query)` - full-text search across all workspace files.
- `get_app_info()` - QC version, workspace id, license tier.
- `get_example(topic)` - canned snippet for a given API topic.

<a id="file-mutation"></a>
## File mutation

Create / edit / delete / rename. All auth-guarded, sandboxed, with dirty-file refusal.

- `create_file(path, content)` - new file with auto-injected disclaimer header. Refuses to overwrite a dirty file (one with unsaved editor changes).
- `edit_file(path, content)` - replace the entire file. Refuses on dirty files.
- `apply_diff(path, oldText, newText)` - surgical replace. Same dirty-file guard.
- `delete_file(path, reason)` - file only (not directories). Reason is required so the model documents intent. Refuses on dirty files.
- `rename_file(old_path, new_path)` - same workspace; refuses on dirty files; refuses if destination exists.
- `undo_edit(path)` - restore the previous content from one-deep undo history. Only works for the most recent edit_file / create_file.

### Notes

- Windows file locks (file open in Excel, file currently being executed by Python, etc.) surface as `EBUSY/EPERM` and are translated to a friendly "File is locked by another process" error.
- Dirty-file refusal sends back: "File has unsaved changes in the editor. Ask the user to save or discard before retrying."

<a id="notebook-mutation"></a>
## Notebook mutation

Edit Jupyter notebooks cell-by-cell.

- `create_notebook(path, cells)` - new .ipynb with an array of {cell_type, source}.
- `edit_cell(path, cell_id, new_source)` - replace a cell's source.
- `insert_cell(path, cell_id, cell_type, new_source)` - insert after the given cell id.
- `delete_cell(path, cell_id)` - remove a cell.

<a id="data-and-execution"></a>
## Data and execution

Inspect parquet files, run backtests, read results.

- `describe_data_file(path)` - schema, row count, time range, columns.
- `query_parquet(sql)` - DuckDB SQL over a parquet file. Read-only.
- `run_backtest(strategy, params, data_file, date)` - single-day single-combo backtest. Returns stats.
- `run_sweep(strategy, params_grid, ...)` - parameter sweep. Returns the per-combo metrics matrix.
- `get_backtest_results(id?)` - last (or by id) backtest result snapshot.
- `get_equity_curve(id?)` - per-tick equity series.
- `get_last_trades(n)` - the n most recent trades from the active backtest.

<a id="chart-and-runtime"></a>
## Chart and runtime

Drive the active chart and read the terminal buffer.

- `list_chart_instances()` - chart ids and their active strategies / indicators.
- `add_strategy_to_chart(chart_id, file)` / `remove_strategy_from_chart(chart_id, instance_id)`.
- `add_indicator_to_chart(chart_id, file)` / `remove_indicator_from_chart(chart_id, instance_id)`.
- `screenshot_chart(chart_id?)` - PNG bytes of the active chart canvas.
- `read_terminal({lines, since, scriptPath})` - the last N entries from the QC terminal buffer (script output, errors, MCP tool log lines).
- `refresh_workspace()` - rescan strategies/, indicators/, notebooks/ and emit discovery events.
