scentindex
README.md
# scentindex
A window onto a large fragrance index. scentindex queries
the public 10ml Fragrance Index — perfumes, the notes inside
them, the houses that make them, and the guides that explain
the vocabulary — and returns what the index returns,
unchanged. No account and no API key are involved; it is a
thin, honest client over a public API.
What you can do with it:
- Search perfumes by free text, house, notes included or
excluded, accords, family, gender, season, occasion or
style, and page through the results with a cursor.
- Open one perfume in full to see its notes, accords and
metadata.
- Start from a perfume, a note set or an accord profile and
find similar scents, or look for alternatives — the same
scent profile from other houses.
- Browse perfumes by a single note, for example everything
containing oud.
- Ask what a note actually smells like and where it tends
to appear.
- List and open fragrance houses, filtered by type or
country, and search the index's guides and glossary
content.
Most tools accept a `locale` for the response language and,
where the underlying operation supports it, a
`response_format` of `concise` (the API's default) or
`detailed`. List tools page with `limit` (1–100) and an
opaque `cursor` taken from a previous response.
## Labelled subset: 9 of 15 tools
This rebuild implements **9 of the original tool set's 15
tools** — the nine that map onto operations published in
the upstream OpenAPI document:
`search_perfumes`, `get_perfume`, `find_similar_perfumes`,
`find_perfume_alternatives`, `perfumes_by_note`,
`explain_note`, `list_houses`, `get_house`, `search_guides`.
The remaining six are **omitted**, because they have no
operation in the published OpenAPI and their argument
shapes are not published anywhere reachable:
`compare_perfumes`, `recommend_perfumes`,
`explain_perfume_term`, `suggest_layering`,
`pick_for_occasion`, `find_gift`.
## Configuration
The API base defaults to `https://mcp.10ml.com/api/v1` and
can be overridden with the `PERFUME_API_BASE` environment
variable. No API key is required.
## CLI
Each tool is a subcommand taking one JSON argument string:
```bash
npx @reneturcios/scentindex search_perfumes '{"q":"oud","limit":10}'
npx @reneturcios/scentindex get_perfume '{"id":"<perfume id>"}'
npx @reneturcios/scentindex find_similar_perfumes '{"perfume":"<name>"}'
npx @reneturcios/scentindex find_perfume_alternatives '{"perfume":"<name>"}'
npx @reneturcios/scentindex perfumes_by_note '{"note":"oud"}'
npx @reneturcios/scentindex explain_note '{"id":"oud"}'
npx @reneturcios/scentindex list_houses '{"country":"FR"}'
npx @reneturcios/scentindex get_house '{"id":"<house id>"}'
npx @reneturcios/scentindex search_guides '{"q":"layering"}'
npx @reneturcios/scentindex --version
```
Output is the upstream JSON, verbatim. 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/scentindex mcp
```
MCP client config:
```json
{
"mcpServers": {
"scentindex": {
"command": "npx",
"args": ["-y", "@reneturcios/scentindex", "mcp"]
}
}
}
```
## Docker
```bash
docker run -i ghcr.io/cloudcorprecords/scentindex
docker run --rm ghcr.io/cloudcorprecords/scentindex perfumes_by_note '{"note":"oud"}'
```
## 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