Skip to main content
Glama
mikki321

night-margin-mcp

by mikki321

night-margin-mcp — Margin Engine

Wheelhouse optimizes what guests pay. night-margin protects what you keep.

Built by a property manager who runs 73 listings in Lapland — for operators like us.

An MCP server that shows every pricing decision for a short-term rental portfolio net of turnover costs — the margin guard for Wheelhouse pricing, the profit layer underneath its revenue optimization (ADR, RevPAR). The key metric: net per available night.

Quick start

claude mcp add margin -- npx -y night-margin-mcp

That's it — works with zero config on synthetic demo data. Open Claude and ask:

Where is my portfolio leaking money in June 2026?

You'll get the leak figure, the net-per-night metric, and your best and worst properties in under a minute. When you're ready to run the analysis against your own Wheelhouse portfolio, see Wheelhouse API key below.

On live data the first call is slower: one request per listing, serial, to stay inside Wheelhouse's 60 req/min limit — 3 listings ≈ 5 s, 73 listings ≈ 90 s. Results are then cached for 10 minutes.

Related MCP server: tokencost-mcp-server

What you get

The first line is the pain, in euros — this is actual zero-config output (June 2026, demo data):

€132 is leaking from 8 bookings that don't cover their own turnover cost. (4.0% of booked nights are net-negative) Net per available night: €74.7 Occupancy 72.9% (175 booked, 65 gap nights) Gross €22,821 − turnover costs €4,900 = net €17,921

Property

Net/night

Booked nights

Gap nights

Net €

demo-1br-03

€21.4

15

15

€643

demo-1br-01

€32

18

12

€960

demo-3br-08

€178.1

30

0

€5,344

Same math, your numbers: set WHEELHOUSE_API_KEY and the analysis runs on your live portfolio.

Live demo

Want to see the output before installing anything? https://mikki321.github.io/night-margin-mcp/ — portfolio KPIs, a per-property heatmap of net per available night, and a triage table of net-negative bookings, generated by this server from the synthetic demo portfolio that ships with the package.

Example prompts

The server provides ten tools: three read-only analysis tools, a four-tool decision loop (see The decision loop), a proactive alerts tool (see Proactive alerts), review_history — a read-only mirror of your own past months net of estimated turnover cost (a description of what happened, never a forecast) — and margin_copilot, which ranks the below-floor gap nights into money-moves, weighs the options for each and marks the recommended one (read-only; staging routes through propose_decisionsapply_decision). No dates needed — analyze_portfolio and compare_strategies default to the last 30 + next 90 days (recent turnovers + your booking horizon), propose_decisions to the next 30 days; pass from/to to change. Try these directly in Claude:

  1. analyze_portfolio — where is the money leaking?

    Where is my portfolio leaking money?

  2. compare_strategies — gross vs. net in the same picture:

    Compare two strategies for June 2026: (A) fill gap nights at a 40% discount and (B) raise the minimum stay to three nights with a 10% price increase. Which one delivers the better net per night?

  3. gap_night_check — is a single gap night worth filling?

    Property demo-1br-01 has a gap night on 2026-06-23. What's the floor price, and is the night worth filling?

  4. propose_decisions — which upcoming nights are at risk of selling below cost?

    Which gap nights are about to sell below my cost floor?

  5. apply_decision — act on a proposal:

    Apply decision d3

    Without explicit confirmation this is a dry run: it prints the exact rate payload that would be written and changes nothing. Prices change only when you confirm the write, and every applied decision can be undone with revert_decision.

  6. Risk presetspropose_decisions and gap_night_check both take an optional risk parameter (conservative | recommended | aggressive, default recommended) that scales the floor's minimum margin — Wheelhouse's own CON/REC/AGG language:

    What should I do this week? Use the aggressive risk preset.

  7. check_alerts — proactive check for gap-floor breaches and new bookings (see Proactive alerts):

    Check for any pricing alerts.

The core message of the demo: filling gaps at a discount can grow revenue while shrinking profit — a 2-night and a 7-night booking consume the same cleaning.

The decision loop

New in 0.3.0 — analysis turns into safe, reversible action:

  1. propose_decisions finds upcoming gap nights (next 30 days by default) where the current price recommendation sits below your cost floor (turnover + travel + MIN_MARGIN, scaled by an optional risk preset — see Example prompts) and proposes fixing those nights at the floor so they can't sell below cost. Proposals go into a local decision log — proposing never touches prices.

  2. apply_decision writes one proposal to Wheelhouse as fixed custom rates — but only with explicit confirm: true. The default is a dry run showing the exact payload without writing anything. Before the first real write, the prior custom rates are snapshotted to the decision log, so revert_decision can always delete what was written and restore what was there before.

  3. set_target stores a monthly gross revenue target per property; analyze_portfolio then reports progress toward any targets whose month overlaps the analysis window.

The safety model in one line: the analysis tools (analyze_portfolio, compare_strategies, gap_night_check) and propose_decisions never change any prices; writes happen only through apply_decision/revert_decision with an explicit confirm: true, always target the listing's own channel, and every write is revertible. Without a WHEELHOUSE_API_KEY you can run the whole loop up to the dry run on demo data — real writes require the key and a fresh propose against your own portfolio. The decision log and targets live locally in NM_STATE_DIR (default ~/.night-margin).

Proactive alerts (watch mode)

check_alerts is read-only and checks two things: (1) upcoming gap nights priced below your cost floor (same data as propose_decisions, always the recommended risk preset, but this tool never saves proposals to the decision log), and (2) new bookings since the last check, each shown net of turnover costs — the same twist as the rest of the server, now in a booking notification. The first run establishes a baseline (records existing bookings without alerting on them); later runs alert on bookings that were not present in the previous check. The Wheelhouse reservation payload carries no creation timestamp, so a booking made earlier will surface the first time its dates enter the 120-day horizon — "new to this check", not "booked since yesterday".

By default check_alerts is silent — it just returns the report as text, same as every other tool. To get pushed notifications, configure a channel:

Variable

Description

NM_TELEGRAM_BOT_TOKEN / NM_TELEGRAM_CHAT_ID

Send alerts via a Telegram bot (checked first).

NM_WEBHOOK_URL

Send alerts to a generic incoming webhook (Slack-compatible {text} JSON body) — used only if Telegram isn't configured.

Neither is required — without either, check_alerts still works and simply says no channel is configured. Notifications are off unless you set one of these — nothing is ever sent by default, and the token/URL are never logged or echoed back in error messages.

For unattended checks (e.g. a daily cron job), run the server with --watch: it runs check_alerts once (sending a notification if a channel is configured), prints the report to stdout, and exits — no MCP server, no stdio transport:

0 8 * * * WHEELHOUSE_API_KEY=... NM_TELEGRAM_BOT_TOKEN=... NM_TELEGRAM_CHAT_ID=... npx -y night-margin-mcp --watch

Configuration (env)

Every setting is optional — without them, the server runs the manual cost model on synthetic demo data. Environment variables are passed via claude mcp add's -e flags:

claude mcp add margin -e WHEELHOUSE_API_KEY=xxx -e COST_SOURCE=csv -e CSV_PATH=/path/to/costs.csv -- npx -y night-margin-mcp

Variable

Default

Description

WHEELHOUSE_API_KEY

Your own Wheelhouse integration key. When set, bookings are fetched from the Wheelhouse RM API; without it, synthetic demo data is used.

WHEELHOUSE_CHANNEL

Optional override for the channel parameter on Wheelhouse read calls (reservations, price recommendations). By default each listing's own channel field is used, which the API accepts. Writes (apply_decision) always go to the listing's own channel — this override never affects writes.

COST_SOURCE

manual

Source of turnover costs: manual | csv | cleanhub.

AVG_TURNOVER_COST

70

Manual mode: € per turnover (cleaning). Also serves as the fallback in CSV mode when a booking has no cost row.

COST_TIERS

Optional tiering, e.g. 1br:55,2br:70,3br:95 — matched against the property's property_id by substring; everything else gets AVG_TURNOVER_COST.

CSV_PATH

CSV mode: path to the cost CSV (required when COST_SOURCE=csv). See CSV mode.

CLEANHUB_API_URL / CLEANHUB_TOKEN

CleanHub mode: actual turnover costs from the CleanHub field-operations platform over HTTP (both required when COST_SOURCE=cleanhub).

MIN_MARGIN

25

Minimum margin € for the gap-night floor: floor = turnover + travel + MIN_MARGIN (scaled by the risk preset — see Example prompts). Used in gap_night_check's fill/skip verdict and in propose_decisions'/check_alerts' floor proposals.

NM_STATE_DIR

~/.night-margin

Local state directory for the decision log, monthly targets, and the seen-bookings set (used by propose_decisions, apply_decision, revert_decision, set_target, check_alerts). Nothing is ever stored in the package directory.

NM_TELEGRAM_BOT_TOKEN / NM_TELEGRAM_CHAT_ID

Optional: send check_alerts notifications via a Telegram bot. See Proactive alerts.

NM_WEBHOOK_URL

Optional: send check_alerts notifications to a Slack-compatible incoming webhook (used only if Telegram isn't configured). See Proactive alerts.

CSV mode

If you know your actual turnover costs per booking, a CSV gives you the most accurate analysis. Schema (header row required):

reservation_id,property_id,checkin,checkout,nights,gross_revenue,cleaning_cost,travel_cost,laundry_cost,turnover_date,is_sunday_or_holiday
demo-1br-01-r1,demo-1br-01,2026-06-03,2026-06-10,7,571,56,16,9,2026-06-10,false

A synthetic sample file (887 rows, covering the full 2026 calendar year of the demo data) ships with the package at examples/sample-costs.csv, and can be downloaded directly:

https://raw.githubusercontent.com/mikki321/night-margin-mcp/main/examples/sample-costs.csv

Usage:

curl -o costs.csv "https://raw.githubusercontent.com/mikki321/night-margin-mcp/main/examples/sample-costs.csv"
claude mcp add margin -e COST_SOURCE=csv -e CSV_PATH="$PWD/costs.csv" -- npx -y night-margin-mcp

Cost rows are matched to bookings primarily by reservation_id, and secondarily by the composite key property_id|checkin|checkout. The tool response reports the attribution quality — e.g. "Cost attribution: 289/289 bookings matched by reservation_id", or with mixed sources "Cost attribution: 41 by reservation_id, 6 by composite key, 3 by average fallback (50 total)". If a row is missing and no AVG_TURNOVER_COST fallback is set, you get a clear error listing the affected bookings.

Wheelhouse API key

Without a key, the server runs on synthetic demo data (and says so in every response). With a key, you get your real bookings from the Wheelhouse RM API: the server fetches your listings and reservations, and every metric is computed from your own portfolio.

  • The key is your own Wheelhouse integration key (the API's X-Integration-Api-Key header). Get it from your Wheelhouse account's integration settings or from Wheelhouse support — API documentation: https://api.usewheelhouse.com/wheelhouse_rm_api.

  • Pass it as an environment variable: claude mcp add margin -e WHEELHOUSE_API_KEY=xxx -- npx -y night-margin-mcp.

  • Never commit the key to git — not in a .env file in the repo, not in README examples, not in commits. The key travels only as an environment variable.

If the key is invalid or the network flakes, the server returns a clear error with instructions — it does not silently fall back to demo data, so you'll never mistake mock numbers for your own.

For developers

Local development:

npm install
npm test
npm run build
claude mcp add margin -- node "<repo path>/dist/index.js"

If the npm package doesn't work for any reason, the same server installs directly from GitHub:

claude mcp add margin -- npx -y github:mikki321/night-margin-mcp

Exploring the Wheelhouse API with curl

Use these commands to verify auth and inspect response shapes (redact guest names/emails before sharing; field names and formats are preserved):

# 1) Listings — confirms auth + provides listing_id and channel
curl -s -H "X-Integration-Api-Key: $WHEELHOUSE_API_KEY" \
  "https://api.usewheelhouse.com/ss_api/v1/listings?per_page=5&page=1" | head -c 4000

# 2) Reservations — THE blocking one (full JSON for 2–3 reservations)
curl -s -H "X-Integration-Api-Key: $WHEELHOUSE_API_KEY" \
  "https://api.usewheelhouse.com/ss_api/v1/listings/<LISTING_ID>/reservations?channel=<CHANNEL>" | head -c 6000

# 3) Price recommendations — for gap_night_check, lower priority
curl -s -H "X-Integration-Api-Key: $WHEELHOUSE_API_KEY" \
  "https://api.usewheelhouse.com/ss_api/v1/listings/<LISTING_ID>/price_recommendations?channel=<CHANNEL>" | head -c 4000

The rate limit is 60 requests/min — the server runs requests serially and backs off on 429 responses (2 s / 4 s / 8 s).

Core math

net_per_night  = (gross − cleaning − laundry − travel) / available nights
available      = booked nights + gap nights in the analysis window
gap_floor      = turnover cost + travel + MIN_MARGIN
leak           = Σ(€ of net-negative bookings) and % of booked nights

All data shipped with the repo and the package is synthetic — no real customer or property data is included.

Available Tools

10 tools
analyze_portfolioAnalyze portfolio net per available nightA

The margin guard for Wheelhouse pricing. Computes a short-term rental portfolio's net after turnover costs (cleaning, laundry, travel): net per available night, leak (net-negative bookings), and the best and worst properties. Read-only — never changes any prices. from/to are optional — without them the window defaults to the last 30 + next 90 days.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoPeriod end (exclusive), YYYY-MM-DD (optional — defaults to last 30 + next 90 days)
fromNoPeriod start, YYYY-MM-DD (optional — defaults to last 30 + next 90 days)
avg_turnover_costNoOverride AVG_TURNOVER_COST for this run: € per turnover (manual mode)

TDQS

A4.3/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 burden. It explicitly states 'Read-only — never changes any prices', which is a critical behavioral trait. It also explains parameter defaults. More details on authentication or rate limits are not necessary for this simple analytical 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?

The description is concise, consisting of three to four sentences. It front-loads the key identity ('The margin guard for Wheelhouse pricing') and immediately explains what it computes. Every sentence adds information, though the first sentence could be more explicit.

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 output schema, the description lists the specific outputs (net per available night, leak, best/worst properties), setting expectations. For a tool with three optional parameters and a well-defined purpose, the description is fairly complete and covers the essential aspects.

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 100% with each parameter having a description. The description adds value by clarifying the default window behavior for from/to and explaining avg_turnover_cost as an override in € per turnover, providing context beyond 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 the verb 'computes' and the resource 'short-term rental portfolio's net after turnover costs', listing specific outputs (net per available night, leak, best/worst properties). It distinguishes itself from siblings like set_target and apply_decision by emphasizing its read-only analytical nature.

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 provides clear context: it is read-only and never changes prices, with optional from/to parameters defaulting to last 30 + next 90 days. It does not explicitly list when not to use it or alternatives, but the context of sibling tools and the described function imply appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

apply_decisionApply a pricing decision to WheelhouseA

Applies a proposed pricing decision to Wheelhouse for real (writes fixed custom rates for the decision's gap nights). This tool DOES change prices — but only with explicit confirm=true; it defaults to a dry run that shows the exact payload without writing anything. The prior custom rates are snapshotted to the decision log before writing, so every applied decision can be undone with revert_decision. Requires WHEELHOUSE_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoMust be true to actually write to Wheelhouse — without it you get a dry-run preview
dry_runNoPreview the exact payload without writing (default: true unless confirm=true)
decision_idYesDecision id from propose_decisions, e.g. "d2"

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully covers behavioral traits: it confirms the tool mutates prices, requires explicit confirmation, snapshots prior rates for reversibility, and requires an API key. No contradictions.

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 well-structured sentences. The first sentence states the primary action and its mutability; the second provides critical usage details (dry-run, snapshot, API key). No wasted words.

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?

The description explains the dry-run preview and the write behavior, and mentions the snapshotting for revert. It lacks explicit details on the output format (e.g., confirmation response), but given the tool's write nature, this 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?

Schema coverage is 100%, but the description adds meaningful context beyond parameter descriptions by explaining the dry-run behavior and the conditional writing based on confirm. This helps the agent understand the interplay between parameters.

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?

Clearly states the tool applies a pricing decision to Wheelhouse, writing fixed custom rates for gap nights. Distinguishes from sibling tools like propose_decisions and revert_decision by specifying the action (apply vs propose/revert).

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?

Describes the dry-run default and the need for confirm=true to write, and mentions the snapshotting for revert. However, it does not explicitly state when to use this tool over siblings, though the context implies it follows propose_decisions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_alertsCheck for gap-floor and new-booking alertsA

Read-only proactive check: (1) upcoming gap nights priced below your cost floor (recommended risk preset — same data as propose_decisions, but this tool never saves proposals to the decision log), and (2) new bookings since the last check, each shown net of turnover costs. Never writes prices. Sends a notification if a channel is configured (NM_TELEGRAM_BOT_TOKEN + NM_TELEGRAM_CHAT_ID, or NM_WEBHOOK_URL) and send is not false — without a channel configured, nothing is sent and the text report is returned as usual. Also available as night-margin-mcp --watch for cron.

ParametersJSON Schema
NameRequiredDescriptionDefault
sendNoSend a notification if a channel is configured (default true — set NM_TELEGRAM_BOT_TOKEN + NM_TELEGRAM_CHAT_ID, or NM_WEBHOOK_URL, to configure one). Set false to only see the report without sending anything.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries full burden. It discloses read-only behavior, no price writes, and detailed notification logic (channel config, default send). Slightly vague on what 'nothing is sent' entails if no channel, but adequate.

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?

The description is front-loaded with the core purpose, uses numbered points for clarity, and includes all necessary details. It is slightly verbose by including the cron alternative inline but remains well-structured.

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 output schema, the description explains the return (text report, optional notification) but does not detail the report contents or format. For a two-alert tool, the description covers key behavioral aspects, but a sample or structure would improve completeness.

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 single parameter 'send' is described in the schema (100% coverage). The description adds context about default behavior and conditional sending, which goes beyond the schema's description. This adds meaningful value for an agent.

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 specifies two distinct alert checks (gap-floor and new-booking) and clearly distinguishes from propose_decisions by stating it never saves proposals. The verb 'check' and resource 'alerts' are specific and unambiguous.

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 explains the tool is for proactive checks and contrasts with propose_decisions. It also mentions the cron alternative. However, it does not explicitly list when to avoid this tool versus siblings like gap_night_check or review_history, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_strategiesCompare pricing strategies on netA

Simulates two pricing strategies and compares them to the baseline on net after turnover costs: A fills gap nights at a discount (default 40% off the property's ADR), B drops bookings below a minimum stay and raises the remaining prices (default min 3 nights, +10%). Shows gross, net, net/night, occupancy, turnovers, and leak per scenario — revealing when gross-optimizing fill is a net loss. Strategy A assumes every gap night sells at the discounted price — an upper bound, not a forecast. Read-only simulation — never changes any prices. from/to are optional — without them the window defaults to the last 30 + next 90 days.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoPeriod end (exclusive), YYYY-MM-DD (optional — defaults to last 30 + next 90 days)
fromNoPeriod start, YYYY-MM-DD (optional — defaults to last 30 + next 90 days)
min_stayNoStrategy B: minimum stay in nights — bookings shorter than this are dropped (default 3)
uplift_pctNoStrategy B: price uplift percentage for the remaining bookings (default 10)
discount_pctNoStrategy A: gap night price discount as a percentage of the property's ADR (default 40)

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly states it is a read-only simulation that never changes prices, explains assumptions (e.g., Strategy A is an upper bound), and lists the metrics shown. Since no annotations exist, the description carries the burden well.

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?

The description is efficiently written and front-loaded with the purpose, though it could be slightly more concise; it is not overly verbose.

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 output schema and 5 optional parameters, the description covers strategies, defaults, assumptions, and metrics. It could mention edge cases or error conditions but is reasonably complete.

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 100%, but the description adds context beyond the schema by explaining the strategies' logic and default behaviors, enriching the meaning of parameters like discount_pct and uplift_pct.

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 it simulates and compares two pricing strategies to baseline, specifying the actions of each strategy. It distinguishes itself from sibling tools like 'analyze_portfolio' or 'gap_night_check' by being a dedicated simulation/comparison tool.

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 the tool is for comparing pricing strategies but does not explicitly state when to use it over alternatives, nor does it provide exclusions or when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gap_night_checkCheck gap night fill (FILL/SKIP)A

Checks whether filling a single gap night is worth it: computes the floor price (turnover cost + travel + minimum margin MIN_MARGIN, adjustable with the risk preset) from the median of the property's actual cost rows and compares the candidate price against it → FILL if price ≥ floor, otherwise SKIP. The verdict reports both the floor clearance and the actual net after turnover costs. If the date is already booked, reports which booking covers it. Read-only — never changes any prices.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYesNight to check, YYYY-MM-DD
riskNoRisk preset for the floor's minimum margin (Wheelhouse's own CON/REC/AGG language): conservative doubles MIN_MARGIN, recommended keeps it as configured (default), aggressive uses 40% of it.
property_idYesProperty identifier in the reservation data (property_id)
candidate_priceNoCandidate price €/night — compared against the floor price; without it only the floor + guidance is shown

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully explains the algorithm: floor price computation from median cost rows, adjustable margin via risk preset, comparison with candidate price, and the verdict. It also mentions behavior for already-booked dates and confirms no state changes. No contradictions.

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 coherent paragraph, front-loaded with purpose, then explaining the algorithm and verdict. Every sentence adds necessary information, with no redundancy or fluff.

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?

Given no output schema, the description adequately explains return values: floor clearance, net after turnover costs, and booking info if applicable. All four parameters are covered, and the tool's behavior is fully described for its complexity.

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?

All parameters are described in the schema (100% coverage). The description adds behavioral meaning: how candidate_price is optional and used, how risk preset adjusts margin, and the role of property_id and date in computing floor price. This adds value beyond schema definitions.

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's purpose: checking whether filling a single gap night is worth it, with a specific verb ('Checks') and resource ('gap night'). It distinguishes from sibling tools by focusing on a single night assessment rather than portfolio analysis or strategy proposals.

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 when to use (when deciding about a gap night) and notes it is read-only, but does not explicitly state when not to use or compare with sibling tools like propose_decisions or apply_decision. The usage context is implied rather than prescribed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

margin_copilotRank where money moves and weigh the options (read-only)A

Margin Copilot: reads the same figures as propose_decisions, groups the gap nights priced below your cost floor into per-property money-moves, ranks them by below-floor exposure (biggest first), and weighs the options for each — Hold, Guard the floor (recommended), and where it applies, raise the minimum stay — with one marked recommended. The only euro figures are computed (below-floor exposure, floor levels); it does NOT invent a '30-day net' or option deltas that would require guessing fill probability, and it never claims an unsold night as a gain. Read-only — it never writes prices or state. Staging a recommended move routes to propose_decisions → apply_decision, where every write is previewed and needs an explicit confirm. Requires WHEELHOUSE_API_KEY (uses live price recommendations).

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest night to scan, YYYY-MM-DD. Optional — defaults to the next 30 days.
fromNoEarliest night to scan, YYYY-MM-DD. Optional — defaults to the next 30 days (the horizon Wheelhouse price recommendations cover).
riskNoRisk preset for the cost floor (margin multiplier). Defaults to 'recommended'. Same presets as propose_decisions.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully discloses behavior: it is read-only (never writes prices or state), does not invent figures like a '30-day net', and requires an API key. It also clarifies what the tool does not do (claim unsold night as gain). This level of detail exceeds requirements.

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?

The description is well-structured and front-loaded, but somewhat verbose. Every sentence adds value, but the paragraph could be slightly more concise. Nonetheless, it is clear and organized.

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?

Given no output schema, the description sufficiently explains what the tool returns (ranked list, options with recommended one). It also covers the workflow context (staging moves leads to propose_decisions/apply_decision). The parameter count is low and all are optional, so completeness is high.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with descriptions for each parameter. The description adds additional context: defaults for from/to (next 30 days), and risk presets are same as propose_decisions. This adds value beyond 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 the tool reads figures, groups gap nights, ranks by below-floor exposure, and weighs options (Hold, Guard floor, raise minimum stay). It explicitly distinguishes itself from propose_decisions by noting that it reads the same figures but does not write, and that staging a move routes to propose_decisions. The verb 'reads' and resource 'margin copilot' are specific, and sibling differentiation is clear.

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?

The description provides explicit when-to-use guidance: it is read-only and should be used to inspect margin opportunities. It also tells the agent when not to use it (for actual writes, use propose_decisions → apply_decision) and how to route actions. It mentions the requirement for WHEELHOUSE_API_KEY. This is complete usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_decisionsPropose pricing decisions (gap night floors)A

Proposes concrete pricing decisions in euros: finds upcoming gap nights where the current price recommendation is below your cost floor (turnover + travel + MIN_MARGIN, adjustable with the risk preset) and proposes fixing those nights at the floor so they can't sell below cost. Proposals are saved to the local decision log (NM_STATE_DIR, default ~/.night-margin). Window defaults to the next 30 days. Proposing never changes prices — prices change only when a decision is applied with apply_decision and explicit confirmation.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoWindow end (exclusive), YYYY-MM-DD (optional — defaults to 30 days from the start)
fromNoWindow start, YYYY-MM-DD (optional — defaults to today; decisions apply to future nights)
riskNoRisk preset for the gap-night floor's minimum margin (Wheelhouse's own CON/REC/AGG language): conservative doubles MIN_MARGIN, recommended keeps it as configured (default), aggressive uses 40% of it.

TDQS

A4.4/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 burden of behavioral disclosure. It explains that proposals are saved to a local decision log, never change prices, and that the risk preset affects the minimum margin. It does not detail authentication or error handling, but covers the core behavior well.

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?

The description is a single paragraph of around 100 words, front-loaded with the main purpose. It is concise, but could be slightly more structured with bullet points or separate sentences for each detail. Still, it is well within acceptable length.

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?

Given 3 optional parameters, no output schema, and no annotations, the description is complete. It covers the tool's operation (finds gap nights, proposes fixes), defaults (window, risk), and side effects (saves to log, no price changes). No important aspects are missing.

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 100%, so baseline is 3. The description adds value by explaining default values for 'from' and 'to' (today and 30 days) and the meaning of the 'risk' enum (conservative doubles MIN_MARGIN, recommended keeps it, aggressive uses 40%). This goes beyond the schema's brief descriptions.

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's purpose: proposing pricing decisions for gap nights by identifying those below cost floor and suggesting fixes. It uses specific verb+resource ('propose decisions') and distinguishes itself from sibling tools like apply_decision by clarifying that proposals do not change prices.

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 explains when to use the tool (for gap nights below cost floor) and contrasts it with apply_decision, which actually applies changes. It mentions defaults (30-day window) and adjustable risk presets but does not explicitly list all alternative tools or specify when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

revert_decisionRevert an applied pricing decisionA

Reverts an applied pricing decision: deletes the custom rates it wrote in Wheelhouse and restores any prior custom rates from the snapshot taken before the write. This tool DOES change prices — but only with explicit confirm=true; without it you get a preview. Requires WHEELHOUSE_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNoMust be true to actually delete the written rates — without it you get a preview
decision_idYesDecision id to revert, e.g. "d2"

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries full burden. It discloses that the tool changes prices (only with confirm), deletes custom rates, and restores prior rates from snapshot. It also mentions the API key requirement. No contradictions.

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 sentences long, with no wasted words. Each sentence serves a purpose: stating core action and highlighting the confirm parameter and authentication requirement.

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?

Lacks description of the return value, which is important for understanding what the preview or result looks like. As a mutation tool with no output schema, the description should cover this but does not.

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 100%, and both parameters are well-described in the schema. The description adds minimal value: it clarifies that confirm must be true to actually delete and gives an example decision_id. This meets the baseline for high schema coverage.

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 reverts an applied pricing decision, specifying the actions: deletes custom rates and restores prior rates. It distinguishes from sibling tools like 'apply_decision' by focusing on the reversal operation.

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 provides clear context: requires explicit confirm=true to execute, otherwise returns a preview. It also mentions the need for WHEELHOUSE_API_KEY. However, it does not specify when NOT to use the tool or list alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

review_historyReview your own past months (net of estimated turnover cost)A

Season review: mirrors your OWN past monthly Wheelhouse KPIs back at you — per month, your revenue, an ESTIMATED turnover cost, estimated net, and what fraction of gross the cleaning ate (turnover share), plus occupancy and ADR. Turnover cost is estimated from monthly averages (occupied nights ÷ average length of stay × AVG_TURNOVER_COST), not measured per booking, and is labeled as an estimate. It describes what already happened over your real history; it does NOT forecast, does NOT recommend or rank strategies, and does NOT say what you 'should have' done or what another strategy 'would have' earned. Window defaults to all available history (usually only a handful of months per listing — it states the real span, never 'last year' or '5 years' unless the data actually covers it). Read-only — never changes any prices and never writes any state. Requires WHEELHOUSE_API_KEY.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest month to include, YYYY-MM-DD — matched at MONTH granularity and INCLUSIVE. Optional — defaults to all available history.
fromNoEarliest month to include, YYYY-MM-DD — matched at MONTH granularity and INCLUSIVE (any day in the month includes that whole month). Optional — defaults to all available history.
avg_turnover_costNoOverride AVG_TURNOVER_COST for this run: € per turnover. Used to ESTIMATE turnover cost from monthly averages (occupied nights ÷ avg length of stay × this number).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries full burden. It declares read-only nature, no state changes, estimation methodology for turnover cost, that estimates are not measured per booking, and that window defaults to available history (no fabricated spans). Comprehensive.

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?

The description is well-structured and front-loaded with purpose. Every sentence adds value, though there is slight redundancy (estimation mentioned twice). Efficient overall.

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?

Without output schema, the description explains return values (revenue, turnover cost, net, turnover share, occupancy, ADR). It also covers derivation limitations, defaults, and read-only behavior. Thorough for a 3-param tool.

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 100%, so baseline is 3. The description adds value by explaining default behavior (optional, defaults to all history) and the purpose of avg_turnover_cost override and its estimation formula. This extra context justifies a 4.

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 mirrors your own past monthly KPIs (revenue, estimated turnover cost, net, turnover share, occupancy, ADR). It distinguishes from siblings like analyze_portfolio or compare_strategies by focusing on personal history review.

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?

Explicitly says when to use: to review past history. Also clearly states what it does NOT do: forecast, recommend, rank strategies, or suggest alternatives. Provides clear context on default window behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_targetSet a monthly gross revenue targetA

Sets a monthly gross revenue target for a property (saved locally to NM_STATE_DIR, default ~/.night-margin). Shows the month's booked gross so far when it can be computed. analyze_portfolio then reports progress toward any targets whose month overlaps the analysis window.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthYesTarget month, YYYY-MM
property_idYesProperty identifier as it appears in analyze_portfolio (property_id)
gross_targetYesGross revenue target for the month, €

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries burden. Mentions local persistence to NM_STATE_DIR and that it shows current booked gross when possible. Lacks details on overwrite behavior, error cases, or idempotency.

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 concise sentences, front-loaded with primary action, no wasted words.

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?

Covers purpose and persistence sufficiently for a simple tool, but lacks mention of error conditions, validation, or return behavior. Could be more complete given no output schema.

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 100% with descriptions in schema. The description adds context about local storage and integration with analyze_portfolio but does not elaborate on parameter meanings beyond 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?

Clearly states it sets a monthly gross revenue target for a property, with specific verb and resource. Distinguishes from sibling analyze_portfolio which reports progress.

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?

Implicitly guides usage by mentioning analyze_portfolio reports progress, implying this tool is used to set targets before analysis. Does not explicitly list when-not-to-use or alternatives, but context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.3/5.0
Disambiguation5/5

Every tool has a clearly distinct purpose: analysis, target setting, alerts, history review, strategy comparison, gap evaluation, proposal creation, application, reversion, and a copilot for recommendations. Despite some conceptual overlap (e.g., gap_night_check and propose_decisions both deal with gap nights), their scope and output are well-differentiated.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (e.g., analyze_portfolio, set_target, check_alerts). However, 'margin_copilot' deviates as a noun phrase, breaking the pattern slightly. The rest are uniformly snake_case with a clear verb.

Tool Count5/5

With 10 tools, the set is well-scoped for the domain of short-term rental pricing management. Each tool contributes a specific, necessary function without redundancy, making the API lean yet comprehensive.

Completeness4/5

The tools cover the full price decision workflow: analysis, proposal, application, reversion, and monitoring. Missing are operational tools like notification configuration or historical alert logs, but these are secondary. The core lifecycle is complete, with safety features (dry runs, snapshots) included.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server designed to automate tender and RFQ pricing by extracting requirements from documents and building structured pricing models. It enables users to calculate final costs, compare market rates, and generate styled HTML pricing reports for PDF export.
  • F
    license
    A
    quality
    C
    maintenance
    MCP server for the Rizerve direct booking platform. Enables managing properties, bookings, availability, iCal sync, analytics, and webhooks through AI assistants.
    19
    1
  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for reading, aggregating, suggesting, and applying price rules (floors) from ActiveView with a confirmation flow, designed for AI agents to analyze and adjust monetization.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mikki321/night-margin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server