Claude Desktop
Settings → Connectors → Add custom connector. Paste the URL.
https://mcp.usetenon.com Tenon exposes 452 tools over the Model Context Protocol — 193 reads, 259 writes — covering projects, estimates, tasks, RFIs, schedule, timesheets, procurement, permits, contacts, communications, handbook, and more. Works with Claude Desktop, Claude Code, Cursor, ChatGPT, or any MCP-compatible client.
Any client that speaks the Model Context Protocol works. Tested with Claude Desktop, Claude Code, Cursor, and ChatGPT Custom GPT Actions. See the per-client recipes below.
Point your client at https://mcp.usetenon.com.
The server speaks Streamable HTTP and advertises its tool
catalog over tools/list on connect.
OAuth 2.1 with Google sign-in or email + password — the same auth as app.usetenon.com. The client redirects you through the consent screen on first connect.
Approve the scopes the client requests. Read-only is the default; write tools (clock-in, create-task, line-item mutations, etc.) need the matching write scope.
Settings → Connectors → Add custom connector. Paste the URL.
https://mcp.usetenon.com Run from any terminal:
claude mcp add tenon https://mcp.usetenon.com Settings → MCP Servers → Add. Paste the URL.
https://mcp.usetenon.com Use as a Custom GPT Action or via the Responses API tool.
https://mcp.usetenon.com
Some clients (notably the claude.ai connector flow) can't send
custom auth headers — for those, generate a long-lived MCP API
key and pass it as the api_key argument on
tool calls.
KEYS ARE SCOPED TO YOUR USER · KEY-LEVEL REVOCATION ONLY · WRITES OBEY YOUR RBAC ROLE
MCP tools respect the connected user's role. Admins get write tools; members get the read-only subset. Every tool call — read or write — is logged with the calling user, tool name, arguments, and outcome. Review activity under Settings → API Keys → Activity.
Every tool is tenant-scoped to the calling user's company and obeys their RBAC role. Writes are audit-logged. Most tools accept either a public UUID or a numeric internal id where an id is required.
Discover, update, and drill into projects. Accepts UUID or numeric project id throughout.
| Tool | Kind | Description |
|---|---|---|
| list_projects | read | List the caller's projects, optionally filtered by status. Returns id, name, status, address, and last activity timestamp. |
| get_project | read | Fetch full details for a single project — name, status, address, contract type, and timestamps. |
| update_project | write | Partial patch of a project — name, status, address, notes. Audit-logged. |
| get_project_schedule | read | Return tasks on a project's schedule, optionally filtered to a date range. |
| create_project | write | Create a new project (name, address, status, client). Returns the new project id and public UUID. |
| create_project_from_template | write | Instantiate a new project pre-populated with phases and tasks from a saved template. |
| save_project_as_template | write | Snapshot an existing project's phases and tasks into a reusable template. |
| copy_project | write | Clone a project's structure (phases, tasks, team) into a new project. |
| create_project_template | write | Create a reusable project template from scratch or from an existing project. |
| get_project_templates | read | List available project templates for the company. |
| fire_project_event | write | Trigger a workflow event on a project (e.g. kick off onboarding sequence). |
| get_project_overview | read | Single-call discovery: returns the project header, all phases (with per-phase task counts and completion), key financial totals, and recent activity. Use instead of chaining list → get calls. |
| delete_project | write | Soft-delete a project (sets deleted_at). Requires confirm=true. Tenant-scoped. |
Read and manage the project schedule — phases, task list, Gantt, finish schedule, and overdue tasks.
| Tool | Kind | Description |
|---|---|---|
| get_schedule | read | Return the full schedule for a project including phase groupings. |
| get_gantt | read | Fetch Gantt-format task data with start/end dates and dependencies. |
| get_phases | read | List phases for a project, optionally including task counts. |
| create_phase | write | Add a new phase to a project schedule. |
| update_phase | write | Rename, reorder, or reassign a phase. |
| get_finish_schedule | read | Return the finish schedule — rooms/areas with expected completion dates. |
| get_overdue_tasks | read | List tasks past their due date, optionally scoped to a project. |
| archive_phase | write | Soft-delete a schedule phase (sets deleted_at). Tasks inside are not deleted but become orphaned. Reversible by support. |
| clone_phase | write | Duplicate a phase and all its child tasks into the same project (or a different one). Returns the new phase id. |
| delete_phase | write | Permanently delete a schedule phase. Destructive — prefer archive_phase for routine cleanup. |
| import_phase_with_tasks | write | Atomically import a phase with tasks, materials, and dependency edges in a single transaction. Designed for bulk migrations. |
| shift_phase_dates | write | Shift a phase row AND every child task forward or backward by N days in one atomic operation. working_days_only uses the project's assigned calendar (holidays + exceptions), not just Sat/Sun. |
| auto_arrange_schedule | write | Topologically sort all tasks + phases in a project schedule so dependency arrows flow left-to-right. Snaps task start/end/due dates to the next working day using the project's assigned calendar (holidays, exceptions, custom hours). Returns dates_snapped count. |
| list_calendars | read | List all schedule calendars (workday clocks) for the company — working hours, holidays, and exceptions. |
| get_calendar | read | Get a single schedule calendar by ID including full working_times, non_working_days, and workday_exceptions. |
| create_calendar | write | Create a new schedule calendar with custom working hours. |
| duplicate_calendar | write | Copy an existing calendar to a new one — useful for per-project variants of the default. |
| update_calendar | write | Update a calendar's name, working hours, holidays, or exceptions. Full-replacement patch. |
| add_calendar_holiday | write | Append a holiday (non-working day) to a calendar. Supports annual recurrence. |
| remove_calendar_holiday | write | Remove a holiday from a calendar by date. |
| add_calendar_exception | write | Mark a normally-off day as worked (workday exception). |
| assign_project_calendar | write | Assign a specific schedule calendar to a project. shift_phase_dates will use it for working-day math. |
| create_milestone | write | Create a Gantt milestone on a project. Milestones have a single target_date and no duration. |
| update_milestone | write | Partially update a Gantt milestone — target_date, title, or description. |
| delete_milestone | write | Permanently delete a Gantt milestone. Destructive and irreversible. |
Read, create, and update tasks across the company or a single project. Includes subtasks, materials, attachments, and constraints. Bulk endpoints exist for migration workflows.
| Tool | Kind | Description |
|---|---|---|
| list_tasks | read | List tasks. Cross-project when project_id is omitted; filter by status, assignee, or date range. |
| create_task | write | Create a task. Returns id and a direct web URL. |
| update_task | write | Partial patch — status, assignee, due date, notes, priority. Audit-logged. |
| bulk_create_tasks | write | Create multiple tasks atomically in one batch. All share the same project_id; optional shared phase_id. Faster than N separate create_task calls for migrations. |
| bulk_update_tasks | write | Update multiple tasks atomically. Each update needs only the fields that change; all succeed or none are applied. |
| archive_task | write | Soft-delete a task. Removes it from list_tasks but preserves row + history; reversible by support. Preferred for routine cleanup. |
| delete_task | write | Permanently delete a task. Destructive and irreversible — requires confirm=true. Prefer archive_task for routine cleanup. |
| get_task_subtasks | read | Return the subtask children of a given task. |
| get_task_materials | read | List materials linked to a task. |
| get_task_materials_cost | read | Return the total material cost for a task. |
| add_task_material | write | Add a single material line to a task. Returns the new line item id. |
| bulk_add_task_materials | write | Add multiple material lines to a task in one atomic batch. |
| update_task_material | write | Partially update a task material line. Only provided fields are written. |
| delete_task_material | write | Soft-delete a task material line. Removed from get_task_materials results. |
| list_task_attachments | read | List attachments on a task — id, name, content type, size, URL, uploader, timestamps. Ordered newest first. |
| upload_task_attachment | write | Attach a file to a task by uploading base64 bytes. Backs the task drawer's Attachments section. Returns the new attachment id and URL. |
| link_task_attachment | write | Attach a pre-uploaded file or external URL to a task — no bytes transferred. Use for existing /uploads/* paths. |
| delete_task_attachment | write | Delete a task attachment by id. Removes the row and best-effort deletes the underlying file. |
| create_constraint | write | Record a blocking constraint on a task. |
| get_constraints | read | List open constraints for a project or task. |
| add_task_dependency | write | Add (or upsert) a dependency edge between two tasks — source_task must complete before target_task can start. |
| bulk_add_task_dependencies | write | Add multiple task dependency edges in a single batch. Each edge needs source_task_id and target_task_id. |
| remove_task_dependency | write | Delete a dependency edge by edge id or by (source_task_id, target_task_id) pair. |
| get_task_dependencies | read | List task dependency edges for a project or a single task. Returns source, target, and dependency type. |
| create_shop_task | write | Create a shop-flagged task (is_shop_task=true). Defaults: type='Custom Build', status='Not Started', priority='Normal'. Audit-logged. |
| complete_shop_task | write | Mark a shop task as Completed and set completed_at=now. Audit-logged. |
| generate_task_description | read | Generate a practical 1-3 sentence task description using AI (Claude Haiku). Useful for shop and construction tasks with terse names. |
| create_goal | write | Create a company goal (OKR / rock) with name, priority, status, and optional owner. |
| update_goal | write | Update a goal — name, status, priority, rock_status, owner, or due date. |
| delete_goal | write | Soft-delete a goal (sets deleted_at). |
| create_goal_milestone | write | Create an inline milestone task attached to a goal. |
| update_goal_milestone | write | Update a goal milestone status or sort order. Pass detach=true to unlink from goal. |
Manage the caller's timer and time entries. Start, stop, log retroactive time, and read or approve timesheet records.
| Tool | Kind | Description |
|---|---|---|
| get_active_timer | read | Return the caller's running tracker, if any — project, started_at, paused state, elapsed seconds. |
| clock_in | write | Start a timer. Stops any existing timer first when force=true. |
| clock_out | write | Stop the caller's active timer. Returns the resulting entry. |
| log_time | write | Log a manual (retroactive) entry against a project. Date defaults to today. |
| get_timesheets | read | List timesheet records, optionally filtered by user, project, or date range. |
| approve_timesheet | write | Approve a timesheet entry. Requires manager permission. |
| get_time_entries | read | Return raw time entries with duration, project, and task linkage. |
| recompute_time_entry_costs | write | Recomputes total_cost on all time_entries for a contact using their current labour rate. Run after a rate change. |
Read and create daily logs. Append narrative entries to existing logs without overwriting prior content.
| Tool | Kind | Description |
|---|---|---|
| list_daily_logs | read | List daily logs for a project, defaulting to the last 30 days. |
| get_daily_report | read | Fetch a single daily log report by id — includes all sections. |
| get_daily_reports | read | List multiple daily reports with optional date/project filters. |
| create_daily_log | write | Create a daily log for a project. Defaults log_date to today. |
| add_log_entry | write | Append to work_performed / issues / delays / notes. Concatenates — does not overwrite. |
List, create, update, and answer requests for information. Answering flips status and records the responder.
| Tool | Kind | Description |
|---|---|---|
| list_rfis | read | List RFIs, optionally filtered by project or status. |
| create_rfi | write | Create an RFI on a project. |
| answer_rfi | write | Answer an RFI. Sets status=answered and records the responder. |
| update_rfi | write | Partial patch of an RFI — title, status, priority, assignee. |
Full change order CRUD — create, edit, issue for approval, accept, and update the rich-text composer.
| Tool | Kind | Description |
|---|---|---|
| get_change_orders | read | List change orders, optionally filtered by project or status. |
| draft_change_order | write | Create a new draft change order with line items. |
| create_change_order | write | Create a change order (title, project, amount, status). Returns id and public_id. |
| update_change_order | write | Update title, description, amount, or status of a change order. |
| delete_change_order | write | Delete a draft change order. Blocked if already issued. |
| issue_change_order | write | Issue a draft change order for client approval (status draft → pending_approval). |
| accept_change_order | write | Accept a pending-approval change order. Updates project contract value. |
| update_change_order_composer | write | Update the rich-text composer body, intro/closing text, amount, language, and co_type. |
Full CRUD for decisions, selection items, categories, and options. Record choices, manage the selection board, and surface open decisions.
| Tool | Kind | Description |
|---|---|---|
| get_decisions | read | List decisions, optionally filtered by project or status. |
| create_decision | write | Create a new decision with option list. |
| make_selection | write | Choose an option on a decision. Audit-logged. |
| get_selections | read | Return all selections made on a project. |
| update_decision | write | Patch fields on an existing decision — title, status, required_by, notes. Audit-logged. |
| delete_decision | write | Permanently delete a decision and its options and links. Irreversible — requires confirm=true. |
| add_decision_option | write | Add a product option to an existing decision. Returns the new option id. |
| remove_decision_option | write | Remove a product option from a decision. The option must belong to the given decision. |
| add_option_photo | write | Add a photo URL to a decision option. The first photo is automatically set as primary. |
| update_option_photo | write | Update caption, sort_order, or make a photo the primary for its option. |
| delete_option_photo | write | Soft-delete a photo from a decision option. If the deleted photo was primary, promotes the next photo. |
| reorder_option_photos | write | Reorder photos for a decision option. Pass the photo IDs in the desired display order. |
| create_decision_link | write | Link a decision to an estimate line item, takeoff measurement, or other entity for cross-reference. |
| delete_decision_link | write | Remove a specific link between a decision and an entity. |
| get_decision_links_by_entity | read | Reverse lookup: all decisions linked to a given entity (line_item_id, takeoff_id, etc.). |
| list_rooms | read | List the rooms (decision_folders) for a project — call before create_selection or update_selection to get valid folder_ids. |
| create_selection | write | Create a selection item for a project (flooring choice, fixture type, etc.). |
| update_selection | write | Update a selection item — category, status, allowance, actual cost, or due date. |
| delete_selection | write | Delete a selection item. |
| create_selection_category | write | Create a selection category within a project to group related choices. |
| update_selection_category | write | Update a selection category name, description, allowance, or sort order. |
| delete_selection_category | write | Delete a selection category and all its options. |
| create_selection_option | write | Add a vendor option within a selection category. |
| update_selection_option | write | Update a selection option (vendor, price, SKU, etc.). |
Full estimate surface — list, read, mutate line items, sections, and assemblies. Switch the Working version and export to CSV.
| Tool | Kind | Description |
|---|---|---|
| list_estimates | read | List estimates, optionally filtered by project or status. |
| get_estimate | read | Fetch a single estimate including header, totals, and line items. |
| get_estimate_versions | read | List all versions. The is_working=true row is the one proposals and invoices reference. |
| export_estimate_csv | read | Return a CSV of line items — sort_order, cost_code, description, quantity, unit, unit_cost, markup_pct, builder_cost, total. |
| create_estimate | write | Create a new estimate. Returns id, public_id, and a web URL. |
| update_estimate | write | Partial patch of an estimate's header — title, status, notes, tax_rate. Audit-logged. |
| delete_estimate | write | Permanently delete an estimate and all its line items. Requires confirmed=true when line items exist. |
| save_estimate_version | write | Save a named snapshot of the estimate's current line items as a new version. Does not change which version is working. |
| add_line_item | write | Append a line item. Defaults cost_type='material', quantity=1, unit='ea'. Audit-logged. |
| bulk_add_line_items | write | Insert multiple line items into an estimate in one batch. Faster than N separate add_line_item calls. |
| update_line_item | write | Patch a line item. Audit-logged. |
| delete_line_item | write | Delete a line item. Audit-logged. |
| reorder_line_items | write | Set sort_order for each id in the array. Audit-logged. |
| add_section | write | Add a section header row. |
| add_assembly | write | Add an assembly parent row (children via add_line_item with parent_line_item_id). |
| set_working_version | write | Switch the Working version — proposals/invoices reference this version. |
| trace_line_item_lineage | read | Trace a line item from estimate through change orders to final invoice. |
| get_quick_estimate_settings | read | Return per-category quick-estimate sqft rates and markup percentages. |
| update_quick_estimate_settings | write | Update quick-estimate sqft rates or default markup for a given category. |
| push_estimate_to_qbo | write | Push a Tenon estimate to QuickBooks Online. Idempotent — updates if already pushed. |
| send_estimate | write | Mark an estimate as sent (status='sent', sent_at=now). Audit-logged. |
| convert_estimate_to_budget | write | Aggregate estimate line items into project budget_items by cost code. Requires estimate linked to a project. |
| generate_po_from_estimate | write | Create a draft purchase order from an estimate's line items. Copies all non-section items (or specific line_item_ids) into a new PO. |
| import_estimate_csv | write | Import a CSV into an estimate. mode='replace' clears and reloads; mode='merge' upserts by (cost_code, description); mode='new-version' snapshots first. |
| duplicate_estimate_line_item | write | Duplicate an estimate line item, appending '(Copy)' to its description and placing the copy at end of list. |
| create_tasks_from_estimate | write | Create project tasks from an estimate's labour, subcontractor, and assembly line items. |
| apply_markup_to_estimate | write | Apply the company's default markup rates to all line items in an estimate, grouped by cost_type. |
| save_estimate_as_template | write | Snapshot an estimate's line items into a reusable estimate template. Returns the new template id. |
| create_estimate_revision | write | Save a versioned snapshot of the current estimate state to estimate_history and increment the version counter. |
Full proposal CRUD — create, send, extend validity, accept, and reject. Bid packages and client updates included.
| Tool | Kind | Description |
|---|---|---|
| get_proposals | read | List proposals, optionally filtered by project or status. |
| get_bids | read | List bid packages and responses for a project. |
| get_client_updates | read | Return client-facing updates published on a project. |
| create_bid_request | write | Create a bid request (status=draft). Audit-logged. |
| create_bid_request_from_tracker | write | Create a bid request pre-populated with line items from procurement tracker items. |
| update_bid_request | write | Update a bid request. Only provided fields are written. |
| delete_bid_request | write | Delete a bid request. Blocked if the bid has been sent to subs (status not draft). |
| get_proposal_response_time_stats | read | Proposal response-time KPI: avg_hours, median_hours, p95_hours, and sample_count over a configurable lookback period. |
| create_proposal | write | Create a new proposal for a project. Returns id, proposal_number, and web URL. |
| update_proposal | write | Partially update a proposal header — title, scope, payment terms, validity date, status. |
| delete_proposal | write | Delete a proposal. Only draft proposals can be deleted. |
| send_proposal | write | Mark a proposal as sent (status → sent, sent_at = now). |
| extend_proposal_validity | write | Extend the expiry date of a sent or viewed proposal. |
| accept_proposal | write | Accept a proposal on behalf of the client. Records signature and sets status to accepted. |
| reject_proposal | write | Decline a proposal. Records optional reason and sets status to declined. |
Create, send, and read invoices. AP bills (vendor invoices) are a separate surface within the same group.
| Tool | Kind | Description |
|---|---|---|
| list_invoices | read | List invoices, optionally filtered by project or status. |
| create_invoice | write | Create a new invoice from an estimate or from scratch. |
| send_invoice | write | Send an invoice to the client — triggers email delivery. |
| get_invoice_aging | read | Return AR aging — outstanding invoices bucketed by days overdue. |
| get_bills | read | List AP bills (vendor invoices) for the company or a project. |
| create_bill | write | Record a vendor bill against a project or cost code. |
| mark_invoice_paid | write | Mark an invoice as paid. Updates status to paid and records paid_at. |
| mark_bill_paid | write | Mark a bill as paid. Idempotent — returns the bill state even if already paid. |
| record_partial_payment | write | Record a partial payment against an invoice without marking it fully paid. |
| send_payment_reminder | write | Log a payment reminder for an outstanding invoice and increment the reminder counter. |
| update_bill_due_date | write | Adjust a bill due date (e.g. vendor agreed to extend terms). |
| snooze_bill_reminder | write | Suppress AP action-flag reminders for a bill until a given date. |
| push_invoice_to_qbo | write | Push a Tenon invoice to QuickBooks Online. Idempotent — updates if already pushed. |
| sync_invoice_from_qbo | write | Pull payment status from a QuickBooks Online invoice into Tenon. If balance=0 in QuickBooks Online, marks the Tenon invoice as paid. |
| create_recurring_bill | write | Create a recurring bill template. The scheduler generates real bills automatically on the configured cadence. |
| list_recurring_bills | read | List recurring bill templates for the company. Pass active=true to return only active templates. |
| update_recurring_bill | write | Update a recurring bill template. Only provided fields are changed. |
| pause_recurring_bill | write | Pause a recurring bill (set active=false). The scheduler skips it until resumed. |
| resume_recurring_bill | write | Resume a paused recurring bill (set active=true). |
| migrate_manual_adjustment_to_recurring_bill | write | Convert a dashboard manual adjustment entry into a proper recurring bill template. |
| update_invoice | write | Update an invoice title, status, due date, notes, tax rate, or total. |
Read budgets, forecasts, cost variance, aging, and accounting sync status. Alert rules are writable.
| Tool | Kind | Description |
|---|---|---|
| get_budget | read | Return the budget for a project — phases, cost codes, and actuals. |
| get_budget_forecast | read | Return a forward-looking budget forecast including committed costs. |
| get_cost_variance | read | Return budgeted vs actual cost variance by cost code. |
| get_ap_aging | read | AP aging — outstanding vendor bills bucketed by days overdue. |
| get_budget_alerts | read | List active budget threshold alerts for a project. |
| get_billing_alert_rules | read | Return company-level billing alert rules. |
| update_billing_alert_rule | write | Modify a billing alert threshold or recipients. |
| query_accounting_sync_status | read | Check the last sync state and error log for QuickBooks / accounting integrations. |
| get_project_cost_summary | read | Return rolled-up contract, budget, actual, and committed cost for a project. |
| get_project_financials | read | Full financial breakdown — invoiced, received, outstanding, margin. |
| get_ar_aging_buckets | read | AR aging with invoice rows: current (≤14 days), over_14 (14–30 days), over_30, over_60, over_90 buckets. |
| get_net_position | read | Hero cash-flow summary: confirmed_ar, draft_ar, total_ar, total_ap, net_position, and months_runway. |
| get_monthly_pnl | read | Monthly P&L summary using Tenon billing data for the last N months (default 12). |
| get_project_pnl | read | Per-project P&L: revenue (invoices), AP costs (bills), labour costs (timesheet entries), and margin. |
| get_overhead_breakdown | read | AP/overhead breakdown grouped by vendor for a given period. |
| get_intercompany_receivable | read | Intercompany receivable: invoices issued to projects tagged with an intercompany flag. |
| get_qbo_kpis | read | Return the latest QuickBooks Online KPI snapshot for the company. |
| get_qbo_sync_status | read | Get the last QuickBooks Online sync status for a specific Tenon entity (invoice, bill, estimate). |
| refresh_qbo_kpis | write | Force a fresh QuickBooks Online KPI snapshot by calling the QuickBooks API and storing the result. |
| get_portfolio_kpis | read | Portfolio-level rollup KPIs across all active projects: contract value, invoiced, received, outstanding, and project count. |
| get_portfolio_budget_variance | read | Per-project budget vs. actual variance. Returns contract_value, budget_revenue, invoiced, received, and variance_pct. |
Read and manage company contacts. Add or remove contacts from teams; inspect team memberships.
| Tool | Kind | Description |
|---|---|---|
| get_contacts | read | List contacts, optionally filtered by type or name search. |
| get_contact_profile | read | Fetch full contact details — phone, email, address, linked company. |
| create_contact | write | Create a new contact record. |
| update_contact | write | Partial patch of a contact — name, phone, email, notes. |
| get_contact_teams | read | Return all teams a contact belongs to. |
| add_contact_to_team | write | Add a contact to a team. |
| remove_contact_from_team | write | Remove a contact from a team. |
| get_contact_labour_rate | read | Return the labour rate configuration for a contact (employee): wage, burden_pct, and blended_rate. |
| update_contact_labour_rate | write | Set or update the labour rate for a contact. Provide wage + burden_pct or a flat blended_rate. |
| get_account_memory | read | Fetch the per-client narrative memory for a contact (root by default). Sections: root, properties, services_active, service_history, preferences, relationships, project_history, scratchpad. Memory holds reasoning, not structured data. |
| update_account_memory_section | write | Replace the full content of one section in a contact's account memory. Atomically writes a memory_write feed entry. |
| append_account_memory_note | write | Append a timestamped note to a section in a contact's account memory without overwriting existing content. |
| get_account_memory_feed | read | List entries from a contact's append-only memory feed, newest first. Filterable by entry type and date range. |
| search_account_memory_feed | read | Full-text search over a contact's memory feed. Supports websearch syntax (quoted phrases, OR, -). |
| append_account_memory_feed | write | Write an entry to a contact's memory feed — comm summaries, transcripts, notable actions. Idempotent on source_ref. |
| archive_contact | write | Archive a contact (sets archived_at). Archived contacts are hidden from active lists but preserved for history. |
| merge_contacts | write | Merge one contact into another. All references are re-pointed to the target; source is deleted after merge. |
Read company structure — roles, teams, members, workload, and task-type configuration. Role permissions are writable.
| Tool | Kind | Description |
|---|---|---|
| get_company_roles | read | List all roles defined for the company. |
| get_company_teams | read | List teams, optionally with member counts. |
| get_teams | read | Return team details including members and linked projects. |
| get_tenant_members | read | List all users in the company with their roles and status. |
| update_role_permissions | write | Patch the permissions set for a company role. |
| get_team_workload | read | Return current task load per team member. |
| get_task_type_config | read | Return task type definitions and default workflows. |
| get_role_default_task_type | read | Return the default task type assigned to a role. |
| get_custom_elements | read | List custom fields and form elements defined for the company. |
| create_company_role | write | Create a new company role with an optional permission matrix. Name must be unique within the company. Audit-logged. |
| update_company_role | write | Update a company role — name or description. Supply only the fields to change. Audit-logged. |
| delete_company_role | write | Delete a non-system role. Fails if the role has users assigned or is a system role. Audit-logged. |
| revert_company_role_to_defaults | write | Reset a system role (admin, subcontractor, supplier, client) permissions and notifications to platform defaults. Audit-logged. |
| update_sage_gmail_permission | write | Toggle whether users can grant Sage access to their Gmail. Requires admin/owner role on the MCP key. Audit-logged. |
Read and manage purchase orders, vendor procurement, and material status through the project pipeline.
| Tool | Kind | Description |
|---|---|---|
| get_procurement | read | Return company-wide procurement summary. |
| get_project_procurement | read | Return procurement status for a single project's materials. |
| get_purchase_orders | read | List purchase orders, optionally filtered by project or vendor. |
| create_purchase_order | write | Create a new purchase order against a project. |
| update_po_tracking | write | Update delivery status and tracking info on a PO. |
| get_po_tracking | read | Return tracking details for a purchase order. |
| get_project_materials_pipeline | read | Return material status through the full procurement pipeline for a project. |
| check_material_availability | read | Check on-hand and on-order quantity for a material item. |
| update_material_status | write | Update the status of a material in the procurement pipeline. |
| add_to_procurement_tracker | write | Add a standalone material/service/equipment line to the procurement tracker for a project. |
| update_procurement_tracker_item | write | Update a procurement tracker item — status, vendor, notes, or linked document. |
| remove_from_procurement_tracker | write | Soft-delete a procurement tracker item. Blocked if the item already has a PO number. |
| create_purchase_order_from_tracker | write | Create a purchase order pre-populated from procurement tracker items. Atomically links the PO to each tracker row. |
| update_purchase_order | write | Update a purchase order. Only provided fields are written. Valid status: draft|sent|received|cancelled. |
| delete_purchase_order | write | Delete a purchase order. Blocked if status is not draft (once sent to the vendor). |
| create_subcontract_from_tracker | write | Create a subcontract pre-populated from procurement tracker items and an awarded bid request. |
Read equipment records, assignments, and usage logs. Check availability before scheduling.
| Tool | Kind | Description |
|---|---|---|
| get_equipment | read | List company equipment — name, type, status, and location. |
| get_equipment_assignments | read | Return current and upcoming equipment assignments by project. |
| check_equipment_availability | read | Check whether a piece of equipment is available in a date range. |
| get_equipment_log | read | Return usage history for a piece of equipment. |
| list_equipment | read | List equipment in the company library. Filterable by type (owned|rental|client_owned), category, location, status, and rental vendor. |
| create_equipment | write | Create a new equipment entry in the company library. Accepts equipment_type (owned|rental|client_owned), vendor contact, catalog ref, and rental dates. |
| update_equipment | write | Update fields on an existing equipment entry. Supply only the fields you want to change. |
| assign_equipment_to_task | write | Link a piece of equipment to a task with an optional rental date window. Returns 409 with conflict details if the window overlaps another assignment. |
| remove_equipment_from_task | write | Delete an equipment-task assignment row by id. Scoped to the caller's company. |
| list_equipment_rental_rates | read | List current (non-superseded) rental rates for an equipment item. Returns period (day/week/month), amount, currency, and effective_from. |
| add_equipment_rental_rate | write | Add a new rental rate for an equipment item. If a current rate for the same period already exists, it is superseded (history preserved). |
| list_equipment_rental_rate_history | read | List all rental rates (including superseded/historical) for an equipment item, newest first. |
| create_equipment_rental_event | write | Record a pickup or return event for rental equipment. After creation, attach condition photos via the files endpoint with entity_type=equipment_rental_event. |
| list_equipment_rental_events | read | List pickup and return events for a rental equipment item, newest first. Each event includes attached photo URLs. |
| delete_equipment | write | Permanently delete an equipment record from the company library. Hard delete — no recovery. Audit-logged. |
| assign_equipment | write | Assign a piece of equipment to a project (project-level assignment, distinct from assign_equipment_to_task). Returns assignment_id. Audit-logged. |
| duplicate_equipment | write | Duplicate an equipment record, creating a copy with '(Copy)' appended to the name. The copy starts as 'available' with no project assignment. Audit-logged. |
| return_equipment | write | Return a piece of equipment from its current project — closes the active assignment and sets status to available. Audit-logged. |
| create_equipment_maintenance | write | Log a maintenance record for a piece of equipment. Updates last_maintenance_date. Audit-logged. |
| create_equipment_attachment | write | Link a file (by URL) as an attachment on a piece of equipment. Supports document, image, or video. Audit-logged. |
Manage consumable stock — track quantities, log usage, transfer between locations, and surface low-stock alerts.
| Tool | Kind | Description |
|---|---|---|
| get_consumable_stock | read | Return current on-hand quantity for consumable items. |
| add_consumable_stock | write | Add stock (receiving / purchase). |
| log_consumable_usage | write | Record consumption of a consumable item. |
| get_consumable_usage_history | read | Return usage history for a consumable item. |
| get_low_stock_items | read | Return all consumables currently below their reorder threshold. |
| transfer_consumable_stock | write | Transfer stock between storage locations. |
| get_storage_locations | read | List storage locations and their current inventory. |
Read and manage permits, inspections, compliance records, and insurance tracking.
| Tool | Kind | Description |
|---|---|---|
| get_permits | read | List permits for a project — type, status, authority, expiry. |
| create_permit | write | Create a new permit record on a project. |
| update_permit | write | Patch a permit — status, issued date, expiry, notes. |
| get_inspections | read | List scheduled and completed inspections for a project. |
| get_compliance | read | Return compliance status for the company or a project. |
| get_compliance_expiry | read | Return compliance items expiring within a configurable window. |
| get_company_insurance | read | Return company-level insurance policies and expiry dates. |
| get_project_insurance | read | Return insurance requirements and certificates filed for a project. |
| delete_permit | write | Permanently delete a permit. Cascades to history entries, conditions, and blockers. |
| create_permit_blocker | write | Create a blocker on a permit — an obstacle that must be resolved before the permit can proceed. |
| update_permit_blocker | write | Update a permit blocker — resolve it or change severity. |
| get_permit_blockers | read | List blockers for a permit ordered by most-recently raised. |
| create_permit_condition | write | Add a condition to a permit (state=open). |
| update_permit_condition | write | Update a permit condition state (open|satisfied). |
| get_permit_conditions | read | List conditions attached to a permit. |
| create_permit_history_entry | write | Create a history entry on a permit (always agent_kind=sage for MCP-created entries). |
| get_permit_history | read | List history entries for a permit, most-recent first. |
| get_inspection_flags | read | List inspection flags for an inspection or a project — issues raised during inspection review. |
| parse_permit_email | read | Parse an inbound permit email: extract key facts, dates, and auto-update permit status if confidence is high. |
Read subcontractor records, contracts, confirmations, and signature status.
| Tool | Kind | Description |
|---|---|---|
| get_subcontractors | read | List subcontractors, optionally filtered by trade or project. |
| get_subcontracts | read | List subcontracts — scope, value, and status. |
| get_sub_confirmations | read | Return schedule and scope confirmations from subcontractors. |
| get_subcontract_signature | read | Check e-signature status on a subcontract. |
| create_subcontract | write | Create a subcontract agreement (status=draft). Audit-logged. |
| update_subcontract | write | Update a subcontract. Only provided fields are written. Valid status: draft|issued|signed|active|complete|cancelled. |
| delete_subcontract | write | Delete a subcontract. Blocked if the subcontract is signed or in-progress. |
Access project drawings, uploaded files, and submittal records.
| Tool | Kind | Description |
|---|---|---|
| get_drawings | read | List drawings for a project — sheet number, revision, and URL. |
| get_files | read | List uploaded files attached to a project or entity. |
| get_submittals | read | Return submittal log — item, status, required by date, and reviewer. |
Query spec items, lock approved specs, flag spec-driven change orders, and patch individual items.
| Tool | Kind | Description |
|---|---|---|
| query_spec | read | Full-text search across project specification items. |
| lock_spec_item | write | Lock a spec item once approved — prevents further edits. |
| flag_spec_change_order | write | Flag a spec item as requiring a change order. |
| update_spec_item | write | Patch a spec item — description, section, notes. |
Create, update, and read punch list items. Auto-generate a punch list from open tasks.
| Tool | Kind | Description |
|---|---|---|
| create_punch_list_item | write | Add an item to the punch list. |
| update_punch_list_item | write | Update status, assignee, or notes on a punch list item. |
| get_punch_list_status | read | Return overall punch list completion status for a project. |
| generate_punch_list | write | Auto-generate a punch list from open tasks and outstanding items. |
Full CRUD for company policies and procedures. Apply a procedure directly to a task to attach its checklist.
| Tool | Kind | Description |
|---|---|---|
| list_policies | read | List company policies, optionally filtered by category. |
| get_policy | read | Fetch the full text and metadata of a policy. |
| create_policy | write | Create a new policy document. |
| update_policy | write | Update policy content or metadata. |
| archive_policy | write | Archive a policy — removes from active list without deleting. |
| list_procedures | read | List procedures, optionally filtered by category or status. |
| get_procedure | read | Fetch the full text, steps, and metadata of a procedure. |
| create_procedure | write | Create a new procedure. |
| update_procedure | write | Update procedure content or steps. |
| archive_procedure | write | Archive a procedure. |
| apply_procedure_to_task | write | Attach a procedure's checklist to a task. |
| draft_procedure | write | Research and draft a new procedure from industry best-practices via AI. Saved as unpublished draft for review. |
| draft_policy | write | Research and draft a company-level handbook policy (operations, HR, safety, finance) via AI. Saved as unpublished draft for review. |
Record and track warranty claims, expiry alerts, and maintenance schedules.
| Tool | Kind | Description |
|---|---|---|
| get_warranty_claims | read | List warranty claims for a project or company. |
| create_warranty_claim_internal | write | Create an internal warranty claim record. |
| get_warranty_expiry_alerts | read | Return warranty items expiring within a configurable window. |
| get_maintenance_document | read | Fetch a maintenance schedule document. |
| get_maintenance_items | read | List scheduled maintenance items — frequency, last done, next due. |
Full lead CRUD + intake submissions. Sage can create, update, and convert leads to projects — enabling the complete lead→project pipeline.
| Tool | Kind | Description |
|---|---|---|
| get_leads | read | List leads with status, source, estimated value, and contact. |
| get_lead | read | Fetch a single lead by id — all fields including notes, contact, and pipeline status. |
| create_lead | write | Create a new CRM lead (title, address, status, value, source, contact). Audit-logged. |
| update_lead | write | Partial update of a lead — status, value, notes, assignee, expected close. Auto-creates timeline activity on status change. Audit-logged. |
| delete_lead | write | Permanently delete a lead. Requires confirm=true. Irreversible. Audit-logged. |
| convert_lead_to_project | write | Convert a lead to an active project. Creates the project, links the client, advances lead status to 'project_created'. High-value for Sage pipeline automation. |
| get_intake_form_config | read | Return the intake form field configuration for the company. |
| get_intake_submissions | read | List intake form submissions, optionally filtered by date or status. |
Search the company knowledge base and retrieve articles. The KB backs Sage AI support responses.
| Tool | Kind | Description |
|---|---|---|
| search_kb | read | Full-text search across knowledge base articles. Returns title, snippet, and URL. |
| get_kb_article | read | Fetch the full content of a knowledge base article. |
| get_help_articles | read | List help articles, optionally filtered by category. |
Read and write Slack messages, team chat, call transcripts, voicemails, and communication aggregation config.
| Tool | Kind | Description |
|---|---|---|
| get_slack_messages | read | Return recent Slack messages for a project or channel. |
| search_slack | read | Full-text search across connected Slack workspace messages. |
| get_team_messages | read | Return messages from an internal Tenon team chat thread. |
| get_teamchat_context | read | Return the recent chat context for a project or team. |
| get_calls_with_contact | read | Return call history with a specific contact. |
| summarize_recent_calls | read | Return AI-generated summaries of recent Dialpad calls. |
| get_voicemail_transcripts | read | Return transcribed voicemails for the company. |
| get_comms_aggregation_config | read | Return the communication aggregation config — which channels are piped into Sage. |
| send_chat_message | write | Send a message to a team chat channel. Requires a user-bound MCP key. |
| edit_chat_message | write | Edit a chat message you sent. Only the original sender can edit. |
| delete_chat_message | write | Soft-delete a chat message. Admins can delete any message; others can delete their own. |
| mark_channel_read | write | Mark all messages in a chat channel as read for the current user. |
| react_to_chat_message | write | Add an emoji reaction to a chat message. |
Read shop drawings, rendered designs, and design review comments. Update design status and add comments.
| Tool | Kind | Description |
|---|---|---|
| get_shop_designs | read | List shop designs for a project — title, version, status. |
| get_shop_orders | read | List shop fabrication orders linked to designs. |
| get_shop_renders | read | Return rendered images for a shop design. |
| get_shop_render_annotations | read | Return annotations placed on a shop render. |
| get_shop_design_comments | read | Return review comments on a shop design. |
| add_shop_design_comment | write | Add a review comment to a shop design. |
| update_shop_design_status | write | Update the approval/revision status of a shop design. |
Read client portal status, onboarding progress, and weekly digest.
| Tool | Kind | Description |
|---|---|---|
| get_portal_clients | read | List clients with active portal access. |
| get_portal_token_status | read | Check whether a client portal token is valid and what it grants access to. |
| get_onboarding_status | read | Return onboarding checklist completion for the company. |
| get_weekly_digest | read | Return the weekly AI-generated digest of project activity. |
Full-text search across every document type the company has filed.
| Tool | Kind | Description |
|---|---|---|
| search_documents | read | Full-text search across estimates, proposals, invoices, change orders, and bid requests. Returns relevance-ranked entity_type, id, title, and snippet. |
| search_similar_tasks | read | Find existing tasks semantically similar to a query string using trigram similarity. Used by Sage before creating a new task to surface potential duplicates. Returns ranked matches with a recommendation: modify_existing, ask_user, or create_new. Returns dedup_hit_id when similarity ≥ 0.65 for use with record_dedup_choice. |
| record_dedup_choice | read | Record the chosen action (modify/new/skip) for a task dedup hit returned by search_similar_tasks. Call after the user decides what to do with a matched task. |
Read and generate QR codes linked to project locations, equipment, and entities.
| Tool | Kind | Description |
|---|---|---|
| get_qr_codes | read | List QR codes registered for the company or a project. |
| get_qr_code_url | read | Return the resolved URL and entity for a scanned QR code. |
Company configuration, cost catalogue, jurisdiction fields, and install documentation.
| Tool | Kind | Description |
|---|---|---|
| get_company_jurisdiction_fields | read | Return jurisdiction-specific required fields for the company. |
| get_cost_catalogue_items | read | List cost catalogue items — preset materials, labour rates, and assemblies. |
| get_install_docs | read | Return integration install documentation for a connector. |
| get_company_settings | read | Read the full company settings: branding (primary_color, logo_url), feature flags, and integration config. |
| update_company_settings | write | Update one or more company settings fields. All fields optional; only provided fields are written. |
| get_document_sequences | read | List all document number sequences for the company (invoice numbers, PO numbers, etc.). |
| update_document_sequence | write | Update the number sequence for a given document type — change the prefix or current counter. |
| get_locations | read | List location records (properties, sub-locations, sites, vehicles) — the entity behind QR codes and equipment assignments. |
| create_cost_catalogue_item | write | Create a cost catalogue item. Tenant-scoped, audit-logged. |
| update_cost_catalogue_item | write | Partially update a cost catalogue item. Only provided fields are written. |
| delete_cost_catalogue_item | write | Soft-delete a cost catalogue item (sets is_active=false). Existing estimate lines are unaffected. |
| get_company_memory | read | Fetch the company-wide narrative memory tree (root by default). Sections: root, lessons, process, finance, team, sourcing, pipeline, scratchpad. Memory holds reasoning above the data layer. |
| update_company_memory_section | write | Replace the full content of one company memory section. Atomically writes a memory_write feed entry. |
| append_company_memory_note | write | Append a timestamped note to a company memory section without overwriting existing content. |
| get_company_memory_feed | read | List entries from the company's append-only memory feed, newest first. Filterable by entry type and date range. |
| search_company_memory_feed | read | Full-text search over the company memory feed. Supports websearch syntax (quoted phrases, OR, -). |
| append_company_memory_feed | write | Write an entry to the company memory feed — significant events, transcripts, process notes. Idempotent on source_ref. |
Read and manage the multi-T&C template library. Sage uses these tools to inspect and set default proposal terms.
| Tool | Kind | Description |
|---|---|---|
| list_terms_templates | read | List T&C templates for the company, optionally filtered by document_type (proposal, invoice, change_order, general) or active status. |
| get_terms_template | read | Fetch a single T&C template by id — full content, language, and default/active flags. |
| create_terms_template | write | Create a new T&C template. Setting is_default=true auto-clears the prior default for that document type. |
| update_terms_template | write | Update an existing T&C template — content, name, language, or default/active flags. |
| get_terms_and_conditions | read | Fetch the company's current Terms & Conditions text along with its version label and last-updated timestamp. |
| update_terms_and_conditions | write | Replace the company Terms & Conditions content. Automatically bumps the terms_version counter. |
Persistent narrative memory for both your company and individual contacts. Company memory stores the state-of-business, priorities, and process decisions. Account memory stores per-client relationship summaries, communication style, and deal history. Both support a structured section tree plus an append-only feed for event logging.
| Tool | Kind | Description |
|---|---|---|
| get_company_memory | read | Fetch the company-wide narrative memory tree. Returns root by default; specify additional sections for deeper context. |
| get_company_memory_feed | read | List entries from the company append-only memory feed, newest first. Filterable by event type and date range. |
| search_company_memory_feed | read | Full-text search over the company memory feed payload. |
| update_company_memory_section | write | Replace the full content of one section in the company memory tree. Atomically writes a memory_write feed entry. |
| append_company_memory_note | write | Append a timestamped note to a section in the company memory tree. |
| append_company_memory_feed | write | Write an event entry directly to the company append-only feed (e.g. project closure, team change). |
| get_account_memory | read | Fetch per-client narrative memory for a contact. Returns root (relationship summary, decision-makers) by default. |
| get_account_memory_feed | read | List entries from a contact append-only memory feed, newest first. |
| search_account_memory_feed | read | Full-text search over a contact memory feed payload. |
| update_account_memory_section | write | Replace the full content of one section in a contact account memory. Atomically writes a memory_write feed entry. |
| append_account_memory_note | write | Append a timestamped note to a section in a contact account memory. |
| append_account_memory_feed | write | Write an event entry directly to a contact append-only feed (e.g. service scheduled, call completed). |
Read and manage the user dashboard layout, widget catalog, and finance action flags. Action flags surface overdue invoices, expiring compliance items, and budget alerts.
| Tool | Kind | Description |
|---|---|---|
| get_dashboard_action_flags | read | Priority action items for the Finance Dashboard: AR invoices overdue >14 days, AP bills due, expiring compliance, and budget alerts. |
| dismiss_action_flag | write | Permanently dismiss a dashboard action flag so it no longer appears in get_dashboard_action_flags. |
| snooze_action_flag | write | Snooze a dashboard action flag until a specified timestamp. |
| list_dismissed_action_flags | read | Audit list of action flags that have been dismissed or snoozed, with timestamps. |
| get_user_dashboard_layout | read | Return the caller's primary user dashboard layout — all widget instances with their grid positions and config. |
| update_user_dashboard_layout | write | Replace the full widget layout on a user dashboard atomically. |
| list_available_widget_types | read | Return the catalog of available widget types with their default grid size and required permissions. |
| add_widget_to_dashboard | write | Add a single widget to a user dashboard. If grid position is omitted, appends to the end. |
| remove_widget_from_dashboard | write | Remove a single widget from a dashboard by widget_instance_id. |
| get_dashboard_manual_adjustments | read | Return the company's dashboard manual adjustments — line items that appear in the Finance Dashboard P&L as one-off entries. |
| update_dashboard_manual_adjustments | write | Replace the company's dashboard manual adjustments array atomically. |
| get_dashboard_role_template | read | Return the dashboard role template for a given role_kind (admin only). |
| update_dashboard_role_template | write | Replace the widget layout for a company role template (admin only). |
Read and write the Meadowlark-wide narrative memory tree and activity feed. Holds reasoning above the data layer (priorities, lessons, team dynamics, pipeline narrative) shared across all agents.
| Tool | Kind | Description |
|---|---|---|
| get_company_memory | read | Return one or more sections of the company memory tree (root, lessons, process, finance, team, sourcing, pipeline, scratchpad). Defaults to root. |
| update_company_memory_section | write | Replace the full content of a company memory section. Atomically writes a memory_write feed entry. |
| append_company_memory_note | write | Append a timestamped note to a company memory section without replacing existing content. |
| get_company_memory_feed | read | Return the append-only activity feed for the company. Filterable by entry type and date range. |
| search_company_memory_feed | read | Full-text search across the company activity feed. Returns entries ranked by relevance. |
| append_company_memory_feed | write | Append a custom entry to the company activity feed. Idempotent via optional source_ref. |
Read and write per-client narrative memory for a contact (account). Holds relationship context, preferences, service history, and project narrative — shared across agents working on the same account.
| Tool | Kind | Description |
|---|---|---|
| get_account_memory | read | Return one or more sections of a contact account memory tree (root, properties, services_active, service_history, preferences, relationships, project_history, scratchpad). Defaults to root. |
| update_account_memory_section | write | Replace the full content of an account memory section. Atomically writes a memory_write feed entry. |
| append_account_memory_note | write | Append a timestamped note to an account memory section without replacing existing content. |
| get_account_memory_feed | read | Return the append-only activity feed for a contact account. Filterable by entry type and date range. |
| search_account_memory_feed | read | Full-text search across a contact account activity feed. Returns entries ranked by relevance. |
| append_account_memory_feed | write | Append a custom entry to a contact account activity feed. Idempotent via optional source_ref. |
Cold-start orientation for any agent entering a Tenon project, account, or company context. Returns memory roots, active state, and operating guidance in a single call — replaces three separate memory fetches.
| Tool | Kind | Description |
|---|---|---|
| get_session_briefing | read | Return a compact session briefing: scope metadata (company + optional account/project), memory roots from each layer in scope, active operational state (timer, open RFIs/decisions), and operating guidance on the memory tools. Call once at session start. |
Read and write a per-project narrative memory tree and append-only activity feed. Sage uses project memory for cross-session context; external agents can append notes and query the feed.
| Tool | Kind | Description |
|---|---|---|
| get_project_memory | read | Return one or more sections of a project memory tree (root, contacts, schedule, scope, sourcing, finance, comms, scratchpad). Defaults to root. |
| update_project_memory_section | write | Replace the full content of a project memory section. Each write creates a new feed row so the edit history is preserved. |
| append_project_memory_note | write | Append a note to a project memory section without replacing existing content. |
| get_project_feed | read | Return the append-only activity feed for a project. Filterable by entry type (memory_write, transcript, comm, note) and date range. |
| search_project_feed | read | Full-text search across a project activity feed. Returns entries ranked by relevance. |
| append_project_feed | write | Append a custom entry to a project activity feed. Accepts entry_type, payload, and an optional idempotency source_ref. |
Manage recurring service contracts, property records, and the service offerings catalog. Powers maintenance subscriptions and auto-spawns service tasks per plan.
| Tool | Kind | Description |
|---|---|---|
| list_service_properties | read | List service properties (managed locations) for the company or a specific contact. |
| create_service_property | write | Create a new service property record linked to a client contact. |
| update_service_property | write | Update fields on an existing service property. |
| attach_equipment_to_property | write | Link a piece of equipment to a service property (e.g. HVAC unit at a client site). |
| list_service_offerings | read | List service offerings (SKUs) in the company catalog. |
| create_service_offering | write | Create a new service offering in the catalog with optional default checklist. |
| list_service_plans | read | List service plans (bundled subscription packages) for the company. |
| create_service_plan | write | Create a new service plan bundling one or more offerings at a set price and cadence. |
| list_service_contracts | read | List active and historical service contracts, optionally filtered by contact or property. |
| create_service_contract | write | Create a service contract subscribing a client to a plan. Auto-spawns service tasks for each included offering. |
| cancel_service_contract | write | Cancel an active service contract and record the cancellation reason. |
The MCP surface is a thin wrapper around the Tenon REST API. Anything an MCP tool can do, a Bearer-token HTTP call can do too — same RBAC, same audit log, same response shapes.
https://app.usetenon.com/api/v1 http://localhost:8080/api/v1 Authorization: Bearer <jwt> 1000 req/min per token | Group | Path prefix | Notes |
|---|---|---|
| Auth & Identity | /auth/*, /me/* | Email + password, Google OAuth, refresh, MFA, profile. |
| Projects | /projects | CRUD + status, schedule, members. |
| Tasks | /tasks | CRUD; cross-project filters via query params. |
| Estimates | /estimates | CRUD, line items, sections, assemblies, versions. |
| Proposals | /proposals | Generated from estimates; portal links + status. |
| Invoices | /invoices | Issue, send, mark paid; line items mirror estimate. |
| Change Orders | /change-orders | CRUD + portal acceptance. |
| Bid Requests | /bid-requests | Issue to subs, collect responses. |
| RFIs | /rfis | CRUD + answer flow. |
| Decisions | /decisions | CRUD + make_selection. |
| Daily Logs | /daily-logs | Per-project narratives, append-only entries. |
| Timesheets | /timesheets, /time-entries | Active timer + clock-in/out + retroactive log_time. |
| Documents | /documents/search | Full-text across estimates, proposals, invoices, COs, bids. |
| Handbook | /policies, /procedures | Org-wide policies + procedures library. |
| MCP API Keys | /mcp-api-keys | Self-serve generate + revoke; tied to the caller's user. |
| Audit | /audit | Read every write across the surfaces above. |
Download the live OpenAPI spec — generated from the running server, always in sync with deployed endpoints. Hook it into Postman, Insomnia, openapi-codegen, or any client SDK generator.
Download OpenAPI 3.0 specThe first 30 days are on us. Bring your existing projects, RFIs, and estimates — or start fresh and have your agent stub them out for you.