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

# App config

> waniwani.config.ts names the MCP server, hands the host an overview at connect time, and tunes the template's search tool and tracking.

Every kit app has one `waniwani.config.ts` at its root, default-exporting `defineApp({ ... })`. The CLI reads it to name the server, and the runtime forwards the rest to the host and to the SDK.

```ts waniwani.config.ts theme={null}
import { defineApp } from "@waniwani/kit";

export default defineApp({
  name: "oney",
  title: "Oney: split your payment",
  overview: `You help shoppers split a purchase into instalments with Oney.

RULES:
- Never quote a monthly amount yourself. Call check-eligibility and let it do the arithmetic.
- Never list the plans in text. Show the select-plan widget and let it render them.`,
});
```

## Options

<ResponseField name="name" type="string" required>
  The MCP server name, e.g. `oney-split-payment`. Hosts show `title` to humans and use this one as the id.
</ResponseField>

<ResponseField name="title" type="string">
  Shown to humans in connector UIs.
</ResponseField>

<ResponseField name="version" type="string">
  Defaults to the `version` in the app's `package.json`.
</ResponseField>

<ResponseField name="overview" type="string">
  What this app is and how its tools fit together, handed to the host LLM once in the `initialize` handshake: which tool to reach for, what order things happen in, how to read what comes back, tone, guardrails. Reaches the wire as the MCP server's `instructions`.

  How a single tool behaves belongs in that tool's own `description`. A description travels with every `tools/list` and reaches the model at the moment it is choosing that tool. The overview is read once at connect, so a client that connected before an edit keeps the old copy until it reconnects, and a host is free to drop it altogether. Put nothing load-bearing in it.
</ResponseField>

<ResponseField name="search" type="SearchOptions">
  Tune, or decline, the `search` tool the distribution template ships on top of the [knowledge base](/sdk/knowledge-base/overview).

  <Expandable title="search options">
    <ResponseField name="enabled" type="boolean">
      Whether the template registers the tool at all. `false` is the only way an app can decline it. A deployment with no corpus behind it is better off without the tool than with one answering confidently out of the wrong file.
    </ResponseField>

    <ResponseField name="topK" type="number" default={5}>
      Passages to ask for, 1 to 20.
    </ResponseField>

    <ResponseField name="minScore" type="number" default={0.3}>
      Similarity floor, 0 to 1, under which a passage is dropped rather than ranked last.
    </ResponseField>

    <ResponseField name="metadata" type="Record<string, string>">
      Exact-match filter on chunk metadata. A passage must carry all of these pairs to come back.
    </ResponseField>

    <ResponseField name="timeoutMs" type="number">
      Give up on a slow search and answer as though nothing matched.
    </ResponseField>

    <ResponseField name="includeSources" type="boolean">
      Name the source document on each passage.
    </ResponseField>

    <ResponseField name="preamble" type="string">
      Framing prepended to the answer text. Retrieved passages are third-party text on their way into a prompt; this is where an app says they are reference material rather than instructions.
    </ResponseField>

    <ResponseField name="notFound" type="string">
      The whole answer when no passage comes back: nothing matched, the search outran `timeoutMs`, or the knowledge base failed. An app whose corpus carries regulated information should write both halves in its own words, the refusal the user reads and the human to go to instead. `preamble` is not applied on top of it.
    </ResponseField>

    <ResponseField name="invoking" type="string">
      Status text the host shows while the call is in flight.
    </ResponseField>

    <ResponseField name="invoked" type="string">
      Status text the host shows once the call has returned.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="tracking" type="TrackingOptions">
  Forwarded whole to the SDK's [`withWaniwani()`](/sdk/configuration/wrap-server). Set `WANIWANI_API_KEY` in the app's `.env` for events to reach the platform; without it tracking is a no-op.

  <Expandable title="tracking options">
    <ResponseField name="toolType" type="ToolType | (toolName: string) => ToolType | undefined">
      One category for every tool, or a function mapping a tool name to a category. Categories: `pricing`, `product_info`, `availability`, `support`, `other`.
    </ResponseField>

    <ResponseField name="metadata" type="Record<string, unknown>">
      Merged into every tracked event.
    </ResponseField>

    <ResponseField name="flushAfterToolCall" type="boolean">
      Flush the tracking transport after each tool call. This is the one that matters on serverless: an invocation frozen between tool calls takes any unsent batch with it.
    </ResponseField>

    <ResponseField name="injectWidgetToken" type="boolean" default={true}>
      Put widget tracking config in each tool response's `_meta.waniwani`, so a widget in the browser can send its own events.
    </ResponseField>

    <ResponseField name="stripLocationFields" type="string[]" default="[]">
      Field names to strip from location `_meta` before events are sent. Pass `["latitude", "longitude"]` to drop coordinates and keep the rest.
    </ResponseField>

    <ResponseField name="applyFieldRedactions" type="boolean" default={false}>
      Replace flow state fields marked with `redacted()` before they are tracked. Wire it to an env var to keep real values in development and redact in production.
    </ResponseField>
  </Expandable>
</ResponseField>

## Where each value ends up

| Option            | Reaches                                                           |
| ----------------- | ----------------------------------------------------------------- |
| `name`, `version` | the `McpServer` constructor                                       |
| `title`           | `serverInfo.title`, shown by connector UIs                        |
| `overview`        | `instructions` in the `initialize` response                       |
| `search`          | the template's `search` tool, through the generated `waniwani.ts` |
| `tracking`        | `withWaniwani()` around the server                                |
