saleroom
README.md
# saleroom
What did that watch actually sell for — and what is one worth
today? saleroom is a read-only client for the altfinance
auction-results service, which tracks realized prices across
twenty luxury categories: watches, handbags, jewelry, gems,
cars and motorcycles, aircraft, wine and whisky, art, design,
fashion, coins and more. You can list the tables, inspect a
table's columns, run filtered and sorted queries over the
sales history, read summary statistics and price trends, ask
for a fair-value range on a single item, search the whole
market at once, consult a precomputed brand/model price
index, and view price alerts.
Nothing here trades, bids or changes anything: all nine
tools only read. Responses come back exactly as the service
returned them — nothing is trimmed, renamed or summarised on
the way through.
## Configuration
Two environment variables control the client:
- `ALTFINANCE_API_KEY` (required) — sent on every request
as `Authorization: Bearer <key>`. When it is not set,
every tool fails with `ALTFINANCE_API_KEY is not set`
before any request is made.
- `ALTFINANCE_API_URL` (optional) — API base URL. Defaults
to `https://api.altfndata.com`.
## Tools
- `list_tables` — the available auction tables, with live
descriptions and column counts. No arguments.
- `get_table_schema` — column names and types for one
table. Takes `table` (required).
- `query_table` — query a table with `filters`, `sort`,
`fields` selection and pagination (`limit` 1–500,
`offset` ≥ 0). Takes `table` (required) plus the optional
arguments.
- `market_stats` — a realized-price summary for a table or
a filtered segment: count, median, percentiles, average,
min/max, sale-date span and top vendors. Takes `table`
(required) and optional `filters`.
- `price_trend` — how realized prices moved over time,
bucketed by `year`, `quarter` or `month`. Takes `table`
(required), optional `bucket` and optional `filters`.
- `price_check` — a fair-value range for a single item from
comparable sales, with source links. Takes `item`
(required) and optional `category`. Live categories are
handbags, watches and cars.
- `search` — whole-market keyword search across every
category at once, merged by realized price. Takes
`query` (required) and optional `category`.
- `market_index` — a precomputed model-level price index
for a brand or model (handbags, watches, cars). Takes
`query` (required) and optional `category`.
- `list_alerts` — a read-only view of price alerts, or
guidance on enabling them. No arguments.
The twenty tables are: `watches`, `handbags`, `jewelry`,
`gems`, `automobile`, `motorcycle`, `aircraft`,
`wine_whisky`, `works_of_art`, `fine_art`, `design`,
`fashion`, `shoes`, `automobilia`, `books`, `coins`,
`other_automobile`, `perfume`, `accessories` and
`musical_instruments`.
A filter is `{column, operator, value}`. The operators are
`eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `in`,
`not_in`, `is_null` and `is_not_null`. Omit `value` for
`is_null` / `is_not_null`; pass an array for `in` /
`not_in`. A sort is `{field, direction}` with direction
`asc` or `desc`.
Validation happens before any request. An unknown operator
fails with `unknown filter operator: <op>`; a missing value
where one is required fails with `filter value is required
for operator <op>`; a `limit` outside 1–500 fails with
`limit must be an integer between 1 and 500`. An upstream
non-2xx reply fails with `altfinance error: HTTP <status>`
and an unreachable API with `altfinance unreachable`.
### Endpoint provenance
The original service's project record pins the nine tools,
the twenty table names, the filter operators, the sorting,
field-selection and pagination rules, the trend buckets and
the two environment variables — and that all nine endpoints
are read-only. It does not pin the per-tool argument names
beyond its prose, the filter/sort JSON shapes, the auth
header or the request paths. Those pieces are
reconstructions, labelled as such:
- `Authorization: Bearer <key>` header — reconstruction
(the record pins API-key authentication only).
- `GET <base>/v1/tables` — `list_tables`.
- `GET <base>/v1/tables/{table}/schema` —
`get_table_schema`.
- `POST <base>/v1/tables/{table}/query` with body
`{filters?, sort?, fields?, limit?, offset?}` (unset
fields omitted) — `query_table`.
- `POST <base>/v1/tables/{table}/stats` with body
`{filters?}` — `market_stats`.
- `GET <base>/v1/tables/{table}/trend` with `bucket` and a
JSON-encoded `filters` query parameter when set —
`price_trend`.
- `POST <base>/v1/price-check` with body
`{item, category?}` — `price_check`.
- `GET <base>/v1/search?q=&category=` — `search`.
- `GET <base>/v1/market-index?query=&category=` —
`market_index`.
- `GET <base>/v1/alerts` — `list_alerts`.
## CLI
Each tool is a subcommand taking one JSON argument string:
```bash
npx @reneturcios/saleroom list_tables '{}'
npx @reneturcios/saleroom query_table '{"table":"watches","filters":[{"column":"brand","operator":"eq","value":"Rolex"}],"limit":10}'
npx @reneturcios/saleroom price_check '{"item":"Rolex Submariner 1968","category":"watches"}'
npx @reneturcios/saleroom --version
```
Output is the tool's result text (the upstream JSON on
success). Exit codes: `0` on success, `1` on a runtime
error (including a validation or upstream failure), `2` on
a usage error.
## MCP server
```bash
npx -y @reneturcios/saleroom mcp
```
MCP client config:
```json
{
"mcpServers": {
"saleroom": {
"command": "npx",
"args": ["-y", "@reneturcios/saleroom", "mcp"],
"env": {
"ALTFINANCE_API_KEY": "<your key>"
}
}
}
}
```
## Docker
```bash
docker run -i ghcr.io/cloudcorprecords/saleroom
docker run --rm ghcr.io/cloudcorprecords/saleroom list_tables '{}'
```
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # tsx --test test/*.test.ts (fake fetch only, no network)
npm run dev # run the CLI from source
```
## License
MIT — Copyright (c) 2026 Rene Turcios
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues