Skip to main content
Glama

🛒 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.

Python MCP Playwright Tests License: MIT Tools

⭐ If this saves you time, star the repo — it helps others find it.

English · Русский


🚀 Quick Start

🧰 Tools

🔄 How it works

🛡️ Safety

🧭 Recon

⚙️ Config

🩺 Troubleshooting

❓ FAQ


📖 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 chromium

2. Register with your MCP client

Edit claude_desktop_config.json and restart Claude Desktop:

OS

Path

Linux

~/.config/Claude/claude_desktop_config.json

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

{
  "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-mcp

Command: 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.

IMPORTANT

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

login

Opens a visible Chromium on finn.no so you log in (e-mail + one-time code). The assistant never handles credentials.

login_status

Checks whether the saved profile is logged in; returns how many ads the account has.

Tool

What it does

Touches finn.no?

check_duplicate

Title + photo match against local history and all your finn.no ads (active, sold, expired, drafts).

read

suggest_price

Median price of comparable "Til salgs" Torget ads; IQR outlier removal; rounded; returns example ads.

read

create_draft

Local draft. Photos auto-rotated, EXIF/GPS stripped, resized to ≤2400 px, HEIC supported. Reports possible duplicates.

—

update_draft

Change any field of a local draft (price, category, condition, …).

—

list_drafts / preview_draft

Inspect local drafts and the exact payload that would be sent.

—

push_draft

Create/update a private draft on finn.no, upload photos, return finn.no's own validation. Never publishes.

write (private)

suggest_category

finn.no's category prediction from the uploaded photos (leaf + full path).

read

confirm_not_duplicate

Unblock a draft the duplicate guard flagged — only after you say it's a different item.

—

publish_draft

Duplicate check → push → validation → with confirm=true only: publish. Detects the BankID requirement.

public

Tool

What it does

my_ads

"Mine annonser": your ads with state, facets and the actions finn.no offers for each.

ad_action

Run one of those actions by name (e.g. DELETE). Anything that changes an ad needs confirm=true.

Tool

What it does

search_finn

Search bap (Torget), homes, lettings, cars_used, jobs with free text + finn.no URL filters.

get_listing

Full listing by FINN-kode (JSON-LD parsing, 24 h cache).

save_search / list_saved_searches / delete_saved_search

Persist named searches.

check_saved_search

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

suggest_price → median of comparable "Til salgs" ads, IQR outliers dropped, rounded (10 / 50 / 100 / 500 kr steps by size)

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

login opens a window; you type e-mail and code yourself.

Nothing goes public without your "yes"

publish_draft returns a preview unless confirm=true; tool docs require explicit user consent.

Destructive actions are gated

ad_action requires confirm=true for any non-GET action (delete, …).

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 "commit": true and payment-like URLs.


🧭 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/start
  1. A Chromium window opens with the same profile the server uses — log in.

  2. Click through the flows (new ad, photos, price, "Publiser", Mine annonser, edit…). Press the red 📸 Snapshot form button on each form step.

  3. Close the window.

File

Content

recon/<ts>/endpoints.md

Endpoint map grouped by method + path template (IDs → {id}), write calls first, ⛔ = blocked

recon/<ts>/endpoints.json

Same, machine-readable

recon/<ts>/requests.jsonl

Every API call: headers, bodies, status, responses — redacted (cookies, tokens, e-mails, phone numbers)

recon/<ts>/bodies/

Large bodies; multipart uploads summarized (field names, sizes — no file bytes)

recon/<ts>/forms/

Form snapshots: every input/select incl. shadow DOM, labels, options, selectors + full-page screenshot

recon/<ts>/private/full.har

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

FINN_PROFILE_DIR

$XDG_DATA_HOME/finn-mcp/browser-profile

Persistent Chromium profile (your session)

FINN_HEADLESS

1

0 shows the browser for all calls (debugging)

FINN_CHROMIUM

Playwright's Chromium

Path to a custom Chromium/Chrome binary

XDG_DATA_HOME

~/.local/share

Base for profile, drafts, cache

FINN_CACHE_DB

…/finn-mcp/cache.sqlite

Search/listing cache (24 h)

FINN_BACKEND

scraper

Search backend (official is a stub)

FINN_BASE_URL

https://www.finn.no

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, duplicates

Tests 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 tools
ad_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.
    
NameRequiredDescriptionDefault
actionYes
confirmNo
finnkodeYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.
    
NameRequiredDescriptionDefault
titleYes
photo_pathsNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

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.
    
NameRequiredDescriptionDefault
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
    
NameRequiredDescriptionDefault
priceNo
titleYes
categoryNo
conditionNo
attributesNo
trade_typeNo1
descriptionYes
photo_pathsYes
postal_codeNo
photo_captionsNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

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.
NameRequiredDescriptionDefault
finnkodeYes
verticalNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior2/5

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.

Conciseness3/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
timeout_secondsNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.
    
NameRequiredDescriptionDefault
facetNoALL
limitNo
offsetNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

NameRequiredDescriptionDefault
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.
    
NameRequiredDescriptionDefault
confirmNo
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
    
NameRequiredDescriptionDefault
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

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.
NameRequiredDescriptionDefault
pageNo
queryYes
filtersNo
verticalYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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).

NameRequiredDescriptionDefault
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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`.
    
NameRequiredDescriptionDefault
queryYes
conditionNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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"}).

NameRequiredDescriptionDefault
changesYes
draft_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 20 tool updatesv0.2.0
    • First observedad_action
    • First observedcheck_duplicate
    • First observedcheck_saved_search
    • First observedconfirm_not_duplicate
    • First observedcreate_draft
    • First observeddelete_saved_search
    • First observedget_listing
    • First observedlist_drafts
    • First observedlist_saved_searches
    • First observedlogin
    • First observedlogin_status
    • First observedmy_ads
    • First observedpreview_draft
    • First observedpublish_draft
    • First observedpush_draft
    • First observedsave_search
    • First observedsearch_finn
    • First observedsuggest_category
    • First observedsuggest_price
    • First observedupdate_draft

TDQS

A3.6/5.0

Scored across 20 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    An 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.
    8
    6
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables 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.
    23
    MIT