Tools reference
The MCP server advertises 19 tools: 12 read and 7 write. The canonical surface comes from the platform's tool registry; this page mirrors it. Where the rendered text disagrees with what the live server reports from tools/list, the live server is authoritative.
Every tool runs inside the authenticated user's withSession transaction. Row-level security gates visibility identically to the web app — a tool sees what the user could already see from app.evenhandhq.com.
Three concepts recur in the descriptions below:
feature_not_available— the tool's backing build step has not shipped to production. The tool is advertised bytools/listso clients can discover the full surface area, but every call returns{ "error": "feature_not_available", "message": "..." }until the corresponding platform build step lands.- Write tools — must additionally pass the per-tool grant and (where applicable) the per-deal opt-in. See Write gating.
deal_id— a UUID identifying a deal the caller participates in. Calls naming a deal the caller cannot see return an empty result; calls naming a non-existent deal are indistinguishable from that case by design.
Read tools
evenhand_deals_list
List deals visible to the caller. Filters by state and brokerage_id.
{
"state": "string, optional, 1–32 chars",
"brokerage_id": "string, optional, 1–128 chars"
}
Returns { deals: Deal[] }. Each deal carries id, title, state, organization_id, exclusive_buyer_user_id, exclusivity_granted_at, exclusivity_expires_at, closed_at, created_at, updated_at, and a synthesized caller_role of broker_assigned, exclusive_buyer, participant, or viewer. Capped at 200 rows. RLS limits the result to deals the caller can read on the web app.
evenhand_deals_get
Fetch a single deal with its participants. RLS-bounded — non-participants get null.
{
"deal_id": "uuid, required"
}
Returns { deal: Deal | null, participants: Participant[] }. A null deal means either the deal does not exist or the caller is not on its participant list. Each participant row carries user_id, role, status.
evenhand_qoe_get
Per-category QoE progress (status, last update). Returns the deal's QoE checklist progress and most-recent accounting snapshot summary.
{
"deal_id": "uuid, required",
"category": "string, optional, 1–64 chars"
}
Returns { progress: ProgressRow[], recent_accounting_snapshots: SnapshotRow[] }. Progress rows carry id, status, completed_at, category, title; the snapshot list is the five most-recent accounting snapshots with id, snapshot_type, status, requested_at, completed_at. RLS restricts both to deals the caller participates in.
evenhand_qoe_pl_periods
P&L period rows from the accounting snapshot pipeline. Filterable by date range.
{
"deal_id": "uuid, required",
"start_date": "string (ISO date), optional",
"end_date": "string (ISO date), optional"
}
Returns { periods: PlPeriodRow[] } drawn from every accounting snapshot on the deal. Capped at 500 rows, ordered by period_start_date descending. Empty when the deal has no accounting snapshots.
evenhand_qoe_customer_concentration
Top-N customer concentration metrics derived from the accounting snapshot's customer-revenue periods.
{
"deal_id": "uuid, required",
"as_of_period": "string (ISO date), optional"
}
Returns { customers: CustomerRevenueRow[] } from the most-recent accounting snapshot, ordered by revenue total descending and capped at 50 rows. Empty when the deal has no accounting snapshots.
evenhand_findings_list
List diligence findings on a deal across all categories.
{
"deal_id": "uuid, required",
"category": "string, optional",
"severity": "enum: critical | major | minor | informational, optional",
"status": "enum: open | mitigated | accepted | resolved, optional"
}
Returns feature_not_available until Phase 2C Build Step 53 ships. Advertised in tools/list so clients can discover the surface ahead of the rollout.
evenhand_findings_get
Fetch a single finding by id.
{
"finding_id": "uuid, required"
}
Returns feature_not_available until Phase 2C Build Step 53 ships.
evenhand_questions_list
List deal Q&A visible to the caller.
{
"deal_id": "uuid, required",
"status": "string, optional, 1–64 chars"
}
Returns { questions: Question[] }. Each row carries id, category, status, asked_at, question_text, distributed_response. Capped at 200 rows, ordered by asked_at descending. RLS limits results to questions the caller may see — typically the caller's own questions as a buyer, or all questions on a deal as a broker.
evenhand_documents_list
List documents accessible to the caller — filename and metadata only. Document bodies are never returned via MCP.
{
"deal_id": "uuid, required",
"category": "string, optional, 1–64 chars",
"confidentiality_level": "enum: public | nda_gated | selected_buyer_only, optional"
}
Returns { documents: DocumentMetadata[] }. Each row carries id, filename, confidentiality, size_bytes, an upload or creation timestamp, and a source field of simple or production indicating which document table the row came from. Capped at 200 rows per source.
evenhand_offers_list
List buyer offers visible to the caller on a deal — the caller's own offers as a buyer, or every buyer's offer as a broker or seller.
{
"deal_id": "uuid, required"
}
Returns { offers: Offer[] }. Each row carries id, buyer_user_id, revision_number, is_current, submitted_at, payload. Capped at 50 rows, ordered by submitted_at descending. The payload shape is documented in the platform's offer schema.
evenhand_financing_stack_get
List the caller's financing sources on a deal.
{
"deal_id": "uuid, required"
}
Returns feature_not_available until Phase 2C Build Step 54 ships.
evenhand_closing_conditions_list
List closing conditions visible to the caller on a deal.
{
"deal_id": "uuid, required"
}
Returns { closing_conditions: ClosingCondition[] }. Each row carries id, name, status, owner_user_id, deadline, completed_at. Capped at 100 rows, ordered by created_at descending.
Write tools
Every write tool below additionally requires the mcp:write scope, an active per-tool grant, and (for deal-scoped tools) an active per-deal opt-in. See Write gating.
evenhand_findings_create
Create a finding on a deal.
{
"deal_id": "uuid, required",
"category": "string, required, 1–64 chars",
"title": "string, required, 1–120 chars",
"description": "string, optional, ≤ 8000 chars",
"severity": "enum: critical | major | minor | informational, required",
"owner_user_id": "string, optional"
}
Returns feature_not_available until Phase 2C Build Step 53 ships.
evenhand_findings_update_status
Update a finding's status.
{
"finding_id": "uuid, required",
"status": "enum: open | mitigated | accepted | resolved, required",
"status_notes": "string, optional, ≤ 8000 chars"
}
Returns feature_not_available until Phase 2C Build Step 53 ships.
evenhand_findings_comment
Add a comment to a finding's thread.
{
"finding_id": "uuid, required",
"body": "string, required, 1–8000 chars"
}
Returns feature_not_available until Phase 2C Build Step 53 ships.
evenhand_questions_create
Submit a buyer Q&A question. Requires an active NDA on the deal; broker review-required state is the default.
{
"deal_id": "uuid, required",
"category": "enum, required (see the live tools/list response for the full set of Q&A categories)",
"question_text": "string, required, 1–4000 chars"
}
Returns { id: "uuid" } on success — the new deal_questions.id, which is then in status = pending_broker_review per the standard Q&A flow.
A submission that the database rejects (no active NDA on the deal, no broker review path configured, etc.) returns a structured { "error": "submission_rejected", "message": "..." } rather than throwing. The web app's Q&A submission flow handles the same case identically.
evenhand_qoe_normalization_create
Record a financial normalization adjustment on a deal's QoE workspace.
{
"deal_id": "uuid, required",
"period_label": "string, required, 1–64 chars",
"adjustment_category": "enum: owner_comp | related_party | one_time | other, required",
"adjustment_amount": "string, required, 1–40 chars (decimal as string)",
"rationale": "string, optional, ≤ 2000 chars"
}
Returns { id: "uuid" } on success. If RLS rejects the insert — the caller is not authorized for this deal's QoE workspace — the tool returns { "error": "rls_denied", "message": "..." }.
The amount is passed as a string to preserve decimal precision end to end; the platform stores it as a numeric column.
evenhand_financing_source_create
Add a financing source to a deal's stack.
{
"deal_id": "uuid, required",
"source_type": "enum: sba_7a | sba_504 | conventional_senior_debt | mezzanine | seller_note | rollover_equity | cash_buyer_equity | equity_investor_check | earnout_credit | other, required",
"source_name": "string, required, 1–256 chars",
"commitment_amount": "integer, required, ≥ 0",
"commitment_status": "enum: identified | applied | term_sheet | committed | funded | expired | withdrawn, optional"
}
Returns feature_not_available until Phase 2C Build Step 54 ships.
evenhand_financing_source_update_status
Update commitment status on a financing source.
{
"source_id": "uuid, required",
"commitment_status": "enum: identified | applied | term_sheet | committed | funded | expired | withdrawn, required"
}
Returns feature_not_available until Phase 2C Build Step 54 ships.