finn-seller-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., "@finn-seller-mcpsell my old iPhone on Torget from these photos"
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.
🛒 finn-seller-mcp
An MCP server that lets Claude (or any MCP client) search and sell on finn.no — Norway's largest marketplace. Send a photo, get a finished Torget ad: description, category, market price, duplicate check, publish.
⭐ If this saves you time, star the repo — it helps others find it.
📖 Table of contents
Related MCP server: Facebook Marketplace MCP
✨ What it does
🏷️ Sell
📸 Photo prep — auto-rotate, strip EXIF/GPS, resize, HEIC (iPhone) support
✍️ Ad writing — the assistant writes title + Norwegian description from your photos
🗂️ Category from photos — uses finn.no's own category prediction
💰 Market price — median of comparable ads, outliers removed
🔁 Duplicate guard — won't re-list something you already listed or sold
🚦 Two-step publish — private draft on finn.no → preview → your "yes" → live
🔎 Search & manage
🔍 Search Torget, real estate, rentals, used cars, jobs
📄 Full listing details by FINN-kode
🔔 Saved searches with "what's new since last time"
📋 Mine annonser — list your ads with state
⚡ Ad actions — run the actions finn.no offers per ad (delete, …), with confirmation
🔐 Passwordless login kept in a local browser profile
🆚 Why this project
Existing finn.no MCP servers are read-only scrapers. This one adds the whole seller side, built on finn.no's internal JSON API (mapped with an included recon tool) rather than brittle form clicking.
Read-only scrapers | finn-seller-mcp | |
Search & listing details | ✅ | ✅ |
Saved searches with diff | some | ✅ |
Log in to your account | ❌ | ✅ (you log in, never the AI) |
Create / publish Torget ads | ❌ | ✅ |
Photo upload + EXIF/GPS strip | ❌ | ✅ |
Category suggestion from photos | ❌ | ✅ |
Market-price suggestion | ❌ | ✅ |
Duplicate protection (local + your finn.no ads) | ❌ | ✅ |
Manage "Mine annonser" | ❌ | ✅ |
Recon tool to re-map the site when it changes | ❌ | ✅ |
🚀 Quick Start
1. Install (needs uv and Python 3.11+)
git clone https://github.com/ml-senior/finn-seller-mcp
cd finn-seller-mcp
uv sync
uv run playwright install chromium2. Register with your MCP client
Edit claude_desktop_config.json and restart Claude Desktop:
OS | Path |
Linux |
|
macOS |
|
Windows |
|
{
"mcpServers": {
"finn": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/finn-seller-mcp", "run", "finn-seller-mcp"]
}
}
}claude mcp add finn -- uv --directory /absolute/path/to/finn-seller-mcp run finn-seller-mcpCommand: uv, args: --directory /absolute/path/to/finn-seller-mcp run finn-seller-mcp. The server speaks MCP over stdio.
3. Log in once
Ask the assistant to run login (or run the recon script, below). A Chromium window opens on finn.no — you type your e-mail and the one-time code from Vend. The session is stored in a local browser profile and reused from then on.
4. Sell something
"Sell this controller" + 📸 photo
That's it. The assistant checks for duplicates, prepares a private draft on finn.no, shows you the preview and publishes only after you say yes.
finn.no asks for a one-timeBankID identity verification before your first Torget ad goes live. If publish_draft returns bankid_required, open the edit_url it gives you, press Gå videre → Verifiser med BankID, finish it yourself, then ask the assistant to publish again.
💬 Example session
You: Sell this. [photo of a PS5 controller]
Claude: ▸ check_duplicate → nothing similar on your account
▸ suggest_price → median 500 kr from 14 comparable ads
▸ create_draft → photo cleaned (EXIF/GPS removed)
▸ push_draft → private draft created on finn.no
▸ suggest_category → Elektronikk › Spill og konsoll › Tilbehør
Here's the ad:
PS5 DualSense kontroller – hvit · Pent brukt · 500 kr · 1 photo
"Original Sony DualSense trådløs kontroller …"
Publish?
You: yes
Claude: ▸ publish_draft(confirm=true) → live ✅🔄 How it works
flowchart LR
U([You + photos]) --> A[Assistant]
A -->|check_duplicate| D{Already listed?}
D -- yes --> S[Stop and show matches]
D -- no --> P[suggest_price<br/>median of comparables]
P --> C[create_draft<br/>EXIF/GPS strip, resize]
C --> PU[push_draft<br/>private draft on finn.no]
PU --> SC[suggest_category<br/>finn.no prediction]
SC --> PV[Preview to you]
PV -->|your explicit yes| PB[publish_draft confirm=true]
PB --> L([Live on finn.no])Under the hood the server talks to the same JSON endpoints the finn.no web form uses, through a persistent Playwright Chromium profile so requests carry your logged-in session:
sequenceDiagram
participant M as finn-seller-mcp
participant F as finn.no
M->>F: POST create-item … /api/create (adType=recommerce)
F-->>M: 301 → /recommerce/create/{adId}
loop each photo
M->>F: POST /recommerce/create/api/image/{adId} (multipart "image")
F-->>M: { path: "item/{adId}/{uuid}", width, height }
end
M->>F: PUT /recommerce/create/api/item/{adId} e-tag: W/"rev" { commit:false, data }
F-->>M: { state:"draft", violations:[], etag }
M->>F: POST /recommerce/create/api/predictions/categories/{adId}
Note over M: user confirms in chat
M->>F: PUT /recommerce/create/api/item/{adId} { commit:true, data }
F-->>M: published — or { requiredVerification:true } → BankID needed{
"trade_type": "SELL",
"category": 65,
"condition": 3,
"title": "PS5 DualSense kontroller – hvit",
"description": "Original Sony DualSense …",
"price": { "price_amount": 500 },
"address": { "postalcode": "0150", "country": "NO" },
"image": [ { "uri": "item/{adId}/{uuid}", "width": 960, "height": 1280, "description": "optional caption" } ]
}Saves use optimistic locking: every PUT sends the last etag in an e-tag request header. No CSRF token is involved — only the session cookies plus Origin/Referer. Full notes: RECON.md.
🧰 Tool reference
Tool | What it does |
| Opens a visible Chromium on finn.no so you log in (e-mail + one-time code). The assistant never handles credentials. |
| Checks whether the saved profile is logged in; returns how many ads the account has. |
Tool | What it does | Touches finn.no? |
| Title + photo match against local history and all your finn.no ads (active, sold, expired, drafts). | read |
| Median price of comparable "Til salgs" Torget ads; IQR outlier removal; rounded; returns example ads. | read |
| Local draft. Photos auto-rotated, EXIF/GPS stripped, resized to ≤2400 px, HEIC supported. Reports possible duplicates. | — |
| Change any field of a local draft (price, category, condition, …). | — |
| Inspect local drafts and the exact payload that would be sent. | — |
| Create/update a private draft on finn.no, upload photos, return finn.no's own validation. Never publishes. | write (private) |
| finn.no's category prediction from the uploaded photos (leaf + full path). | read |
| Unblock a draft the duplicate guard flagged — only after you say it's a different item. | — |
| Duplicate check → push → validation → with | public |
Tool | What it does |
| "Mine annonser": your ads with state, facets and the actions finn.no offers for each. |
| Run one of those actions by name (e.g. |
Tool | What it does |
| Search |
| Full listing by FINN-kode (JSON-LD parsing, 24 h cache). |
| Persist named searches. |
| Run a saved search and return only listings new since the last check. |
Condition — 1 Helt ny · 2 Som ny · 3 Pent brukt · 4 Godt brukt · 5 Må fikses
Top-level Torget categories — 76 Antikviteter og kunst · 77 Dyr og utstyr · 93 Elektronikk og hvitevarer · 68 Foreldre og barn · 86 Fritid, hobby og underholdning · 67 Hage, oppussing og hus · 71 Klær, kosmetikk og tilbehør · 78 Møbler og interiør · 91 Næringsvirksomhet · 69 Sport og friluftsliv · 90 Utstyr til bil, båt og MC
Ads need a leaf category id (e.g. 93 › 3905 › 65 → use 65). Easiest: push_draft with a best guess, then suggest_category.
💰 Pricing policy
Situation | Price used |
You name a price | Exactly your price |
You don't |
|
Fewer than 3 comparables | The assistant asks you instead of guessing |
The policy is written into the tool descriptions, so any MCP client follows it.
🔁 Duplicate protection
Before creating and again before publishing, every new ad is compared with:
🗃️ Local history — every draft/ad made through this server, photos matched by a 64-bit perceptual dHash (survives resizing, re-compression and EXIF stripping; ≤10-bit distance = same picture).
🌐 Your finn.no account — all ads in "Mine annonser" in any state, matched by normalized title similarity (≥85 %, or ≥60 % plus a shared photo).
A hit blocks publish_draft. Only confirm_not_duplicate, called after you say "it's a different item", unblocks it.
🛡️ Safety model
Rule | How it's enforced |
The AI never logs in for you |
|
Nothing goes public without your "yes" |
|
Destructive actions are gated |
|
No accidental re-listing | Duplicate guard blocks publishing. |
Your photos don't leak location | EXIF (incl. GPS) is dropped; images re-encoded. |
Identity checks stay yours | BankID is detected and handed back to you, never automated. |
Recon can't publish by accident | The recon script aborts any request containing |
🧭 Recon: mapping the site yourself
finn.no can change its internals at any time. scripts/recon.py lets anyone re-map the seller flow in minutes without publishing anything:
uv run python scripts/recon.py --start https://www.finn.no/create-item/startA Chromium window opens with the same profile the server uses — log in.
Click through the flows (new ad, photos, price, "Publiser", Mine annonser, edit…). Press the red 📸 Snapshot form button on each form step.
Close the window.
File | Content |
| Endpoint map grouped by method + path template (IDs → |
| Same, machine-readable |
| Every API call: headers, bodies, status, responses — redacted (cookies, tokens, e-mails, phone numbers) |
| Large bodies; multipart uploads summarized (field names, sizes — no file bytes) |
| Form snapshots: every input/select incl. shadow DOM, labels, options, selectors + full-page screenshot |
| Full HAR with cookies — never share |
Safety flags: --block REGEX adds patterns; --no-default-block disables blocking (real actions will happen!). Tracker hosts are filtered out. Non-UTF-8 request bodies are handled safely.
⚙️ Configuration
Variable | Default | Purpose |
|
| Persistent Chromium profile (your session) |
|
|
|
| Playwright's Chromium | Path to a custom Chromium/Chrome binary |
|
| Base for profile, drafts, cache |
|
| Search/listing cache (24 h) |
|
| Search backend ( |
|
| Override for tests against a mock server only |
Local data lives in ~/.local/share/finn-mcp/: browser-profile/, drafts/<id>/draft.json + cleaned photos, cache.sqlite.
🗂️ Project layout
finn-seller-mcp/
├── src/finn_mcp/
│ ├── server.py # FastMCP server, search tools, registers seller tools
│ ├── scraper/ # read-only HTML/JSON-LD scrapers (bap, homes, cars, jobs)
│ ├── backend/ # search backend abstraction
│ └── seller/
│ ├── tools.py # seller MCP tools
│ ├── api.py # finn.no seller JSON API client (via Playwright context)
│ ├── browser.py # persistent Chromium session, interactive login
│ ├── drafts.py # local draft store + validation
│ ├── photos.py # EXIF/GPS strip, rotate, resize, HEIC
│ ├── dupes.py # perceptual-hash + title duplicate detection
│ ├── pricing.py # market-price median with outlier removal
│ └── selectors.py # every site-specific URL/selector in one place
├── scripts/recon.py # site recorder with publish blocking
├── tests/ # fixtures-based tests (no network)
├── RECON.md # what we know about finn.no internals
└── docs/ # translations, assets🧪 Development & tests
uv sync
uv run pytest -q # offline: HTML fixtures, pricing, duplicatesTests never hit finn.no. For end-to-end work, point FINN_BASE_URL at a mock server that replays shapes from RECON.md.
🩺 Troubleshooting
Run the login tool (or the recon script) and log in again. Sessions are long-lived but finn.no expires them eventually.
One-time identity check by finn.no. Open the returned edit_url, press Gå videre → Verifiser med BankID, complete it, then publish again.
You used a parent category. Use a leaf id — run suggest_category after push_draft.
Working as intended. Check the matches; if it really is a different item, tell the assistant so it calls confirm_not_duplicate.
Harmless on Kali/Arch/etc. — Playwright downloads an Ubuntu build that works. Or set FINN_CHROMIUM to your own Chromium.
Update to the latest scripts/recon.py — older versions crashed on non-UTF-8 request bodies sent by the login page, which stalled the request.
❓ FAQ
Is there an official finn.no API for this? Not for private sellers. FINN's import APIs are B2B (jobs, real estate, dealers) and require a contract. This project uses the same internal endpoints as the finn.no website, with your own session.
Does the AI see my password? There is no password — login is e-mail + one-time code, and you type both yourself in a real browser window.
Can it publish without asking?
No. publish_draft without confirm=true only returns a preview, and the tool contract requires your explicit "yes".
Which categories work?
All Torget leaf categories. Category-specific extra fields can be passed via attributes.
Does it work for cars / real estate? Search: yes. Selling: Torget only for now.
🗺️ Roadmap
Read-only search, listings, saved searches
Login via persistent browser profile
Create / push / publish Torget ads, photo upload
Category prediction, market price, duplicate guard
Mine annonser + generic ad actions
Recon tool with publish blocking
"Gi bort" (give away) trade type
Fiks ferdig (shipping) fields
Mark sold / deactivate / renew on live ads (action names pending recon)
Buyer messages
Full category tree export
Price from Klarna Prisguiden (new-price ceiling)
🤝 Contributing
PRs welcome — see CONTRIBUTING.md. If finn.no changed something, run the recon script and attach the redacted endpoints.md (never the private/ folder).
⚖️ Disclaimer
Independent open-source project, not affiliated with or endorsed by FINN.no / Vend Marketplaces. It automates your own account through finn.no's web endpoints; you are responsible for complying with finn.no's terms of use. Keep usage personal and moderate — no bulk listing, no scraping at scale.
📄 License & credits
MIT © 2026 ml-senior
Search/scraper layer based on aHk-coder/finn-mcp (MIT). Condition and category code tables adapted from viktorfa/finn_mcp (MIT).
Available Tools
20 toolsad_actionA
Run an action finn.no offers for one of the user's ads (names come from my_ads, e.g. DELETE).
Anything that changes the ad (DELETE, mark sold, deactivate ...) needs
confirm=true, given only after the user explicitly agreed in chat.
DELETE is permanent.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| confirm | No | ||
| finnkode | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does disclose key safety behavior: mutations require explicit confirmation, confirmation timing is constrained, and DELETE is permanent. It does not cover permission requirements or side effects for non-delete changing actions, but it covers the central risk profile well.
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 description is short, front-loaded with what the tool does, and then immediately covers the critical confirmation and permanence rules. Every sentence contributes to safe invocation guidance.
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 tool has no annotations, 0% schema description coverage, and an open-ended action string, so the description must carry substantial context. It covers the most important safety rules and the source of action names, but it leaves finnkode unexplained and does not enumerate or constrain the full action set. The output schema exists, so return-value explanation is not required.
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 explain all parameters. It clarifies the action parameter by saying names come from my_ads and giving DELETE as an example, and it explains confirm=true semantics in detail. However, it never explains the required finnkode parameter, leaving a significant gap.
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 description states a specific verb and resource: 'Run an action finn.no offers for one of the user's ads,' and gives DELETE as an example. It clearly identifies the ad domain and points to my_ads as the source of action names, though it does not explicitly distinguish itself from sibling tools such as update_draft.
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 important usage context: action names come from my_ads, changing actions require confirm=true, and confirmation must follow explicit user agreement in chat. It does not explicitly state when to use this tool instead of alternatives like update_draft or delete-related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_duplicateA
Check whether an item was already listed (locally or on the user's finn.no account).
Call this BEFORE preparing a new ad. Local photos are matched by
perceptual hash; finn.no ads (any state: active, sold, expired, draft)
are matched by title.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| photo_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses that photos are compared by perceptual hash and titles against finn.no ads in any state (active, sold, expired, draft) — non-obvious behavior that materially affects interpretation of results. It omits any statement about permissions, rate limits, or the cost of the scan, and defers match/return semantics to the output schema.
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?
Two short sentences, front-loaded with the purpose, then the when-to-use rule, then the matching mechanics. No filler or restatement of the tool name.
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 two-parameter read-only check with an output schema available, the description covers what is compared and against what sources, which is the information an agent needs to call it correctly. Only the optionality of photo_paths and the distinction from confirm_not_duplicate are left implicit.
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 compensate, and it does partially: it explains that photo_paths feed perceptual-hash matching and that title is the matching key for finn.no. It does not state that photo_paths is optional or what happens when it is omitted, nor the expected path format.
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 (check whether an item was already listed) and scopes it to two distinct backends: local records and the user's finn.no account. It also distinguishes the matching mechanism per backend, so an agent understands exactly what 'duplicate' means here.
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?
"Call this BEFORE preparing a new ad" gives an explicit trigger point in the workflow, which is stronger than most sibling definitions. It does not name or contrast with the obvious sibling confirm_not_duplicate, leaving the agent to infer the distinction between detection and confirmation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_saved_searchA
Run a saved search, return only listings that are new since the last check.
Updates the saved search's ``last_checked_at`` and ``last_finnkodes``.
On the first call all current results are "new".
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool updates last_checked_at and last_finnkodes, which are side effects beyond the schema. It also explains the first-call behavior. Since no annotations are provided, the description fully carries the transparency burden.
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 description is extremely concise: two sentences and a list of side effects. Every line serves a purpose, and the main verb 'Run' leads the text. No superfluous content.
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 the tool has an output schema (not shown but known), the description adequately covers the behavior and side effects. However, it could explain the term 'last_finnkodes' and provide more context about the input format, but it remains sufficient for a simple tool.
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?
Only one parameter 'name' exists, and the description does not mention it at all. With schema coverage at 0%, the description should add meaning (e.g., what names are valid or how to construct them), but it fails to do so.
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 description clearly states the action: run a saved search and return new listings. It specifies the resource (saved search) and the unique behavior (only new results). This distinguishes it from siblings like search_finn or list_saved_searches.
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?
The description explains that on the first call all results are new, implying subsequent calls yield only new changes. However, it does not explicitly state when to use this tool versus alternatives like search_finn, nor does it list preconditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
confirm_not_duplicateA
Mark a draft as a genuinely different item so publish_draft stops blocking it.
Only call after the USER said in chat that it is not the same item.
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It discloses that the tool mutates the draft state and unblocks publish_draft, plus a user-confirmation requirement, but it omits permissions, reversibility, and what happens if the draft is not actually a duplicate.
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 description is two short sentences, front-loaded with the action and outcome. The precondition follows immediately and there is no 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?
An output schema exists, so return values need not be explained. For a simple one-parameter state flag, the description supplies purpose and a user-confirmation precondition; the remaining gaps are behavioral rather than blocking invocation.
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%, and the only parameter, draft_id, is undocumented in the schema. The description says 'a draft' but does not explain the identifier format or where to obtain it, so it adds little beyond the field name.
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 description states a specific verb and resource: 'Mark a draft as a genuinely different item.' It also names the downstream effect on the sibling tool publish_draft, so an agent can distinguish this from check_duplicate and publish_draft itself.
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?
The description gives a clear precondition: 'Only call after the USER said in chat that it is not the same item.' This defines when to call it, but it does not explicitly name check_duplicate as the alternative or explain other cases where calling would be inappropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_draftA
Create a LOCAL draft ad (nothing is sent to finn.no yet).
Photos are auto-rotated, stripped of EXIF/GPS and resized; the first
photo is the cover. category = numeric LEAF id (e.g. "43" Bærbar PC;
use suggest_category after push_draft if unsure). condition: 1=Helt ny
2=Som ny 3=Pent brukt 4=Godt brukt 5=Må fikses. trade_type: 1=Til salgs.
Price is in whole NOK.
PRICE POLICY: if the user named a price, use exactly that. Otherwise call
suggest_price first and use its `suggested_price` (market median), and
tell the user which comparables it is based on.
| Name | Required | Description | Default |
|---|---|---|---|
| price | No | ||
| title | Yes | ||
| category | No | ||
| condition | No | ||
| attributes | No | ||
| trade_type | No | 1 | |
| description | Yes | ||
| photo_paths | Yes | ||
| postal_code | No | ||
| photo_captions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, and it does well: it discloses that the draft is local-only, that photos are auto-rotated, EXIF/GPS-stripped and resized, and that the first photo becomes the cover. It does not disclose authentication/prerequisite state or what happens to existing drafts on repeat calls, leaving some behavioral gaps for an unannotated mutation tool.
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 single most important fact (local, nothing published), then compact enum glossaries and a clearly labelled PRICE POLICY block. Slightly longer than needed, and the parenthetical 'use suggest_category after push_draft if unsure' is easy to misread as an instruction for this call rather than a later one.
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 10 parameters, no annotations and an output schema present, the description covers the world-facing essentials: environment (local), side effects on photos, enum code meanings, currency units, and the price-decision policy. Remaining undocumented fields (attributes, postal_code, captions) are optional conveniences rather than things needed to call the tool 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 description coverage is 0%, so the description must compensate, and it does for the hard parameters: category as a numeric LEAF id with an example, all five condition codes spelled out, trade_type 1=Til salgs, and price as whole NOK. Five of ten parameters (title, description, attributes, postal_code, photo_captions) still get no semantic explanation anywhere.
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?
Specific verb+resource: 'Create a LOCAL draft ad', immediately qualified with '(nothing is sent to finn.no yet)', which cleanly separates it from push_draft and publish_draft. An agent can tell which of the draft-related siblings to call 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?
Explicit pre-call routing is given for price (use the user's named price, otherwise call suggest_price first and cite comparables) and for category (fall back to suggest_category via push_draft). No explicit exclusion such as 'use update_draft to modify an existing draft', so the when-not case is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_saved_searchA
Delete a saved search by name. Returns True if it existed.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description provides basic behavioral details: it deletes by name and returns True if it existed. However, it does not disclose whether the action is reversible, required permissions, or the behavior on invalid input. The mention of return value adds some transparency but is minimal.
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?
Two short sentences convey the purpose and a key behavioral detail with no unnecessary words. The description is front-loaded and efficient, earning its space.
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 the existence of an output schema (context signal), the description covers the return value concisely. However, it lacks context about error handling, prerequisites, or relation to sibling tools like check_saved_search. It is adequate for a simple tool but has room for improvement.
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 schema provides no description for the 'name' parameter (0% coverage). The description adds meaning by specifying that the tool operates 'by name', clarifying the parameter's role as the identifier of the saved search to delete. This compensates for the schema gap effectively for a single string 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?
Description clearly states the verb (Delete) and resource (saved search) with a specific identifier (by name). It distinguishes from siblings like save_search, list_saved_searches, and check_saved_search by describing a unique delete operation.
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?
No explicit guidance on when to use this tool versus alternatives, such as using check_saved_search first or handling non-existence. The description implies it can be used to delete a saved search, but does not provide context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_listingA
Fetch a full listing by its finnkode.
If ``vertical`` is omitted the server tries a cache hint first, then
probes each vertical until one returns a valid page. Results are cached
for 24 hours in a local SQLite database.
| Name | Required | Description | Default |
|---|---|---|---|
| finnkode | Yes | ||
| vertical | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses caching for 24 hours, fallback probing of verticals, and cache hint behavior, offering solid transparency for a read-only tool.
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?
Two clearly separated paragraphs: one for purpose, one for behavior. Concise without excess, though could add bullet points for readability.
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 simple parameters and an existing output schema, the description covers main behavior and caching. It omits return format but that's delegated to 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 coverage is 0%, so description adds value: it explains vertical's behavior when omitted (cache hint, probing). Finnkode is only named, but its role is obvious from the 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 description clearly states 'Fetch a full listing by its finnkode', providing a specific verb and resource. It distinguishes from sibling search/save tools by focusing on single listing retrieval.
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?
The context implies use when a finnkode is known, but no explicit when-to-use/alternatives are given. Siblings like search_finn are not mentioned, leaving the agent to infer usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_draftsB
List local drafts.
| 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?
No annotations are provided, so the description carries the full behavioral burden. "List" implies a read, but the definition doesn't state whether it is side-effect free, whether results are user-scoped, how "local" differs from server-side drafts, ordering, or whether an empty result is possible. The output schema covers return shape, but the operation's semantics remain under-disclosed.
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 single sentence is front-loaded with the verb and free of padding. However, its extreme brevity reflects under-specification rather than disciplined economy, leaving key scoping ambiguous.
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 list tool with an output schema, the description is minimally viable, but with no annotations the meaning of "local" and the relationship to other draft tools are unresolved. It stops short of what an agent needs to decide between list_drafts and siblings like preview_draft or my_ads.
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 there is no parameter semantics to document. Baseline 4 applies, and the description introduces no confusing parameter claims.
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?
"List local drafts" states a specific verb (list) and resource (drafts), with the modifier "local" narrowing scope. Siblings like create_draft, update_draft, and publish_draft are clearly different operations, though the description never explicitly contrasts itself with them.
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?
There is no guidance on when to call this tool, what precondition makes drafts "local," or which sibling to use instead (e.g., preview_draft or push_draft). The agent must infer usage entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_saved_searchesA
Return every saved search in the local store, ordered by name.
| 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?
No annotations are provided, so the description carries the full burden. It explicitly states the tool returns all saved searches and orders them by name. It does not mention side effects or permissions, but for a read-only listing operation, the description is adequately transparent.
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 description is a single sentence that conveys the essential information without unnecessary words. It is front-loaded and efficient.
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 no parameters, no annotations, and the presence of an output schema, the description is fairly complete. It could potentially mention that the output is a list or the ordering, but the output schema likely covers the return format. Overall, it is adequate.
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?
There are no parameters, and schema description coverage is 100%. The description does not add parameter-level meaning because none exist. Baseline for zero parameters is 4, which is appropriate.
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 description clearly states the tool returns every saved search in the local store, ordered by name. It uses a specific verb ('Return') and resource ('saved searches'), and differentiates from sibling tools like save_search, delete_saved_search, etc.
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?
The description does not explicitly state when to use this tool versus alternatives such as get_listing or search_finn. Usage is implied by the name and description, but no exclusions or comparison guidelines are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
loginB
Open a visible browser window on finn.no so the USER can log in by hand.
Login is passwordless (e-mail + one-time code from login.vend.no). The assistant never types credentials. The session is kept in the local profile.
| Name | Required | Description | Default |
|---|---|---|---|
| timeout_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does real work: it discloses that a visible browser window is opened, that the flow is passwordless (e-mail + one-time code from login.vend.no), that the assistant must not type credentials, and that the session persists in the local profile. It omits whether the call blocks until login completes, what happens on timeout, and what failure looks like.
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 core action in the first sentence, then three short supporting sentences with no filler. Only a minor deduction for the stray formatting/line-break artifacts and the fact that the most important constraint (the wait window) is absent.
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 values needn't be explained, and the auth flow is well described. Still, for a tool whose only knob is a 300-second blocking timeout, neither the schema nor the description explains the wait/failure behavior, leaving the agent without a basis for setting the parameter or handling expiry.
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 single parameter timeout_seconds has 0% schema description coverage, and the description never mentions it. The reader cannot tell from either source that the call waits up to 300 seconds by default for the user to finish, or what happens when it expires.
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?
Specific verb and resource: opens a visible browser window on finn.no for manual user login. An agent can tell this is the interactive authentication step, though it never explicitly distinguishes itself from the sibling login_status (which presumably checks whether a session exists).
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?
Usage is implied rather than stated: the mention that the session is kept in the local profile hints that repeated logins aren't needed, and 'the assistant never types credentials' tells the agent to hand off to the user. But there is no explicit 'call this when X, use login_status when Y' routing, and no prerequisites or failure guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
login_statusA
Check whether the saved browser profile is logged in to finn.no.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden: 'Check' implies a non-mutating read, and mentioning the 'saved browser profile' usefully discloses that state comes from persisted credentials rather than a passed token. It does not state what happens when no profile exists or whether the check is side-effect free.
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?
A single front-loaded sentence with no wasted words, sized appropriately for a trivial no-argument predicate tool.
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 values needn't be explained, and with zero parameters there is little else required. Only minor gap is not stating behavior when no saved profile is present.
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?
Zero parameters, so the baseline of 4 applies; there is nothing to disambiguate and the description correctly implies no inputs are needed.
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 ('Check') and a precise resource/scope: whether the saved browser profile is logged in to finn.no. This is distinguishable from the sibling 'login' tool, which presumably performs the login rather than reporting state, though the description doesn't name that distinction explicitly.
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?
Usage is only implied — an agent can infer it should be called before authenticated actions, but there is no explicit when-to-use, when-not, or reference to the 'login' alternative when the answer is negative. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
my_adsC
List the user's ads on finn.no ("Mine annonser") with state and available actions.
facet: ALL or DRAFT (confirmed); the response's `facets` lists the others.
| Name | Required | Description | Default |
|---|---|---|---|
| facet | No | ALL | |
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It implies a read/list operation, but it does not state authentication requirements, whether the operation is read-only, pagination behavior, or any rate limits or side effects.
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 description is short, front-loaded with the main purpose, and the second sentence adds useful facet context without unnecessary exposition. There is no wasted text.
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 values need less explanation, but the description still omits authentication context, pagination semantics for limit/offset, and when to choose this tool over sibling listing tools. For a no-annotation tool with 0% schema description coverage, more contextual detail is needed.
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%, and only the facet parameter is explained in the description, with allowed values ALL and DRAFT. The limit and offset parameters are not described at all, leaving two of three parameters with no added semantic meaning.
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 description gives a specific verb and resource: "List the user's ads on finn.no ('Mine annonser') with state and available actions." That is clear enough for an agent to understand what the tool does. It does not explicitly distinguish itself from the sibling tool list_drafts, so it falls short of a 5.
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?
The description mentions that facet may be ALL or DRAFT and that the response facets field lists others, but it gives no guidance on when to use this tool instead of siblings such as list_drafts or search_finn. There are no when-not conditions or alternative routing instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_draftA
Show a draft exactly as it would be sent to finn.no, plus blocking problems.
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden; 'Show' implies a read-only, non-mutating operation and it usefully discloses that validation problems are returned. However, it does not state that the draft is unmodified, whether any permissions are required, or whether the preview reflects the saved or unsaved state — relevant for a tool whose siblings include push_draft and publish_draft.
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?
One sentence, zero filler, with the outcome ('exactly as it would be sent to finn.no') and the secondary value ('plus blocking problems') both front-loaded. Nothing restates the name or title.
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 values need not be explained, and the description still calls out the two things an agent cares about from that output. For a single-parameter read tool this is nearly sufficient; only the missing read-only assurance and draft_id meaning keep it short of complete.
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 single required parameter draft_id is undocumented in both schema and description. The name is largely self-explanatory for a drafts-oriented tool, and sibling list_drafts/create_draft establish the ID concept, so the shortfall is not severe, but the description adds no meaning beyond the property name.
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 ('Show') and resource ('a draft') plus what is produced: the exact payload sent to finn.no and any blocking problems. That contrasts naturally with publish_draft and push_draft, though it never names those siblings explicitly, so differentiation is inferred rather than stated.
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?
Usage is only implied — 'blocking problems' hints it is a pre-publish check, but the description never says when to call it versus publish_draft or push_draft, nor what to do with the blocking problems it surfaces. No exclusions or alternatives are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_draftA
Publish a draft on finn.no. PUBLIC.
Flow: duplicate check (local + finn.no account) -> push as private draft
-> finn.no validation -> only with confirm=true: publish.
Call with confirm=true ONLY after the user saw the preview and said yes in chat.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the multi-step flow (duplicate check local + finn.no account, push as private draft, finn.no validation, then publish), and warns that the effect is public. It omits auth/login requirements and what happens when the duplicate check or validation fails.
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 action and the PUBLIC warning, then the flow, then the confirm rule — every line earns its place. Minor deduction for the fragmented 'PUBLIC.' and indented multi-line formatting that reads less cleanly than a single tight paragraph.
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 values needn't be explained, and the description covers the main risk (irreversible public posting gated by confirm) plus the internal validation sequence. Missing details are auth prerequisites and error/duplicate-failure behavior for what is an externally visible mutation.
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 compensate. It explains 'confirm' thoroughly as a publish gate that should only be true after user approval, but 'draft_id' is never described beyond its name — the agent must infer it comes from create_draft/list_drafts.
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 (publish a draft on finn.no) and adds the crucial scope qualifier that the result is PUBLIC, which distinguishes it from sibling preview_draft/push_draft operations.
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 an explicit gating condition: call with confirm=true ONLY after the user saw the preview and said yes in chat, which implicitly routes the agent to preview_draft first. The when-to-use rule is unambiguous and enforceable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
push_draftA
Upload a local draft to finn.no as a PRIVATE draft (not published, not visible).
Creates the finn.no draft if needed, uploads photos, saves the fields and
returns finn.no's own validation (`violations`). Safe to call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With zero annotations the description carries the full burden and does well: it discloses upsert semantics (creates draft if needed), side effects (uploads photos, saves fields), non-publication, and idempotency. It omits auth/permission requirements and any rate/latency caveats, keeping it below a 5.
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?
Three tight sentences; the private/non-published guarantee is front-loaded ahead of the mechanics and return summary. Nothing redundant.
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 the return-value mention is bonus rather than necessity, and the behavioral profile is unusually complete for an annotation-free tool. The only real gap is the meaning/origin of draft_id.
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?
Single parameter draft_id at 0% schema coverage. The phrase 'upload a local draft' implies draft_id identifies a local draft rather than a finn.no id, but the description never states this explicitly or says where the id comes from (e.g. create_draft or list_drafts). Additive but thin.
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?
Specific verb+resource: uploads a local draft to finn.no as a PRIVATE draft. The parenthetical '(not published, not visible)' clearly separates it from publish_draft and preview_draft, even though no sibling is named explicitly.
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?
'Safe to call repeatedly' and 'creates the finn.no draft if needed' imply when to use it (iterative sync of local edits), but there is no explicit when-not guidance or pointer to publish_draft/create_draft/update_draft as the alternative for other flows.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_searchB
Persist a named search for repeated monitoring via check_saved_search.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| query | Yes | ||
| filters | No | ||
| vertical | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| query | Yes | |
| filters | No | |
| vertical | Yes | |
| last_finnkodes | No | |
| last_checked_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It only says 'persist', implying a write operation, but lacks details about side effects, permissions, rate limits, or what the response contains. This is inadequate for a mutation tool.
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 description is very concise (one sentence), but it sacrifices necessary detail. It is front-loaded with purpose but lacks parameter explanations and behavioral context, making it underspecified.
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 the complexity (4 parameters, 3 required, write operation) and the presence of an output schema, the description should at least explain parameter roles. It does not, leaving significant gaps in understanding. The description is minimally adequate for a simple tool but insufficient for its actual complexity.
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%, and the description adds no information about any of the 4 parameters (name, query, filters, vertical). The schema provides types and enums, but the description fails to explain their meaning or usage, leaving the agent without guidance.
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 description clearly states the tool persists a named search for repeated monitoring via check_saved_search. It uses specific verb 'persist' and resource 'named search', and distinguishes its purpose from siblings like list_saved_searches or delete_saved_search.
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?
The description explicitly states that this tool is for repeated monitoring via check_saved_search, providing clear usage context. However, it does not explicitly mention when not to use it or list alternatives beyond check_saved_search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_finnA
Search finn.no within a vertical.
``vertical`` is one of: ``bap`` (Torget / used goods), ``homes`` (real
estate for sale), ``lettings`` (real estate for rent), ``cars_used``,
``cars_new`` (not yet supported by the scraper backend), ``jobs``.
``query`` is a free-text keyword. ``filters`` is a dict of extra
URL-query parameters understood by finn.no (e.g. ``{"price_to":"300000"}``
for cars, ``{"location":"1.20001.20061"}`` for Oslo).
Returns up to ~50 ``SearchResult`` entries. Fewer if finn.no returned
fewer matches; an empty list is a valid result.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| query | Yes | ||
| filters | No | ||
| vertical | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses return behavior (up to ~50 SearchResult entries, empty list valid), unsupported backend (cars_new), and extra URL-query parameters for filters. This is thorough for behavioral expectations.
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?
Description is extremely concise: two short paragraphs front-loading the purpose, then details on parameters and return behavior. No redundant sentences; every line adds value.
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 the tool complexity (4 params, output schema), the description covers essentials: verticals, query, filters, return limits, and unsupported items. Missing page parameter explanation is minor, and output schema details are not needed since it exists separately. Adequate for informed use.
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 description must compensate. It adds meaning to vertical (expands enum with descriptions), query (free-text), and filters (dict example). However, it omits the 'page' parameter entirely. Thus partial coverage, baseline 3.
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 description clearly states 'Search finn.no within a vertical', specifying the verb (search) and resource (finn.no within a vertical). It lists all vertical options (bap, homes, lettings, etc.) and distinguishes from sibling tools (get_listing, save_search, etc.) which have different purposes.
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?
The description implies usage through naming and vertical specification, but does not explicitly state when to use this tool vs. alternatives (e.g., 'use for general search; use get_listing for a single item'). No exclusions or when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_categoryA
finn.no's category suggestions based on the draft's uploaded photos (needs push_draft first).
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It usefully discloses that the suggestion is derived from previously uploaded photos and depends on push_draft having run, but says nothing about whether the call is read-only, whether it can fail when no photos exist, or any cost/latency.
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?
A single short sentence with the prerequisite front-loaded alongside the purpose; every clause earns its place and nothing is padded.
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 values need not be explained, and the one required parameter plus the push_draft dependency are covered. What remains missing is failure/no-photo behavior, but the definition is adequate to call the tool 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?
Only one parameter (draft_id) with 0% schema description coverage. The description implies the id refers to a draft that has already been pushed with photos, adding indirect meaning, but never states the expected format or where to obtain the id.
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 (suggests) and resource (category) plus the data source (the draft's uploaded photos), which distinguishes it from suggest_price. It stops short of explicitly contrasting itself with that sibling, but the purpose is unmistakable.
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?
The parenthetical '(needs push_draft first)' is an explicit prerequisite that tells the agent the correct call order relative to a sibling. No when-not-to-use guidance or alternative suggestions are given, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_priceA
Market price for an item: median of comparable "Til salgs" ads on finn.no Torget.
Default price source whenever the user did not name a price. `query` =
short search words (brand + model, e.g. "DualSense PS5 kontroller").
Outliers are dropped (IQR); result is rounded. Show the user the
suggested price and a few of the `examples`.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| condition | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does real work: it discloses the statistical method (median), outlier handling (IQR), rounding, and that representative `examples` come back and should be surfaced to the user. It omits failure behaviour — e.g. what happens when too few comparables exist — which matters for a price estimate.
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?
Short and front-loaded: method first, then default-usage rule, then parameter naming guidance, then output handling. The line break layout is slightly noisy but every sentence adds 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?
An output schema exists, so return values need no explanation, and the description still usefully flags `examples` as a field to show. The main gap is the undocumented `condition` parameter and unstated behaviour when no comparable ads are found.
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 all parameter meaning. It compensates well for `query` by defining it as short brand+model search words with a concrete example, but `condition` (the 1-5 enum) is never mentioned, leaving half the parameters undocumented.
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 with its exact derivation method ("median of comparable 'Til salgs' ads on finn.no Torget"), which no sibling tool offers. It is clearly distinguishable from suggest_category and the search tools.
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?
"Default price source whenever the user did not name a price" gives an explicit selection rule an agent can act on. It stops short of naming an alternative tool or stating when not to call it (e.g. category mismatch), so it is not full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_draftC
Change fields of a local draft (e.g. {"price": 1500, "category": "43"}).
| Name | Required | Description | Default |
|---|---|---|---|
| changes | Yes | ||
| draft_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, yet it only says fields are changed. It does not disclose permissions, error behavior, whether existing unspecified fields are preserved, or any side effects beyond local draft mutation.
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 definition is a single front-loaded sentence with an embedded example, and no sentence is wasted. It is appropriately sized for a short mutation tool.
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?
This is a mutation tool with no annotations, low parameter documentation, and nested object input. Although an output schema exists and reduces the need to describe return values, the description remains too thin about valid draft IDs, allowed changes, and mutation behavior.
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%, and the description only partially compensates by showing one example object for "changes". It does not describe allowed keys or value constraints, and it says nothing meaningful about "draft_id" beyond the parameter name.
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 description uses a specific verb ("Change fields") and resource ("local draft"), and the inline example clarifies the kind of payload involved. It does not explicitly distinguish itself from siblings such as create_draft, publish_draft, or preview_draft, so it stops short of full clarity.
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 no guidance on when to use this tool versus alternatives like create_draft, publish_draft, push_draft, or preview_draft. There are also no stated preconditions, exclusions, or workflow context.
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.
20 tool updates
v0.2.0- First observed
ad_action - First observed
check_duplicate - First observed
check_saved_search - First observed
confirm_not_duplicate - First observed
create_draft - First observed
delete_saved_search - First observed
get_listing - First observed
list_drafts - First observed
list_saved_searches - First observed
login - First observed
login_status - First observed
my_ads - First observed
preview_draft - First observed
publish_draft - First observed
push_draft - First observed
save_search - First observed
search_finn - First observed
suggest_category - First observed
suggest_price - First observed
update_draft
TDQS
Scored across 20 tools
Most tools target clearly distinct resources and lifecycle steps (drafting, publishing, ad actions, search, saved searches, auth). The only plausible confusion is between push_draft, publish_draft, and ad_action, but descriptions explicitly distinguish private upload vs public publish vs post-publish actions, so boundaries remain clear.
The dominant pattern is verb_noun (list_drafts, preview_draft, create_draft, update_draft, push_draft, publish_draft, suggest_price, save_search, check_duplicate, search_finn, get_listing). A few deviations exist (ad_action, my_ads, login_status, bare-verb login), but they remain readable and contextually obvious.
20 tools is on the heavy side, but the server genuinely spans several distinct capabilities—auth, local drafting, publishing, marketplace search, and saved-search monitoring—and no tool appears redundant. Slightly over what a single-purpose server would need, but reasonable for this scope.
The seller lifecycle is well covered: create/update/preview drafts, category and price suggestions, duplicate detection, private push, publish, and ad actions plus listing/browse/saved-search CRUD. Minor gaps exist (no single-draft getter, no buyer messaging, no explicit photo curation tool), but agents can work around them.
Maintenance
Related MCP Connectors
Holiday photo MCP server: list and fetch personal holiday photos inline in Claude chat.
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
AI-agent-first offers directory: search and publish listings via MCP.
Publish and schedule videos to TikTok, YouTube Shorts, Instagram, Facebook, LinkedIn, Pinterest, Bluesky, Threads and X from Claude, Cursor or any MCP client. Upload once, post everywhere, track views in unified analytics, and retry failed posts. Official platform APIs only, free plan available. Docs: https://docs.multi-upload-tool.com/mcp
Related MCP Servers
- AlicenseAqualityCmaintenanceAn MCP server that provides access to finn.no, Norway's largest online classifieds marketplace, enabling searches and listing retrieval across used goods, real estate, cars, and jobs.861MIT
- FlicenseAqualityCmaintenanceEnables searching Facebook Marketplace listings from Claude using your existing Facebook session without a browser.72-
- AlicenseAqualityBmaintenanceEnables posting second-hand items to Facebook Marketplace from local photo folders via Claude, featuring login, listing creation, pricing reference, and publishing tools.75MIT
- AlicenseAqualityBmaintenanceEnables turning photos and observed facts into a ready-to-publish Leboncoin ad, with comparable search, asking-price statistics, category lookup, local drafts, and browser form automation that stops one click short of publishing until approved.23MIT