# Nora search · developer preview

Nora lets a broker describe a client's office requirements in plain language. It turns the request into editable criteria, searches the Broker Tool's live listings over MCP, and explains every result.

## Open it

No build step and no installs.

- **`index.html`** is the developer preview: concept, desktop and mobile prototypes, and build notes. Open it in a browser.
- **`screens/Prototype.html`** is the full clickable prototype. These links open it in a specific state:
  - `#ask` opens the dashboard with the example request filled in.
  - `#nora` runs the example search.
  - `#nora-near` runs a search with no exact matches.
  - `#detail` runs the example search and opens the first listing.

If your browser blocks local iframes, serve the folder instead, for example with `npx serve .` or `python3 -m http.server`.

## Run the rule tests

```
node tests/engine.test.js       # 16 tests, Node 18+
node tests/generate-examples.js # rewrites mcp/examples/*.json from the mock
```

## Layout

| Path | What it is |
| --- | --- |
| `src/broker-tool-mock.js` | Stands in for the Broker Tool MCP server. It holds the sample inventory, `search_spaces`, `get_space_details`, the match rules and the ranking. This logic belongs in the Broker Tool, not in Nora. |
| `src/nora.js` | Turns the request into criteria (`interpret`, `toArgs`) and builds the summary and reasons (`describe`, `explain`). It reads only fields that the tool returned. |
| `src/app.js` | The dashboard and Nora UI. |
| `src/util.js` | Shared formatting helpers. |
| `mcp/tools.json` | MCP tool definitions with input and output JSON Schemas. |
| `mcp/examples/` | Request and response pairs generated from the mock. |
| `tests/` | The rule tests and a VM loader that runs the browser files in Node. |

The `src` files are plain classic scripts that share globals, so they load in order without a bundler. Turn them into modules when you port them.

## What's mocked

- **Inventory.** There are 22 sample listings. The addresses, fields and dates are illustrative only. Verification dates are relative to today, so the prototype doesn't go stale.
- **Interpretation.** `interpret()` is rule-based (regex and keywords). In production it's a model call that must return the same criteria shape, validated against `mcp/tools.json` → `search_spaces.inputSchema`. The production contract adds `unparsed`, which the prototype doesn't implement.
- **Permissions.** These aren't enforced in the mock. The real MCP server applies the broker's existing visibility rules on both tools.
- **Other dashboard buttons.** Anything outside Nora on the dashboard is static.
