booklint
Checks an agent's trades, spend, bookings and offers against its owner's limits. Facts, not advice.
我该使用它吗
质量与安全性
基于对工具定义和协议合规性的自动分析。
上下文开销
这是每次将服务器的工具加载到模型上下文窗口时所消耗的大致 token 数。数值越高,可用于其他任务的注意力就越少。
安装
一键安装
将以下内容添加到你的 `claude_desktop_config.json` 文件中:
{
"mcpServers": {
"desk": {
"url": "https://booklint.com/mcp"
}
}
}远程端点
https://booklint.com/mcpstreamable-http它能做什么
工具清单
工具(7)
🟢get_sample(name)
Returns a public sample, the same as GET /v1/sample. Start with name "booking" (sample 3, a hotel offer): passed to check_book as sample="booking", it returns real STOP results against the limits its owner wrote. "subscription" (sample 4, a subscription checkout) is the other Fine-Print Check request: an offer, limits, as_of and page text. name "trading" (the default) is sample 1, a trading agent's book (snapshot, rulebook, broker, journal), stamped now. name "spend" is sample 2, a purchasing and booking agent's actions and the limits its owner wrote. Edit it and pass it to check_book.
输入模式
{
"type": "object",
"properties": {
"name": {
"type": "string",
"enum": [
"trading",
"spend",
"booking",
"subscription"
],
"description": "trading (default, sample 1), spend (sample 2), booking (sample 3) or subscription (sample 4)."
}
},
"additionalProperties": false
}🟢check_book(snapshot, rulebook, broker, journal, actions, ...)
Deterministic rule checks of any agent's actions against the limits its owner wrote, the same as POST /v1/check. Send a trading book (snapshot and rulebook, optionally broker and journal) or an actions list with limits (per-transaction and daily spend caps, merchant allow and deny lists, refundability), or, BEFORE booking or subscribing, one offer with limits (Fine-Print Check: total price cap, mandatory fees over the headline price, refundability, free-cancellation window, auto-renewal, renewal price, trial length, and an optional page_text consistency scan; each rule answers MATCH, WARN, STOP or NOT_CHECKED with the figure found). Send plain text you already have. Do not send a URL; booklint will not fetch one. Returns verdict (FLAGGED, CLEAN, NOT_VERIFIED, REFUSED), coverage and flags. Each rule reports passed, failed or not checked; missing data is not checked, never assumed, and a result with zero flags is not a pass. Pass sample=true (sample 1, trading), sample="spend" (sample 2, purchasing and booking), sample="booking" (sample 3) or sample="subscription" (sample 4) with no key, never counted against the free caps, to see a full result. Without api_key the keyless free plan and its daily cap apply. Not advice; nothing is executed.
输入模式
{
"type": "object",
"properties": {
"snapshot": {
"type": "object",
"description": "The book: positions, cash, as_of (ISO 8601)."
},
"rulebook": {
"type": "object",
"description": "The agent's own rules."
},
"broker": {
"type": "object",
"description": "Optional broker export (desk checks)."
},
"journal": {
"type": "object",
"description": "Optional journal of claims (desk checks)."
},
"actions": {
"type": "array",
"description": "An agent's actions: each {id, time (ISO 8601; days are UTC), amount, currency, merchant, refundable, kind}. Send with limits."
},
"limits": {
"type": "object",
"description": "The owner's limits: a rulebook (version, declared, rules)."
},
"offer": {
"type": "object",
"description": "One offer, as structured fields your agent extracted: merchant, currency, headline_price, line_items [{label, amount, mandatory}], refund {refundable, free_cancel_until}, subscription {auto_renews, renewal_price, renewal_interval, trial_ends}. Send with limits."
},
"as_of": {
"type": "string",
"description": "The current UTC time (ISO 8601). Time rules use it; the server clock is never used."
},
"page_text": {
"type": "string",
"description": "Optional plain text copied from the offer page, at most 64 KB. Scanned for amounts and refund or renewal phrases. Send plain text you already have. Do not send a URL; booklint will not fetch one."
},
"sample": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "string",
"enum": [
"spend",
"booking",
"subscription"
]
}
],
"description": "true runs sample 1 (trading); \"spend\", \"booking\" or \"subscription\" runs sample 2, 3 or 4 instead."
},
"api_key": {
"type": "string",
"description": "Optional key (vdk_...). Same as the Bearer header."
}
},
"additionalProperties": false
}🟢check_invoice(expected_currency, lines, options, api_key)
Send invoice or expense lines as JSON; returns flags for duplicate IDs, repeat vendor+amount+date, missing fields and currency mismatch. Math only. Process-and-discard: nothing is stored or logged after the run. A request containing a Luhn-valid card number or a valid IBAN is refused before accept with reason sensitive_data_refused (not counted as a check). Free plan: runs under the shared free check cap. Desk: volume use. Top-level verdict is CLEAN, FLAGGED or NOT_VERIFIED.
输入模式
{
"type": "object",
"properties": {
"expected_currency": {
"type": "string",
"description": "The header currency all lines should use (e.g. GBP)."
},
"lines": {
"type": "array",
"description": "Invoice or expense lines. Each line needs id, vendor, date, amount and currency.",
"items": {
"type": "object"
}
},
"options": {
"type": "object",
"description": "Optional. round_number_note (bool, default true): informational note for amounts >= 1,000 that are exact multiples of 1,000.",
"properties": {
"round_number_note": {
"type": "boolean"
}
},
"additionalProperties": false
},
"api_key": {
"type": "string",
"description": "Optional key (vdk_...). Same as the Bearer header."
}
},
"required": [
"expected_currency",
"lines"
],
"additionalProperties": false
}🟢check_quote_math(lines, currency, subtotal, discount, total, ...)
Send quote or pricing sheet lines as JSON; returns flags for mismatched line totals, wrong discount amounts, subtotal and grand-total errors, and tier range conflicts (overlap and gap). Math only. Process-and-discard: nothing is stored or logged after the run. A request containing a Luhn-valid card number or a valid IBAN is refused before accept with reason sensitive_data_refused (not counted as a check). Free plan: runs under the shared free check cap. Desk: volume use. Top-level verdict is CLEAN, FLAGGED or NOT_VERIFIED.
输入模式
{
"type": "object",
"properties": {
"lines": {
"type": "array",
"description": "Quote lines. Each line should have line_id, qty, unit_price, and line_total.",
"items": {
"type": "object"
}
},
"currency": {
"type": "string",
"description": "Optional currency code (e.g. GBP). Carried through but not used in arithmetic checks."
},
"subtotal": {
"type": "number",
"description": "Optional stated subtotal; checked against sum of line totals."
},
"discount": {
"type": "object",
"description": "Optional discount block: rate_pct (number, 0-100), base (string label, e.g. 'subtotal'), amount (number).",
"properties": {
"rate_pct": {
"type": "number"
},
"base": {
"type": "string"
},
"amount": {
"type": "number"
}
},
"required": [
"rate_pct",
"base",
"amount"
],
"additionalProperties": false
},
"total": {
"type": "number",
"description": "Optional stated total after discount; checked against subtotal minus discount."
},
"tiers": {
"type": "array",
"description": "Optional quantity tiers. Each tier needs min_qty (int), max_qty (int or null), unit_price (number). Checked for overlaps and gaps.",
"items": {
"type": "object"
}
},
"api_key": {
"type": "string",
"description": "Optional key (vdk_...). Same as the Bearer header."
}
},
"required": [
"lines"
],
"additionalProperties": false
}🟢check_budget_variance(lines, currency, period, thresholds, api_key)
Send budget and actual lines as JSON; returns MATCH/WARN/STOP per line (default 5%/20%, overridable per request, thresholds always echoed), ranked overruns (largest % overrun first). Overall = worst line status. Math only. Process-and-discard: nothing is stored or logged after the run. A request containing a Luhn-valid card number or a valid IBAN is refused before accept with reason sensitive_data_refused (not counted as a check). Free plan: runs under the shared free check cap. Desk: volume use. Top-level verdict is CLEAN, FLAGGED or NOT_VERIFIED. Per-line and overall status stay MATCH, WARN or STOP; those are not the top-level verdict.
输入模式
{
"type": "object",
"properties": {
"lines": {
"type": "array",
"description": "Budget vs actual lines. Each line needs line_id (string), budget (number) and actual (number). A line with budget 0 is reported as NOT_CHECKED (not a flag) and makes coverage incomplete.",
"items": {
"type": "object"
}
},
"currency": {
"type": "string",
"description": "Optional currency code (e.g. GBP). Carried through but not used in checks."
},
"period": {
"type": "string",
"description": "Optional period label (e.g. 2026-09). Carried through but not validated."
},
"thresholds": {
"type": "object",
"description": "Optional threshold overrides. match_max_pct (default 5): overspend % at or below this is MATCH. warn_max_pct (default 20): overspend % above match_max_pct and at or below this is WARN; above is STOP. Both must be non-negative and warn_max_pct >= match_max_pct.",
"properties": {
"match_max_pct": {
"type": "number"
},
"warn_max_pct": {
"type": "number"
}
},
"required": [
"match_max_pct",
"warn_max_pct"
],
"additionalProperties": false
},
"api_key": {
"type": "string",
"description": "Optional key (vdk_...). Same as the Bearer header."
}
},
"required": [
"lines"
],
"additionalProperties": false
}🟢check_accounts_tieout(periods, api_key)
Send one or more balance-sheet periods as JSON; checks that assets equal liabilities plus equity (tolerance 0.01), that any stated subtotals sum correctly, that net income less dividends agrees with the change in retained earnings (tolerance ±1, per terms), and that consecutive periods (when start/end dates are supplied) have no gaps or overlaps. Process-and-discard: nothing is stored or logged after the run. A request containing a Luhn-valid card number or a valid IBAN is refused before accept with reason sensitive_data_refused (not counted as a check). Free plan: runs under the shared free check cap. Desk: volume use. Top-level verdict is CLEAN, FLAGGED or NOT_VERIFIED. NOT_VERIFIED when tieout fields are absent for any period or fewer than two periods carry parseable dates (period_sequence NOT_CHECKED).
输入模式
{
"type": "object",
"properties": {
"periods": {
"type": "array",
"description": "List of balance-sheet periods. Each period requires: period_id (string), total_assets (number), total_liabilities (number), total_equity (number). Optional per period: start and end (ISO date YYYY-MM-DD, for gap/overlap check), subtotals (array of {label, items: [number, ...], stated}), net_income (number), dividends (number, default 0), retained_earnings_open (number), retained_earnings_close (number). net_income_tieout runs only when net_income, retained_earnings_open and retained_earnings_close are all supplied.",
"items": {
"type": "object"
}
},
"api_key": {
"type": "string",
"description": "Optional key (vdk_...). Same as the Bearer header."
}
},
"required": [
"periods"
],
"additionalProperties": false
}🟡get_free_key(label)
Returns a free key at once, the same as POST /v1/keys {"plan": "free"}: no card, no e-mail, and the same daily limits on new keys per client and across the service. The key is shown once in this result and is not stored or logged; pass it as api_key to check_book. A free key runs more own checks a day than the keyless plan; the result lists its limits. Optional label: 1 to 40 letters, digits, '.', '_' or '-'.
输入模式
{
"type": "object",
"properties": {
"label": {
"type": "string",
"description": "Optional label for your own records (1-40 of A-Z a-z 0-9 . _ -)."
}
},
"additionalProperties": false
}社区
证据