night-margin-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@night-margin-mcpWhere is my portfolio leaking money?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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-mcpThat'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_decisions → apply_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:
analyze_portfolio— where is the money leaking?Where is my portfolio leaking money?
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?
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?
propose_decisions— which upcoming nights are at risk of selling below cost?Which gap nights are about to sell below my cost floor?
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.Risk presets —
propose_decisionsandgap_night_checkboth take an optionalriskparameter (conservative|recommended|aggressive, defaultrecommended) 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.
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:
propose_decisionsfinds 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 optionalriskpreset — 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.apply_decisionwrites one proposal to Wheelhouse as fixed custom rates — but only with explicitconfirm: 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, sorevert_decisioncan always delete what was written and restore what was there before.set_targetstores a monthly gross revenue target per property;analyze_portfoliothen 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 |
| Send alerts via a Telegram bot (checked first). |
| Send alerts to a generic incoming webhook (Slack-compatible |
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 --watchConfiguration (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-mcpVariable | Default | Description |
| – | Your own Wheelhouse integration key. When set, bookings are fetched from the Wheelhouse RM API; without it, synthetic demo data is used. |
| – | Optional override for the |
|
| Source of turnover costs: |
|
| Manual mode: € per turnover (cleaning). Also serves as the fallback in CSV mode when a booking has no cost row. |
| – | Optional tiering, e.g. |
| – | CSV mode: path to the cost CSV (required when |
| – | CleanHub mode: actual turnover costs from the CleanHub field-operations platform over HTTP (both required when |
|
| Minimum margin € for the gap-night floor: floor = turnover + travel + |
|
| Local state directory for the decision log, monthly targets, and the seen-bookings set (used by |
| – | Optional: send |
| – | Optional: send |
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,falseA 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.csvUsage:
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-mcpCost 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-Keyheader). 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
.envfile 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-mcpExploring 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 4000The 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 nightsAll data shipped with the repo and the package is synthetic — no real customer or property data is included.
Available Tools
10 toolsanalyze_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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Period end (exclusive), YYYY-MM-DD (optional — defaults to last 30 + next 90 days) | |
| from | No | Period start, YYYY-MM-DD (optional — defaults to last 30 + next 90 days) | |
| avg_turnover_cost | No | Override AVG_TURNOVER_COST for this run: € per turnover (manual mode) |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to actually write to Wheelhouse — without it you get a dry-run preview | |
| dry_run | No | Preview the exact payload without writing (default: true unless confirm=true) | |
| decision_id | Yes | Decision id from propose_decisions, e.g. "d2" |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| send | No | Send 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
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Period end (exclusive), YYYY-MM-DD (optional — defaults to last 30 + next 90 days) | |
| from | No | Period start, YYYY-MM-DD (optional — defaults to last 30 + next 90 days) | |
| min_stay | No | Strategy B: minimum stay in nights — bookings shorter than this are dropped (default 3) | |
| uplift_pct | No | Strategy B: price uplift percentage for the remaining bookings (default 10) | |
| discount_pct | No | Strategy A: gap night price discount as a percentage of the property's ADR (default 40) |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Night to check, YYYY-MM-DD | |
| risk | No | Risk 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_id | Yes | Property identifier in the reservation data (property_id) | |
| candidate_price | No | Candidate price €/night — compared against the floor price; without it only the floor + guidance is shown |
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest night to scan, YYYY-MM-DD. Optional — defaults to the next 30 days. | |
| from | No | Earliest night to scan, YYYY-MM-DD. Optional — defaults to the next 30 days (the horizon Wheelhouse price recommendations cover). | |
| risk | No | Risk preset for the cost floor (margin multiplier). Defaults to 'recommended'. Same presets as propose_decisions. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Window end (exclusive), YYYY-MM-DD (optional — defaults to 30 days from the start) | |
| from | No | Window start, YYYY-MM-DD (optional — defaults to today; decisions apply to future nights) | |
| risk | No | Risk 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
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to actually delete the written rates — without it you get a preview | |
| decision_id | Yes | Decision id to revert, e.g. "d2" |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest month to include, YYYY-MM-DD — matched at MONTH granularity and INCLUSIVE. Optional — defaults to all available history. | |
| from | No | Earliest 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_cost | No | Override 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
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Target month, YYYY-MM | |
| property_id | Yes | Property identifier as it appears in analyze_portfolio (property_id) | |
| gross_target | Yes | Gross revenue target for the month, € |
TDQS
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.
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.
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.
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.
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.
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
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.
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.
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.
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
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
MCP server for VC pitch-deck scoring, thesis-fit matching, and deal-flow management.
A hosted MCP server for planning, scheduling, media, analytics, and social publishing.
Hosted MCP server for AWS cloud spend: service breakdowns, anomalies, savings and forecasts.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn 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.
- AlicenseAqualityDmaintenanceAn MCP (Model Context Protocol) server that provides real-time LLM token pricing data for 60+ AI models across 15 providers.6152MIT
- FlicenseAqualityCmaintenanceMCP server for the Rizerve direct booking platform. Enables managing properties, bookings, availability, iCal sync, analytics, and webhooks through AI assistants.191
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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