New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

@triplebooks/mcp

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@triplebooks/mcp

TripleBooks MCP server — connect Claude Desktop, Cursor, and other MCP clients to your books via the workspace API.

latest
Source
npmnpm
Version
0.1.1
Version published
Weekly downloads
38
-82.65%
Maintainers
1
Weekly downloads
 
Created
Source

@triplebooks/mcp

Stdio Model Context Protocol server that proxies tool calls to the workspace JSON API with Authorization: Bearer ak_… and x-entity-id. No tenant DB or Cortex logic lives here—only HTTP.

Quick start (users)

After this package is published to npm, use Settings → MCP or:

{
  "mcpServers": {
    "triplebooks": {
      "command": "npx",
      "args": ["-y", "@triplebooks/mcp@latest"],
      "env": {
        "AXIOMATIC_BASE_URL": "https://app.triplebooks.com",
        "AXIOMATIC_API_KEY": "ak_…",
        "AXIOMATIC_ENTITY_ID": "…"
      }
    }
  }
}

Quick start (developers)

  • Copy .env.example to .env.local and set AXIOMATIC_BASE_URL, AXIOMATIC_API_KEY, AXIOMATIC_ENTITY_ID.

  • Run the workspace yourself when needed (local pnpm dev:web, or pnpm dev:workspace:prod-env from repo root for production-backed env on http://localhost:3010). There is no Cursor sessionStart auto-start of the web server — if an old local .cursor/hooks.json still calls ensure-workspace-dev-server.sh, delete that hook (the script was removed).

  • From this directory:

    pnpm mcp-doctor
    pnpm build
    
  • Point Cursor / Claude Desktop at dist/cli.js (local mode) or use npx after publish. In-app: Settings → MCP.

Tool UX: installToolUx adds human titles (e.g. Ledger: List journal) and MCP annotations (readOnlyHint, destructiveHint, openWorldHint) on every tool. After pulling, pnpm build here and fully quit Claude so stdio reloads.

Publish to npm

cd apps/mcp
pnpm pack:npm
npm publish --access public

Requires npm auth for the @triplebooks scope. build:cli bundles workspace code (including @triplebooks/crypto sanitization) into dist/cli.js so the published tarball only depends on @modelcontextprotocol/sdk and zod. Bump version in package.json (and matching server.json) before each publish — npm will reject a republish of the same version. mcpName must stay com.triplebooks/mcp.

Official MCP Registry

server.json is the listing. Domain proof is the public key at https://triplebooks.com/.well-known/mcp-registry-auth (and a matching apex TXT). After npm has the new version:

brew install mcp-publisher
cd apps/mcp
mcp-publisher validate
PRIVATE_KEY="$(openssl pkey -in ~/.ssh/mcp-registry-key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n')"
mcp-publisher login dns --domain triplebooks.com --private-key "${PRIVATE_KEY}"
mcp-publisher publish

Verify: curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=com.triplebooks/mcp"

Production usage (HTTP tool path)

What “production” means for MCP: the workspace process behind AXIOMATIC_BASE_URL resolves real control-plane and tenant data, and your key is a real ak_… with correct RBAC scopes. That is true when:

  • AXIOMATIC_BASE_URL is your deployed app origin, or
  • AXIOMATIC_BASE_URL is localhost while the workspace runs with prod-backed env (pnpm dev:workspace:prod-env).

Both are valid; only the network hop to Next changes.

Entity alignment: API keys are pinned to one entity. AXIOMATIC_ENTITY_ID must match that key; withTenant rejects mismatches.

Scopes: Create keys from the workspace (Ledger API keys UI or /api/ledger/api-keys). Use least privilege—e.g. read:ledger for ledger/cap-table/entity_get; read:settings for entity_list_addresses; write:settings for entity_upsert_address and entity_update_profile (NAICS/tax ID); read:crm for CRM reads; write:crm for crm_update_company, crm_create_*, crm_advance_lead_stage, etc.; read:sales / write:sales for quotes/orders/deal pricing and fundraising_create_pipeline_entry; read:admin for parties_list / parties_get; write:admin for parties_create; read:sales for fundraising_get_investor; add read:invoicing / write:invoicing for invoice automation (including projects_invoice_milestone); read:inventory / write:inventory for catalog SKUs; read:projects / write:projects for client projects and internal Backlog. The API key owner’s RBAC still applies on every route.

Common URL / env mistakes

  • AXIOMATIC_BASE_URL doesn’t match where Next is listening (wrong host/port after a port change).
  • Production ak_ key against a dev workspace that points at a different tenant DB than you expect—or the reverse—so entity UUIDs don’t exist.
  • AXIOMATIC_ENTITY_ID doesn’t match the entity the key was issued for (middleware returns 403).
  • 402 = tenant credits exhausted, not a “wrong URL” (but looks like random API failure if you don’t check body).

Credits: API-key requests debit api_calls per hit. Tenant balance 0 returns 402 (credits_exhausted). Top up tenant credits in-app if tools suddenly fail.

Secrets: Never commit .env.local. Prefer separate keys for read-only vs automation that can write.

Directory (entity, CRM, parties)

ToolPurpose
entity_getActive entity profile (read:ledger)
entity_update_profileSet NAICS / tax ID (EIN, encrypted) / industry / jurisdiction (write:settings, OWNER/ADMIN)
entity_list_addressesEntity HQ / registered / mailing addresses (read:settings)
entity_upsert_addressCreate/update entity self-address (write:settings, OWNER/ADMIN)
crm_list_companiesPaginated companies (read:crm)
crm_get_companyCompany + counterparty detail
crm_create_companyCreate company (write:crm)
crm_update_companyPatch company; metadata.billingTenantId for credits grant mapping (write:crm)
crm_list_company_addressesAddresses for a company
crm_upsert_company_addressCreate/update company address (write:crm)
crm_list_contactsPeople; optional companyId filter
crm_get_contactContact detail
crm_create_contactCreate contact (write:crm)
crm_update_contactPatch contact (write:crm)
crm_list_leadsLeads/opportunities
crm_get_leadSingle lead detail
crm_list_pipeline_stagesPipeline stages + lead counts
crm_create_pipeline_stageAdd open stage (write:crm, crm.pipeline.manage)
crm_update_pipeline_stageRename/restyle stage (write:crm, crm.pipeline.manage)
crm_delete_pipeline_stageDelete open stage; optional lead reassignment (write:crm)
crm_reorder_pipeline_stagesReorder stage columns (write:crm)
crm_create_leadCreate lead (write:crm)
crm_update_leadPatch lead fields (write:crm)
crm_advance_lead_stageMove lead stage; won automation (write:crm)
crm_batch_update_companiesUniform patch many companies (write:crm)
crm_archive_companySet company status inactive (write:crm)
crm_delete_companyPermanent company delete (write:crm)
crm_search_prospecting_placesGoogle Maps Discover search (read:crm)
crm_get_prospecting_placePlace details by id (read:crm)
crm_import_prospect_from_placeImport place → prospect company (write:crm)
crm_discover_company_contactsWebsite contact/email discovery (write:crm)
crm_enrich_company_from_websiteWebsite crawl + apply proposals (write:crm)
crm_start_succession_scanQueue batch succession scan (write:admin + crm.leads.edit)
crm_get_succession_scan_runScan run progress + proposals (read:admin)
crm_list_outbound_email_connectionsGmail/Resend connections for CRM drafts (read:crm)
crm_create_email_draftCreate CRM email draft only (Gmail Drafts + outbound_messages); optional attachmentDocumentIds (write:crm)
crm_send_email_draftSend an approved draft by outboundMessageId (write:crm)
email_list_outbound_draftsList open outbound drafts / scheduled sends (email.draft)
email_discard_outbound_draftCancel a draft so it leaves Email → Drafts (email.draft)
parties_listLegal parties search (read:admin, governance.view)
parties_getParty detail (seats, holders, links)
parties_createCreate or dedupe legal party (write:admin, governance.manage)
fundraising_get_investorInvestor profile + pipeline (read:sales, fundraising.view)
fundraising_create_pipeline_entryAdd prospect to a round pipeline (write:sales, fundraising.pipeline.manage)
fundraising_list_pipeline_stagesRound pipeline stages + entry counts (read:sales)
fundraising_create_pipeline_stageAdd open stage; optional insertAfterStageId (write:sales, fundraising.pipeline.manage)
fundraising_update_pipeline_stageRename/restyle stage (write:sales)
fundraising_delete_pipeline_stageDelete open stage; optional entry reassignment (write:sales)
fundraising_reorder_pipeline_stagesReorder all stage columns for a round (write:sales)
fundraising_list_data_roomsList investor data rooms; optional roundId (read:sales)
fundraising_get_data_roomOne data room including requireNda (read:sales)
fundraising_create_data_roomCreate data room for a round (write:sales, fundraising.data_room.manage)
fundraising_update_data_roomPatch requireNda / expiry / NDA template (write:sales, fundraising.data_room.manage)

Documents & RAG

ToolPurpose
documents_list_foldersFolder tree (read:documents)
documents_listList docs; filter folderId or linkableType+linkableId (e.g. counterparty)
documents_get_textFull text / PDF extract / OCR for one document
documents_list_revisionsRevision history (number, source, label, author) for editable docs
documents_get_revisionOne revision: metadata, text body, derived PDFs linked to that revision
documents_get_derivationPDF lineage → source document + revision (pass child PDF id)
documents_create_revision_checkpointNamed version checkpoint without changing live file (write:documents)
documents_update_revision_labelRename/clear revision label (write:documents)
documents_restore_revisionRestore prior revision as live doc (write:documents)
documents_update_contentReplace text body; prior version auto-snapshotted (write:documents)
documents_update_metadataRename or retag any file — PDF, PNG, MP4, etc. (write:documents)
documents_upload_fileCreate a document from a local path on the MCP host (write:documents)
documents_replace_fileReplace binary bytes from a local path on the MCP host (write:documents)
documents_save_html_pdfServer-side HTML → PDF save/replace in folder (write:documents)
documents_list_signature_requestsList e-sign envelopes; optional status filter (read:documents)
documents_get_signature_requestDetail + signers + placed field overlays / fieldCount (read:documents)
documents_create_signature_requestCreate draft (or send: true); reuses fielded draft for same PDF (write:documents, documents.sign)
documents_send_signature_requestSend draft invitations (write:documents, documents.sign)
documents_cancel_signature_requestCancel envelope (write:documents, documents.sign)
documents_remind_signature_requestReminder emails to pending signers (write:documents, documents.sign)
data_room_syncLocal export-pdfs.sh + data room upload scripts (requires pandoc + Chrome)
kb_retrieve_contextSemantic RAG (documents + optional kb_page scope); read:documents
kb_list_spacesList KB spaces (read:kb)
kb_list_pagesPages in a space (read:kb)
kb_create_spaceCreate KB space (write:kb)
kb_create_pageCreate KB page with markdown (write:kb)
kb_update_pagePatch page body / publish (write:kb)
kb_search_lexicalFull-text search KB titles (read:kb)

Add read:documents to your API key. After upload, OCR + embedding index runs via the document pipeline/cron — then RAG returns chunks.

Invoicing & printable HTML

MCP tools (requires scopes on the key + RBAC on the key owner):

ToolPurpose
invoicing_list_invoicesPaginated invoice list (GET /api/invoicing/invoices — invoicing.view or ledger.view on owner)
invoicing_get_invoiceFull invoice JSON (GET /api/invoicing/invoices/:id — invoicing.view on key owner)
invoicing_create_invoiceCreate DRAFT invoice (POST /api/invoicing/invoices — write:invoicing, ledger.post)
invoicing_update_invoiceUpdate DRAFT invoice lines/metadata (PATCH without action)
invoicing_invoice_actionsend / void / unvoid / record_payment / mark_paid / void_payment
invoicing_void_paymentVoid one payment (reverse payment/deposit JEs; reopen invoice to SENT when unpaid)
invoicing_backfill_line_catalogAttach catalog SKU snapshots to existing lines (PAID ok) without changing amounts
invoicing_invoice_print_metaPrint / template metadata without full HTML: printPath, default vs invoicing.print template, MIME OK for merge, totals, line sample
invoicing_invoice_send_readinessSend pre-flight: customer billing email, Gmail/Resend connections, HTML_TO_PDF_ENABLED, blockers/warnings, suggested billing period
invoicing_send_invoiceEmail invoice PDF (same as Invoicing → Send): posts AR, marks SENT. Optional to / deliveryMemo; defaults connection + billing period from readiness. dryRun: true previews without emailing
invoicing_list_outbound_email_connectionsActive outbound email connections (connectionId + channel for send)
invoicing_list_print_templatesRows with category invoicing.print (linked document for HTML merge) — needs read:documents
invoicing_ar_subledger_gridAR subledger vs GL (moduleKey=ar slice of subledger grid); optional onlyDrift

Add read:invoicing / write:invoicing to your API key for invoice automation.

Sales — quotes, orders, deal pricing

ToolPurpose
sales_list_quotesPaginated quotes — read:sales
sales_get_quoteQuote + lines + linked Order Form hint
sales_update_quotePatch quote; lines on draft with milestone_service — write:sales
sales_propose_quote_milestones_from_documentPropose milestone rows from OF/SOW (no write) — write:sales
sales_convert_quote_to_orderQuote → draft order (full line copy) — write:sales
sales_list_orders / sales_get_orderOrder list + detail — read:sales
sales_update_orderConfirm order (spawn project), finalize one-time invoice — write:sales

Catalog / inventory

ToolPurpose
catalog_searchLine-picker search (GET /api/inventory/catalog) — read:inventory
inventory_list_itemsPaginated item list (GET /api/inventory?view=items)
inventory_get_itemSingle item detail
inventory_create_itemCreate SKU (POST /api/inventory create-item) — write:inventory
inventory_update_itemUpdate SKU (PUT /api/inventory)

Expense reports

ToolPurpose
expenses_list_reportsPaginated reports; filter status=draft, search q by report number — read:expenses
expenses_get_reportOne report with lines — read:expenses
expenses_create_reportCreate draft with optional lines — write:expenses, expenses.submit
expenses_delete_reportDelete draft report and lines — write:expenses (draft only)

Client projects / service jobs

ToolPurpose
projects_listList client jobs/projects (GET /api/projects/services) — read:projects
projects_getJob detail with lines/milestones
projects_get_financeWIP, recognized revenue, billable milestones + invoiceId
projects_invoice_milestoneDRAFT AR invoice for one milestone (idempotent) — write:invoicing
projects_createCreate client project — write:projects
projects_updatePatch job status, notes, dates

Internal Backlog uses work_* tools (same projects API scope; UI routes are /backlog).

ToolPurpose
work_list_projectsList Backlog teams/projects — read:projects
work_create_itemCreate issue; optional sprintId, priority, assignToMe / assigneeId — write:projects
work_update_itemPatch issue; prefer ref=PLATFORM-123; taskId alias for id — write:projects
work_plan_sprintBulk-assign task UUIDs into a sprint (preferred over per-issue patches)
team_list_membersEntity members + currentUserId for assignee pickers — read:settings

Period close (checklists + soft/hard close)

ToolPurpose
ledger_close_calendarTemplates / checklists / checklist-items (+ system checks) — read:ledger
ledger_close_dashboardFocus period, checklist progress, blockers — read:ledger
ledger_generate_close_checklistSpawn checklist for a period — write:ledger + ledger.close
ledger_update_close_checklist_itemStatus / assignee / notes on one item — write:ledger + ledger.close
ledger_update_close_checklistChecklist IN_PROGRESS / COMPLETED — write:ledger + ledger.close
ledger_close_periodSOFT_CLOSE / HARD_CLOSE — write:ledger + ledger.close
ledger_reopen_periodReopen soft/hard-closed period — write:ledger + ledger.close

Shipped on main in eebd227d. Cursor loads tsx src/index.ts; after a pull that adds tools, run Developer: Reload Window or the IDE keeps a stale tool list.

Audit chain (tamper-evident log)

ToolPurpose
ledger_audit_chain_summaryEntry counts, head/genesis hashes, needsBackfill
ledger_audit_chain_verifyFull SHA-256 chain recompute — valid, brokenAt
ledger_audit_chain_inspectDiagnose break: stored vs recomputed hashes, breakReason, duplicate sequences
ledger_query_audit_trailPaginated human-readable rows (no hash fields)

Requires read:ledger scope and key owner admin.view RBAC (same as /accounting/audit-verify UI).

Verification

pnpm mcp-doctor

Loads .env.local, validates env, GETs /api/ledger/subledgers?action=specs, lists period-close tool names, and checks GET /api/ledger/close-dashboard.

Extra smoke checks (cap-table summary; 403 is OK if the key lacks cap_table.view):

pnpm mcp-doctor -- --smoke

Spot-check tools you rely on (same URL + headers as MCP): cap table summary, trial balance, etc.

Cursor

Repo .cursor/mcp.json runs tsx src/index.ts with envFile → platform/apps/mcp/.env.local.

Composer agent server id is often user-triplebooks or project-0-triplebooks-triplebooks (not the bare key triplebooks); see workspace Cursor rules.

Missing tools after git pull? Doctor passing only proves the API is reachable. Cursor caches the MCP tool list until Command Palette → Developer: Reload Window (or toggle the server off/on). Claude Desktop users who run node dist/index.js must also pnpm build in apps/mcp after tool registration changes.

Second MCP server (another entity)

Copy .env.example to platform/apps/mcp/.env.harvest-blade.local (gitignored) with a separate ak_… key and that entity's AXIOMATIC_ENTITY_ID. The repo registers server triplebooks-hb in .cursor/mcp.json (short id — Cursor limits combined server+tool name length). Reload Cursor after editing; agent server id becomes user-triplebooks-hb or project-0-triplebooks-triplebooks-hb.

CapSign Inc. (separate tenant): .env.capsign.local + server triplebooks-capsign. Verify: pnpm mcp-doctor:capsign. Agent id: user-triplebooks-capsign or project-0-triplebooks-triplebooks-capsign.

Import / QuickBooks inspection

ToolPurpose
ledger_list_import_batchesBatch list with counts and match status
ledger_get_import_batchRows in one batch
ledger_staged_import_breakdownGroup by source_format + status; pass importMethod: QUICKBOOKS
ledger_save_match_patternSave bank-feed match_patterns rule from a NEEDS_REVIEW row; optional reapply to siblings
ledger_list_match_patternsList all Rules (match_patterns) for the entity
ledger_upsert_match_patternCreate or update a rule by counterpartyPattern
ledger_update_match_patternPatch one rule by id
ledger_delete_match_patternDelete one rule by id
ledger_get_settingsRead Autopilot mode, confidence threshold, require AI approval (read:ledger)
ledger_update_settingsPatch Autopilot / controls (write:ledger, ledger.edit)
integrations_list_connectionsQBO/Plaid connection + last sync error
integrations_get_sync_logsPer-connection sync history
ledger_migration_sourcesMigration wizard connected sources

Requires read:ledger on the API key.

Claude Desktop

Recommended (after npm publish):

{
  "mcpServers": {
    "triplebooks": {
      "command": "npx",
      "args": ["-y", "@triplebooks/mcp@latest"],
      "env": {
        "AXIOMATIC_BASE_URL": "https://app.triplebooks.com",
        "AXIOMATIC_API_KEY": "ak_…",
        "AXIOMATIC_ENTITY_ID": "…"
      }
    }
  }
}

Local checkout (after pnpm build):

{
  "mcpServers": {
    "triplebooks": {
      "command": "node",
      "args": ["/ABS/PATH/platform/apps/mcp/dist/cli.js"],
      "env": {
        "AXIOMATIC_BASE_URL": "http://localhost:3010",
        "AXIOMATIC_API_KEY": "ak_…",
        "AXIOMATIC_ENTITY_ID": "…"
      }
    }
  }
}

During development you can use pnpm exec tsx src/index.ts with the same env map.

CI

pnpm build at the repo root runs Turbo build, which includes @triplebooks/mcp (tsc + bundled dist/cli.js). The GitHub Actions TypeScript workflow runs that full build so MCP must compile on every PR.

Remote / hosted MCP (next stage)

Claude Desktop and Cursor default to local stdio (spawn process). Hosting MCP over HTTP/SSE for claude.ai requires remote MCP + OAuth — Stage 3.

Scripts

ScriptPurpose
pnpm buildtsc + bundled dist/cli.js
pnpm pack:npmBuild and create an npm tarball for inspection
pnpm mcp-doctorEnv + subledger specs + close-dashboard API + period-close tool name list
pnpm mcp-doctor -- --smokeAbove + optional cap-table summary + audit chain verify
pnpm startnode dist/cli.js (stdio server)

See src/index.ts header comment for full context.

Keywords

mcp

FAQs

Package last updated on 11 Sep 2026

Related posts