> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lilfella.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Built-in tools

> The seven built-in tools, their purposes, and their actual guardrails.

> Built-in tools are application code. The lean release has no dynamic runtime integrations.

## Definition

Fella's standard registry contains seven built-in tools. Adding one requires an application code change. Each has a JSON schema and produces an evidence record.

The experimental MCP boundary is documented separately, but `/mcp` is inert in
the shipped application. No remote tools can enter the default registry.

The extension point is a Rust trait, not a dynamic plugin ABI:

```rust theme={null}
#[async_trait]
pub trait Tool: Send + Sync {
    fn name(&self) -> &'static str;
    fn description(&self) -> &'static str;
    fn parameters(&self) -> serde_json::Value;
    async fn run(
        &self,
        engine: &EngineState,
        args: &serde_json::Value,
    ) -> EngineResult<ToolOutput>;
}
```

`ToolOutput` keeps the model-facing text separate from the data shown in the evidence panel:

```rust theme={null}
pub struct ToolOutput {
    pub summary: String,
    pub llm_text: String,
    pub sql: Option<String>,
    pub columns: Option<Vec<String>>,
    pub rows: Option<Vec<Vec<serde_json::Value>>>,
    pub row_count: Option<usize>,
    pub output: Option<String>,
    pub chart: Option<ChartData>,
}
```

The standard registry is explicit:

```rust theme={null}
tools: vec![
    Box::new(ListFiles),
    Box::new(InspectTable),
    Box::new(RunSql),
    Box::new(GrepFiles),
    Box::new(ReadFile),
    Box::new(RunPython),
    Box::new(MakeChart),
],
```

`inspect_table` is the current combined interface; older commits had separate `describe_schema` and `sample_rows` concepts. [PR #52](https://github.com/Avijit-Kumar-GIT/fella/pull/52) merged that surface so schema statistics and sample rows travel through one tool.

## Architecture

| Built-in        | Purpose                                    | Enforced behavior                                                                                                                                                       |
| --------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_files`    | List recognized workspace files and tables | Reads the workspace catalog                                                                                                                                             |
| `inspect_table` | Return schema statistics and sample rows   | Resolves a known table; requested sample is capped                                                                                                                      |
| `run_sql`       | Filter, join, group, and aggregate tables  | Guarded SQL through the active local data engine; results and runtime are capped                                                                                        |
| `grep_files`    | Search document text                       | Case-insensitive regex over cataloged documents; 30 hits by default and 100 maximum                                                                                     |
| `read_file`     | Read cataloged document bodies             | Resolves one or more catalogued names; 12,000 characters per document and 16,000 characters combined                                                                    |
| `run_python`    | Run analysis that is awkward in SQL        | Embedded WASM/RustPython guest with no filesystem, network, environment, or subprocess imports; fuel, memory, stack, source, output, SQL-row, and SQL-response limits   |
| `make_chart`    | Build a bar or line chart from a query     | Runs a guarded read-only query, derives the first column as labels and the next one or two columns as numeric series, then validates the result before client rendering |

The built-ins are offered when a workspace is open. With no workspace, the model
receives no data tools.

Every successful call is translated into a `ToolOutput` and then an `EvidenceItem` with a stable ordered ID for that answer. SQL-backed evidence also maps referenced tables to catalogued files or workbook sheets and retains source-level ingest notes when present. The output has a human-facing summary, compact model text, and optional SQL, columns, rows, text output, or structured chart data. `make_chart` derives its chart values from its own read-only query, so the chart evidence retains the SQL, result rows, and source mapping; it never accepts or emits SVG/HTML. `ChartData` is rendered by the Svelte client. Failed calls are also recorded with an error, summary, and elapsed time rather than disappearing from the run.

## Flow

For tables, the expected path is inspection when needed followed by `run_sql`. For documents, the model uses `grep_files` to locate text and `read_file` for context; `read_file` accepts either `name` or a `names` array and labels combined documents. `make_chart` receives a query, executes it through the guarded data path, and derives the chart values itself. The first query column becomes labels; the next one or two become series.

`run_python` provides `sql(query)`, which returns a bounded list of dictionaries from the host's read-only data engine. The built-in `median`, `stdev`, `pearsonr`, and `linregress` helpers cover the small calculations SQL handles poorly. The embedded guest has no pandas, NumPy, SciPy, package installer, or system Python dependency.

## Behavior

SQL is preferred because the query and rows are straightforward to display and rerun. `run_sql` accepts a single guarded read-only query, and the SQLite query connection is opened read-only. Direct file-reading SQL functions are blocked.

There is no MCP execution path in the personal release. A future connector
must preserve the fixed evidence and verification boundary before it can become
an official feature.

## Limits

* Python runs in a fresh embedded WASM guest with no filesystem, network, environment, or subprocess capability. Wasmi fuel, memory, stack, source, output, SQL-row, and SQL-response limits bound the calculation; Wasmi, RustPython, and the checked-in guest remain part of the trusted computing base.
* The Python guest's fuel, memory, stack, source, output, SQL-row, and SQL-response limits are cross-platform; the host SQL watchdog applies to each SQL call.
* Tool outputs are capped, so evidence can contain a sample rather than every returned row or character.

Direct `/sql` is deliberately outside this registry path: it calls the engine directly, prints a system result, and does not create an assistant evidence fold or invoke post-answer verification.

## Next steps

<CardGroup cols={2}>
  <Card title="The harness" icon="workflow" href="/concepts/harness">
    Follow tool selection, execution, caching, and stopping.
  </Card>

  <Card title="Experimental MCP" icon="puzzle" href="/extensions-and-mcp">
    Read the inert extension boundary for future forks.
  </Card>

  <Card title="Verification" icon="badge-check" href="/concepts/verification">
    See which results can be checked after the answer.
  </Card>

  <Card title="The engine" icon="database" href="/concepts/engine">
    Understand the local SQL and document paths behind the tools.
  </Card>
</CardGroup>
