altfinance-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@altfinance-mcpfind the top 10 most expensive Rolex watches sold after 2020"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ALT/FNDATA MCP Server
Connect your AI assistant to luxury and collectibles auction data. Query watches, jewelry, loose gemstones, handbags, cars, motorcycles, aircraft, wine and whisky, fine art, works of art, design, fashion, shoes, automobilia, books, coins, perfume, accessories, musical instruments and other vehicles from 100+ global auction houses, in plain language.
It uses the open Model Context Protocol (MCP), so it works with Claude, ChatGPT, Gemini, Perplexity and other assistants and developer tools that support MCP servers.
Quick Start
1. Get an API Key
Get your key from API Key & MCP in the ALT/FNDATA app.
2a. Connect the hosted server (no install)
In any assistant that supports remote MCP servers (often called custom connectors), add a connector with this URL:
https://mcp.altfndata.com/mcpChoose OAuth if you are asked for an authentication method. A sign-in page then asks for your ALT/FNDATA API key.
Claude: Settings → Connectors → add a custom connector.
ChatGPT: add it as a custom connector (developer mode). ChatGPT only connects to hosted servers, so use this option.
Perplexity: Settings → Connectors → add a custom connector with the URL above.
Gemini app: Settings → Connected Apps → add a custom app with the URL above (personal Google accounts).
Gemini Enterprise: an admin adds ALT/FNDATA once for the organisation. See Gemini Enterprise set-up below.
Menu names and plan availability are set by each assistant and change over time; check its help pages if the steps differ.
Gemini Enterprise (admin set-up)
Gemini Enterprise connects through a Custom MCP Server data store, which an admin sets up once for the organisation.
Register a client. The response contains a
client_idand aclient_secret. The secret is shown only once, so store it safely.curl -X POST https://mcp.altfndata.com/register \ -H "Content-Type: application/json" \ -d '{"client_name": "Gemini Enterprise (your organisation)", "redirect_uris": ["https://vertexaisearch.cloud.google.com/oauth-redirect"], "token_endpoint_auth_method": "client_secret_post", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "read"}'In the Gemini Enterprise console, add a Custom MCP Server data store with these values:
Field
Value
MCP Server URL
https://mcp.altfndata.com/mcpAuthorization URL
https://mcp.altfndata.com/authorizeToken URL
https://mcp.altfndata.com/tokenClient ID
client_idfrom step 1Client Secret
client_secretfrom step 1Scopes
readEnable PKCE
ticked
Each user then connects from Gemini and signs in with their own ALT/FNDATA API key. The client ID and secret only identify your organisation's Gemini Enterprise; they give no access to data on their own.
Google's guide to setting up a custom MCP server describes the console screens.
2b. Or run it locally
For desktop apps and developer tools that launch MCP servers on your machine, either install it with pip:
pip install altfinance-mcpor run it with no install using uv — point the client's command at uvx with altfinance-mcp as the argument (see the uvx config example below):
uvx altfinance-mcpMost tools take a configuration in this shape; add it to the tool's MCP settings and restart it.
Example, Claude Desktop: the config file is %APPDATA%\Claude\claude_desktop_config.json on Windows and ~/Library/Application Support/Claude/claude_desktop_config.json on macOS.
{
"mcpServers": {
"altfinance": {
"command": "altfinance-mcp",
"env": {
"ALTFINANCE_API_KEY": "your-api-key-here"
}
}
}
}With uvx (no pip install needed), use "command": "uvx" and pass the package as an argument:
{
"mcpServers": {
"altfinance": {
"command": "uvx",
"args": ["altfinance-mcp"],
"env": {
"ALTFINANCE_API_KEY": "your-api-key-here"
}
}
}
}Example, Claude Code:
claude mcp add altfinance -- altfinance-mcpSet the env var before launching:
export ALTFINANCE_API_KEY="your-api-key-here"Related MCP server: mcp-gov-auctions
What You Can Ask
Once connected, ask your assistant questions like:
"What tables are available in the ALT/FNDATA database?"
"Show me the schema for the watches table"
"Find the top 10 most expensive Rolex watches sold after 2020"
"How many Hermes handbags were sold by Christie's?"
"Give me market stats for Patek Philippe watches sold at Phillips"
"How have Hermes Birkin prices moved over the last five years?"
"Price-check a Rolex Daytona 116500 white dial"
"Search the whole market for a Burma ruby ring over $50k"
"What loose sapphires have sold at auction?" (uses
gems, notjewelry)
Available Tools
All 9 tools are read-only and annotated with readOnlyHint: true. No data is modified by any tool.
Tool | Description |
| Lists the 20 available tables with live descriptions and column counts |
| Shows column names and types for one table |
| Queries a table with filters, sorting, field selection, and pagination |
| Realized-price summary for a table or filtered segment: count of sales, median, 25th/75th percentiles, average, min/max, sale-date span, and top vendors by volume |
| How realized prices moved over time, bucketed by year, quarter, or month (count, median, average per period) |
| Fair-value range for a single item from comparable sales, with source links. Live comp categories: handbags, watches, cars |
| Whole-market keyword search across every category at once, merged by realized price. With no category it fans out across all 20 tables |
| Precomputed model-level price index (low / 25th / median / 75th / high, sample size, trend) for a brand or model. Covered categories: handbags, watches, cars |
| Read-only view of price alerts, or guidance on enabling them. See "Price alerts are read-only" below |
Every tool carries readOnlyHint and openWorldHint.
Price alerts are read-only
Price alerts belong to a signed-in ALT/FNDATA account (Cognito login), not to an API key. The MCP authenticates with an API key only, so it cannot create or enable alerts, and the alerts feed itself is not reachable for an API-key caller. list_alerts therefore either reports fired alerts (when a session makes the feed reachable) or returns guidance on setting alerts up in the app at app.altfndata.com. Alert allowance by plan: free 0, registered 1, collector 10, pro 100, included with Membership.
Feature and plan suggestions
Some tool responses may append a single short "💡" line suggesting a complementary ALT/FNDATA product or a plan upgrade. This happens at most once per response, only at a genuine tier boundary (a table your plan does not include, or an exhausted row quota) or as a relevant feature tip, and never for unlimited or comp accounts. It never changes the data returned.
Query Capabilities
Filter by any column using operators:
eq,neq,gt,gte,lt,lte,like,in,not_in,is_null,is_not_nullSort by any column, ascending or descending
Select specific fields to return
Paginate with limit/offset (max 500 rows per request)
Data Coverage
The database spans 20 tables. Call list_tables for the live set with current column counts.
Table | Description |
| Luxury watch auction results |
| Luxury handbag auction results |
| Finished jewelry, mounted pieces (rings, necklaces, bracelets, earrings) set with gemstones |
| Loose, unmounted gemstones (single stones and parcels). Use this for gemstone valuations, not |
| Collector car auction results |
| Collector motorcycle auction results |
| Aircraft auction results |
| Wine and whisky auction results |
| Works of art with stone/jewelry relevance (jade, jadeite, diamond-set, etc.) |
| Fine art auction results across all movements and periods |
| Design and decorative arts: furniture, lighting, glass, ceramics, studio/industrial design |
| Fashion and couture: clothing and accessories (not handbags or shoes, which have their own tables) |
| Footwear: designer shoes and collectible sneakers |
| Automotive memorabilia, parts, signage, models and related collectibles (not the cars themselves) |
| Books, manuscripts, maps and printed material |
| Numismatic coin auction results |
| Other vehicles: boats, tractors, trucks, buses and military vehicles (not cars or motorcycles) |
| Perfume and collectible fragrance bottles and flacons |
| Fashion accessories: belts, scarves, cufflinks, brooches and sunglasses, including gem-set pieces |
| Musical instruments: guitars, violin family, pianos and keyboards, woodwind, brass, percussion and amplifiers |
gems vs jewelry: gems holds LOOSE, unmounted stones (the right table for a gemstone valuation); jewelry holds FINISHED, mounted pieces set with stones. If one returns nothing, try the other.
Data sources include Christie's, Sotheby's, Phillips, Bonhams, Artcurial, Dorotheum, Heritage Auctions, and 100+ other auction houses worldwide.
Hosted Server
The hosted server at https://mcp.altfndata.com/mcp (Quick Start 2a) is this package running in HTTP mode. Any MCP client that supports remote servers with OAuth can connect to it; the sign-in page asks for your ALT/FNDATA API key, so no local installation is needed.
Self-Hosting the Remote Server
To run the MCP server in remote (HTTP) mode:
export ALTFINANCE_TRANSPORT=streamable-http
export ALTFINANCE_ISSUER_URL=https://mcp.altfndata.com
export ALTFINANCE_RESOURCE_URL=https://mcp.altfndata.com
python -m altfinance_mcpOr with Docker:
docker build -t altfinance-mcp .
docker run -p 8000:8000 \
-e ALTFINANCE_TRANSPORT=streamable-http \
-e ALTFINANCE_ISSUER_URL=https://mcp.altfndata.com \
-e ALTFINANCE_RESOURCE_URL=https://mcp.altfndata.com \
altfinance-mcpThe remote server exposes:
POST/GET/DELETE /mcp— MCP Streamable HTTP endpoint (authenticated)GET /.well-known/oauth-authorization-server— OAuth metadataPOST /register— Dynamic Client RegistrationGET /authorize— OAuth authorizationPOST /token— Token exchangeGET/POST /login— API key entry form
Environment Variables
Local (stdio) mode
Variable | Required | Default | Description |
| Yes | — | Your ALT/FNDATA API key |
| No |
| API base URL |
Remote (HTTP) mode
Variable | Required | Default | Description |
| Yes |
| Set to |
| No |
| API base URL |
| No |
| HTTP listen address |
| No |
| HTTP listen port |
| No |
| OAuth issuer URL (your public URL) |
| No | Same as issuer | OAuth resource server URL |
Privacy Policy
This MCP server connects to the ALT/FNDATA API (api.altfndata.com) to retrieve auction data. The following outlines our data practices:
Data collection: The server sends your API key and query parameters (table names, filters, sort options) to the ALT/FNDATA API. No personal user data is collected beyond what is required for API authentication and query execution.
Usage and storage: Query data is processed in real-time and returned to the MCP client. The server does not persist, cache, or store any query results or user data locally.
Third-party sharing: Data is exchanged only between the MCP client and the ALT/FNDATA API (
api.altfndata.com). No data is shared with any other third parties.Data retention: The server is stateless. No user data or query history is retained after a session ends.
Contact: For privacy inquiries, contact support@altfndata.com.
Full privacy policy: https://altfndata.com/privacy-policy/
Support
Documentation: https://docs.altfndata.com
Email: support@altfndata.com
Requirements
Python 3.10+
An ALT/FNDATA API key
License
MIT
Available Tools
9 toolsget_table_schemaARead-onlyInspect
List a table's column names and types so you can build a precise query.
Call this before query_table (or before adding filters to market_stats /
price_trend) to learn the exact field names a table exposes — e.g. whether
prices are in usd_price_decimal, how the brand/designer field is named, or
whether a carats column exists. Avoids guessing column names.
Example: before querying Rolex sales, call get_table_schema("watches") to
confirm the brand field is designer and the price field is
usd_price_decimal.
Args: table: Table alias (call list_tables for the full set). Note: "gems" = loose/unmounted stones; "jewelry" = finished/mounted pieces.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful behavioral context — that it prevents column-name guessing and reveals semantic aliasing like brand→`designer` — but says nothing about error behavior for an invalid table alias or how table aliases are discovered beyond a pointer to list_tables.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, followed by routing guidance, then a concrete example, then arg notes — a sound ordering. The Rolex example partially restates the preceding sentence's point about `usd_price_decimal`, so it is slightly longer than strictly necessary, but each block still earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The return shape is handled by the output schema, and the description covers the remaining needs for a one-parameter read tool: when to call it, what it reveals, how to find valid aliases, and alias disambiguation. Nothing an agent needs in order to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (the lone column is just typed 'string' with no description), so the description must carry the load and it largely does: it explains that `table` is a table alias, points to list_tables for the full set, and disambiguates the confusable 'gems' vs 'jewelry' aliases. Only the alias syntax/format itself is left implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'List a table's column names and types' — and immediately frames the outcome ('so you can build a precise query'), which separates it from query_table, market_stats, and the other siblings. An agent knows exactly what this returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly prescribes when to call it: 'before query_table (or before adding filters to market_stats / price_trend)'. It names the alternatives and the exact condition that selects this tool, including a concrete worked example with a real table alias and field names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_alertsARead-onlyInspect
Show ALT/FNDATA price alerts (read-only) or explain how to set them up.
Price alerts watch a saved item and fire when a matching lot sells at or below your target. They belong to a signed-in ALT/FNDATA account, not to an API key — so alerts are created and managed in the app (app.altfndata.com), and this MCP can only read/report them. If your key isn't tied to a signed-in session, this returns guidance on enabling alerts (allowance: free 0 · registered 1 · collector 10 · pro 100 · included with Membership) rather than a data feed.
Args: limit: Max fired alerts to show if the alerts feed is reachable (default 25).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: alerts belong to a signed-in account rather than an API key, this MCP can only read/report them, and a non-signed-in key yields setup guidance rather than data. It also discloses allowance tiers, which helps the agent interpret non-data responses. This is consistent with readOnlyHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and the structure is logical: what it does, account constraints, fallback behavior, then the argument. It is slightly verbose with background about how alerts fire and the allowance list, but those details are relevant enough that the length is largely justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description need not explain return values, and it covers the key behavioral edge cases: feed reachability, account-session requirements, read-only scope, and fallback guidance. For a one-parameter read tool, nothing important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter meaning. It does: 'limit' is documented as the maximum fired alerts to show, with the condition 'if the alerts feed is reachable' and the default value, fully covering the single optional parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Show ALT/FNDATA price alerts') and explicitly scopes it as read-only or explanatory. It distinguishes this MCP's read/report capability from the app's create/manage capability, so an agent can tell exactly what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains when this tool applies (reading/reporting alerts), when it does not (creating/managing alerts, which must be done in the app), and what happens when the API key is not tied to a signed-in session. The alternative path (app.altfndata.com) is named explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesARead-onlyInspect
List every auction-data table ALT/FNDATA serves, with live descriptions and column counts.
Start here whenever a question names a category and you need the right table
alias to pass to get_table_schema, query_table, market_stats or price_trend.
The set spans watches, jewelry (finished/mounted pieces), gems (loose
stones), handbags, cars, motorcycles, wine & whisky, works of art, fine art,
coins, and more. Always call this for the current set rather than assuming
it, and note that loose gemstones live in gems, not jewelry.
Example: for "what categories of data do you have?" or before "show me the
most expensive coins sold at auction" (to confirm the coins alias exists).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful context beyond them: results are live/current rather than static, entries include column counts, and it warns about a specific taxonomy trap ("loose gemstones live in `gems`, not `jewelry`"). It doesn't discuss ordering or the shape of each row, but the output schema exists to cover that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose in the first sentence, followed by routing guidance and examples in descending priority. The category enumeration is somewhat long, but it doubles as evidence of scope and the gems-vs-jewelry caveat earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only discovery tool with an output schema, this covers everything an agent needs: what it returns, when to call it, which siblings to route to next, and the main taxonomy pitfall. No gap remains that would cause a misinvocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description correctly implies a no-argument call by framing the tool as a discovery entry point, and adds no misleading input expectations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List every auction-data table ALT/FNDATA serves") and immediately adds what each entry carries (live descriptions, column counts). It is unmistakably distinct from siblings like get_table_schema and query_table, which consume the aliases this tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says "Start here whenever a question names a category and you need the right table alias," and names the four downstream tools that consume the output. It also gives the when-not guidance ("Always call this for the current set rather than assuming it") plus concrete trigger examples for discovery-style questions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
market_indexARead-onlyInspect
Precomputed model-level price index (headline figures) for a model or brand.
Reads the ALT/FNDATA Index's precomputed hot-stats — instant, no scan. Give a
typed model query (e.g. "Hermès Birkin 25", "Rolex Daytona 116500") for a
single model's realized-price band (low / 25th / median / 75th / high), sample
size, and recent trend; or give a brand alone for that brand's whole set of
model indices. Covered categories are handbags, watches, and cars. For other
categories, use market_stats (whole-market read) or price_trend instead — this
tool never invents a figure that isn't precomputed.
Args: query: A specific model to look up (brand + model + optional size/material). brand: A brand to list all model indices for (alternative to query). category: One of "handbags", "watches", "cars". Inferred from the text when omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| brand | No | ||
| query | No | ||
| category | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds real behavioral context beyond them: the read is 'instant, no scan' (precomputed source) and it 'never invents a figure that isn't precomputed,' which tells the agent how to interpret missing results. It stops short of discussing coverage gaps per model or empty-result behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and routing guidance are front-loaded ahead of the Args block, and every sentence carries information. Slight redundancy in restating each parameter in prose after the summary paragraph keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is optional, yet the description still names the useful fields (low/25th/median/75th/high, sample size, trend). Combined with the routing guidance, an agent has enough to invoke correctly; only edge cases like combined query+brand are uncovered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema carries no enum for `category`, so the description must carry the load — and it does, supplying the three valid values, inference-when-omitted behavior, example values for `query`, and the query/brand alternative. It doesn't state what happens if both `query` and `brand` are supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource — 'Precomputed model-level price index' — and immediately characterizes the data source (ALT/FNDATA hot-stats). It explicitly distinguishes itself from market_stats and price_trend by category scope, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit selection logic: a typed model `query` for one model's band, a `brand` alone for the whole brand set, and names market_stats or price_trend for categories outside handbags/watches/cars. When-to-use and alternatives are both present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
market_statsARead-onlyInspect
Summarize the realized-price market for a table or a filtered segment.
Returns count of sales, median, 25th/75th percentiles, average, min/max of
usd_price_decimal, the sale-date span, and the top vendors by volume — all
computed server-side over the full matching set (not a sample).
Args: table: Table alias (call list_tables first). "gems" = LOOSE, unmounted stones (use for a gemstone-market read); "jewelry" = FINISHED, mounted pieces. A loose-stone question can span both. filters: Optional list of filter dicts, same shape as query_table (field/op/value). Narrow to a segment, e.g. [{"field": "designer", "op": "eq", "value": "Patek Philippe"}]. sold_only: When true (default), restricts to sold lots with a positive USD price so the stats reflect realized transactions.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ||
| filters | No | ||
| sold_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds meaningful context beyond that: stats are computed server-side over the full matching set rather than a sample, and sold_only=true restricts to sold lots with a positive USD price so results reflect realized transactions. No auth, rate-limit, or cost disclosure, but the sampling and sold-only semantics are genuinely useful behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and return set are front-loaded, followed by per-argument notes, so the structure is easy to scan. The Args-style block is slightly verbose and the return enumeration is somewhat redundant given an output schema, but nothing is outright filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter read-only aggregation with an output schema, the description covers the argument semantics and the key caveat about full-set versus sampled computation. The remaining gap is relational: it never positions itself against market_index or price_trend, so an agent must guess between them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does so: table is explained with alias semantics ("gems" = loose/unmounted, "jewelry" = finished/mounted, may span both), filters is defined as field/op/value dicts matching query_table with a concrete Patek Philippe example, and sold_only is given its default and effect. All three parameters gain meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource — summarize the realized-price market for a table or filtered segment — and the return list makes the output concrete (count, median, percentiles, min/max, vendor ranking). It does not explicitly distinguish itself from sibling aggregators such as market_index or price_trend, which an agent would still need to disambiguate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a prerequisite ("call list_tables first") and explains when to pick "gems" versus "jewelry" and that a loose-stone question can span both, which is real usage context. However, it never says when to use market_stats instead of market_index, price_trend, or price_check, leaving the biggest selection question unanswered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
price_checkARead-onlyInspect
Estimate a single item's fair-value range from comparable auction sales.
Give either a free-text description (e.g. "Hermès Birkin 25 Togo, gold hardware") OR a lot URL from an auction house. Returns a realized-price range (low / median / high), a confidence read, and comparable sales with source links. Best for valuing ONE specific piece; for a whole-market read use market_stats.
Live comp categories are handbags, watches, and cars. Loose gemstones and
jewelry are intentionally held from comp-matching (under-specified colored
stones give unreliable medians) — for those, use market_stats on gems
(loose stones) or jewelry (mounted pieces) instead.
Args: description: Free-text item description. lot_url: A lot URL from an auction house (alternative to description). category: One of "handbags", "watches", "cars". Inferred from the text if omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| lot_url | No | ||
| category | No | ||
| description | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered; the description adds genuinely non-derivable behavior — the realized-price range plus confidence plus source-linked comps, and the deliberate exclusion of loose stones and jewelry because under-specified colored stones give unreliable medians. The remaining detail (exact output shape) is carried by the output schema, so it doesn't need restating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, input alternatives, and the sibling boundary are all front-loaded in the first two paragraphs, and the exclusion caveat earns its space. The Args block partially duplicates the input schema but adds the missing category enum and example formatting, so the redundancy is mostly justified rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the read-only/open-world profile, the description only needed to explain inputs, routing, and limitations — all of which it does, including the category-coverage caveat. The one real hole is edge-case behavior when both or neither of description and lot_url are provided, on a tool where all three params are optional.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load, and it largely does: it explains the description/lot_url tradeoff, gives a concrete free-text example with brand/model/material, and supplies the category enum values ("handbags", "watches", "cars") plus an inference rule when omitted — none of which appears in the schema. It stops short of saying what happens when both description and lot_url are supplied, or when neither is.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Estimate a single item's fair-value range from comparable auction sales") and immediately distinguishes itself from the sibling market_stats ("Best for valuing ONE specific piece; for a whole-market read use market_stats"). An agent can route between the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit input alternatives (free-text description OR auction-house lot URL), an explicit use-case boundary versus market_stats, and an explicit exclusion with a fallback: gemstones and jewelry are held from comp-matching, so use market_stats on `gems` or `jewelry` instead. This is close to a complete routing rule set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
price_trendARead-onlyInspect
Show how realized prices moved over time for a table or filtered segment.
Buckets sold lots by sale period and reports, per period, the number of
sales, the median, and the average usd_price_decimal.
Args: table: Table alias (call list_tables first). Gems = loose stones; jewelry = mounted pieces. filters: Optional filter dicts (field/op/value), same shape as query_table. by: Time bucket — "year" (default), "quarter", or "month". sold_only: Restrict to sold lots with a positive USD price (default true).
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | year | |
| table | Yes | ||
| filters | No | ||
| sold_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description adds substantive behavior: the aggregation it performs, the time-bucketing behavior, and that sold_only restricts to sold lots with a positive USD price (default true) – a material effect on results. No auth or rate-limit context, and no note on sparse/empty periods.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then an Args block that is easy to scan. Slightly redundant where it restates defaults already present in the schema (year, true), but those restatements are paired with clarifying semantics rather than pure duplication.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still summarizes the returned metrics (per-period sales count, median, average), which is enough for an agent to know what it will get. Combined with the parameter documentation and read-only annotation, nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does so: it explains the table alias domain (Gems = loose stones, jewelry = mounted), the allowed 'by' values (year/quarter/month) which are absent as an enum in the schema, the filter shape referenced to query_table, and the precise semantics of sold_only. All four parameters gain meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Show how realized prices moved over time') and adds the exact computation performed (bucket sold lots by period, report count/median/average usd_price_decimal), which is more than a restatement of the name. It does not explicitly distinguish itself from siblings like market_stats or price_check, leaving the agent to infer the difference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives actionable prerequisites ('call list_tables first') and clarifies that filters use 'the same shape as query_table', which steers reuse of a known pattern. It never says when to prefer market_stats or price_check instead, so there is no explicit exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_tableARead-onlyInspect
Query one known table with precise filtering, sorting, and field selection.
Use this when you already know the target table (from list_tables) and want
exact control — e.g. "the 10 most expensive Rolex watches sold since 2020"
becomes table="watches", filters on designer/sale_date, sort by
usd_price_decimal desc, limit 10. If you don't know which table holds the
item, use search (whole-market) instead; for aggregate figures (median,
percentiles) use market_stats.
Args: table: Table alias (call list_tables for the full set). "gems" = loose stones (use for gemstone valuations); "jewelry" = finished pieces. fields: List of column names to return (e.g., ["item_title", "vendor", "usd_price_decimal"]). If not specified, returns all columns. filters: List of filter conditions. Each filter is a dict with: - "field": column name - "op": operator — one of "eq", "neq", "gt", "gte", "lt", "lte", "like", "in", "not_in", "is_null", "is_not_null" - "value": the value to compare against Example: [{"field": "vendor", "op": "eq", "value": "Phillips"}, {"field": "usd_price_decimal", "op": "gte", "value": 50000}] sort_field: Column name to sort by (e.g., "usd_price_decimal" or "sale_date") sort_direction: "asc" or "desc" (default: "desc") limit: Maximum rows to return (default: 20, max: 500) offset: Number of rows to skip for pagination (default: 0)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| table | Yes | ||
| fields | No | ||
| offset | No | ||
| filters | No | ||
| sort_field | No | ||
| sort_direction | No | desc |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and an output schema exists, so the bar is lower. The description still adds value annotations cannot: the full operator vocabulary for filters, the 20-row default with a hard 500-row cap (the cap is absent from the schema), and the alias semantics for "gems" vs "jewelry". It does not mention error behavior for an invalid table or what happens when a filter references an unknown column.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and a use case, then a clean Args block matching the schema order. Slightly long, and the two examples partially overlap (the query example restates filter/sort/limit intent), but nearly every sentence adds distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values, and annotations cover the safety profile. For a 7-parameter, 0%-coverage schema the description fully compensates, including nested filter structure and the limit ceiling, leaving nothing an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the load and does: every parameter is explained, including the nested filter dict shape with its "field"/"op"/"value" keys, the enumerated operator list, and a concrete filter example. It also supplies the missing max limit and clarifies that `fields` defaults to all columns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource and immediately bounds the scope: 'Query one known table'. The worked example (table="watches" with filters, sort, limit) makes the operation concrete, and the described purpose is clearly distinct from the sibling `search` (whole-market) and `market_stats` (aggregates).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing is given: use this when the target table is already known from `list_tables`, use `search` when the table is unknown, and use `market_stats` for aggregate figures. Both an inclusion condition and two named alternatives are stated, so no inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyInspect
Whole-market keyword search across every ALT/FNDATA category at once.
Runs a server-side free-text search (the same engine behind the ALT/FNDATA
Search app): your query is split into tokens, each matched across
item_title, designer, vendor, gem_type, primary_gem, origin, color, model
and sale_title with synonym expansion (e.g. ruby↔rubis, jade↔jadeite). With
no category it fans out across the whole market and merges the top realized
sales by USD price — so you don't have to guess which table holds an item.
Args: query: Free-text keywords, e.g. "ruby ring", "Daytona 116500", "Birkin 25". category: Optional hint to narrow the search — a table alias (e.g. "watches") or a plain word ("cars", "gemstone"). A gemstone/stone hint searches BOTH gems (loose) and jewelry (mounted); omit it to search everything. filters: Optional extra filter dicts (same field/op/value shape as query_table), AND-ed with the keyword match — e.g. [{"field": "usd_price_decimal", "op": "gte", "value": 50000}]. limit: Max merged results to return (default 25, max 100).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| filters | No | ||
| category | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description goes well beyond them by disclosing tokenization, synonym expansion (ruby↔rubis), the exact fields matched, merge/dedup behavior ranked by top realized USD sales, and the limit ceiling of 100. That is exactly the kind of engine-level behavior an agent cannot infer from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line summary followed by mechanics and an Args block, with no filler sentences. Minor redundancy: the intro already explains the no-category fan-out and merge behavior, then the category arg repeats part of it, making it slightly longer than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-param search tool with an output schema, everything the agent needs to call correctly is present: matching semantics, result merging/ordering, filter syntax, and size caps. Return-value shape is correctly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does so for all four parameters: query examples ('Daytona 116500', 'Birkin 25'), the dual alias/plain-word semantics of category, the AND-ed filter dict shape with a concrete usd_price_decimal gte example, and limit's default 25 / max 100.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with explicit scope: 'Whole-market keyword search across every ALT/FNDATA category at once.' The line 'so you don't have to guess which table holds an item' implicitly positions it against the per-table query_table sibling, letting an agent choose without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear use context (use when you don't know which table holds an item; omit category to fan out) and explains that category can be a table alias or a plain word, with gemstone hints searching both loose gems and mounted jewelry. It stops short of explicitly naming query_table or price_check as alternatives, so there is no explicit when-not-to-use routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.4.7- First observed
get_table_schema - First observed
list_alerts - First observed
list_tables - First observed
market_index - First observed
market_stats - First observed
price_check - First observed
price_trend - First observed
query_table - First observed
search
TDQS
Scored across 9 tools
Most tools occupy distinct slots: list_tables (discovery), get_table_schema (introspection), query_table (precise rows), market_stats (aggregates), price_trend (time series), price_check (single-item comp), search (cross-market keywords), market_index (precomputed model index), list_alerts. The only soft boundaries are market_stats vs market_index (segment stats vs precomputed model band) and query_table vs search, but descriptions explicitly tell the agent which to pick and when to fall back.
All names are snake_case, but conventions are mixed: verb_noun (list_tables, get_table_schema, query_table, list_alerts), noun_phrase (market_stats, price_trend, price_check, market_index), and a bare verb (search). The market_* family is internally coherent, yet the surface as a whole does not follow one predictable pattern, so an agent can't infer a namespace purely from a name.
Nine tools for an auction-market data server is well scoped: discovery, schema, row query, aggregate, trend, valuation, search, index, and alerts each cover a genuinely different need. Nothing looks redundant or padded, and there is no obvious missing layer that would require an additional tool.
The read-only lifecycle is well covered end to end: find tables, inspect schema, query rows, aggregate, trend, value a piece, and search across categories. Gaps are minor but real — no single-lot lookup by ID/URL independent of price_check, no cross-table aggregation across categories (e.g. gems+jewelry), and alerts are read-only by design, though each gap is documented with a workaround.
Maintenance
Related MCP Connectors
Collector-car auction history, live listings, bid trails, and market statistics for AI agents.
AI-native art catalogue. Catalogue works, parse provenance, and generate signed RAIs.
Live crypto + IDX stock market intelligence for AI agents — 19 tools, no API key.
Pay-per-call on-chain data for AI agents: token, wallet, risk, whale, NFT, tx. No API keys.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI assistants to access real-time on-chain crypto analytics, whale tracking, and market metrics through natural language queries. It provides access to over 245 endpoints for comprehensive data analysis of assets like Bitcoin, Ethereum, and stablecoins.739 npm8MIT
- AlicenseNot gradedqualityBmaintenanceProvides access to government auctions data for physical-asset auctions including surplus, seized, and forfeited items. Designed for AI agents to query and retrieve auction information via natural language.11 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to read-only access Catawiki auction marketplace data, including searching lots, inspecting items, browsing categories, and exploring auctions.MIT
- AlicenseNot gradedqualityBmaintenanceGovAuctions.app is a free public site for searching government surplus auctions. This MCP server exposes its data: live listings from GSA and other public sellers across the US, UK, CA and AU, sold-price comps from 170,000+ closed auctions, and a 0-100 Flip Score resale signal.6 npmMIT