ledger-mobile (nine4-team/ledger-mobile) is an MCP server listed on the M8ven Trust Index. It scores 8 out of 100, grade F. It declares 90 tools. No publisher has claimed this listing.
Native project, purchasing, inventory, budget, and billing system for an interior-design business
Warning. Serious findings were identified. Review the full report before connecting. Grades reflect the full trust pyramid: code, verification depth, and reputation. New projects cap at C until adoption is earned.
How we verified
Verified is a snapshot. Live keeps it current, and builds your track record.
⚡ Connect GitHub → continuous verification on every pushwhy connect →Who stands behind it
nine4-team
Source: github_repo_search
Claim it to get a verified publisher badge, a free copy of our full audit findings, and direct contact for any high-priority issues we find. Or connect your repo for our deepest verification, Live Monitored: read-only, revoke anytime. What we access →
Install from
The grade above is for the source repository. Registries can serve a different version, so we mark the ones we were not able to read.
These names and descriptions are the publisher's own, read from the source code. We print them as written. Our assessment is the findings above, not this list.
server_info[read-only] Return the MCP server version, feature flags, and deprecations. Call once per session to detect available capabilities.
list_accountsList all accounts the current user has access to. Shows which account is currently active.
switch_accountSwitch to a different account. All subsequent queries will use this account. Use list_accounts to see available accounts.
project_healthComprehensive project health snapshot: budget utilization, item counts by status, items needing attention.
inventory_summaryBusiness inventory overview: total items, value, breakdown by status and vendor.
spending_by_vendorAggregate spending grouped by vendor/source, sorted by total.
budget_variance_reportPer-category over/under budget status for a project.
items_needing_attentionFind items with data quality issues: missing prices, SKUs, names, or with incomplete status.
list_budget_categoriesList all account-level budget categories (presets).
get_project_budget_categoriesList enabled budget categories for a project with allocations and computed spend.
update_project_budget_allocationSet or update the budget amount for a category in a project.
enable_category_for_projectEnable a budget category for a project. Creates the project budget category document.
get_transactions[read-only] Fetch multiple transactions by ID in one round-trip. Returns {found, missing}. Prefer this over looping get_transaction when you have a known list of IDs.
get_items[read-only] Fetch multiple items by ID in one round-trip. Returns {found, missing}. Prefer this over looping get_item when you have a known list of IDs.
get_projects[read-only] Fetch multiple projects by ID in one round-trip. Returns {found, missing}.
reconcile_transaction[read-only] Fetch a transaction, resolve its linked items, and return a reconciliation report: audit variance, missing tax rates, items without prices, and concrete suggested fixes. Use this instead of chaining get_transaction + list item details manually.
create_transaction_with_items[mutating] Atomically create a transaction and its items in a single batched write. Replaces the create_transaction + bulk_create_items chain and rolls back if any step fails. Requires a dated audit note. For receipt reconstruction or quantity expansion, create one document per physical unit and rep…
triage_inbox[read-only] Return incomplete transactions most in need of attention, with suggested next actions. Summary mode. Use this as an entry point for cleanup workflows.
return_items_from_inventory_to_projectsell_items_from_inventory_to_projectsell_items_from_project_to_inventoryreturn_itemssell_items_from_project_to_projectapply_contract_setup[mutating] Apply structured contract details to a project and optionally create a created invoice with invoice-only manual charges. Prefer FeeInstallments for planned fee schedules. This never creates payment transactions.
list_invoices[read-only] List project invoices. Invoices are demands for money, not records of money movement.
get_invoice[read-only] Get a single invoice demand, including its source lines and settlement links.
billable_pool[read-only] Return billable project sources not already claimed by a non-canceled invoice. Includes item lines, non-itemized transaction lines, and fee installment lines.
create_invoice[mutating] Create a created invoice demand. Lines may include item, transaction, feeInstallment, or invoice-only manual charges/credits. This does not create any transaction.
add_invoice_line[mutating] Add one line to a created invoice. Use feeInstallment for planned fees; manual creates an invoice-only charge or credit. This does not create a transaction.
update_invoice_line[mutating] Replace or remove a line on a created invoice. Set remove: true to delete the line. This does not create a transaction.
mark_invoice_sent[mutating] Mark a created invoice as sent and freeze its current lines and total. This is still only a demand for money; it does not create a transaction.
void_invoice[mutating] Cancel an invoice demand. Existing settlement transactions are not deleted.
mark_invoice_collected[mutating] Record collection for an invoice by creating categorized paymentToBusiness transaction(s) linked with settlementInvoiceId, then marking the invoice paid. Use for money actually received from the client.
mark_invoice_lines_collected[mutating] Record real payment event(s) that settle selected invoice lines. Creates categorized paymentToBusiness transaction(s) linked to settlementInvoiceId and settlementInvoiceLineIds.
list_itemsList items by EXACT-match structured filters (projectId, status, budgetCategoryId, etc.). Use projectId='inventory' for business inventory (no project). Supports pagination via offset + limit. Picking between this and search_items: - Exact vendor string → list_items (here). - Partial vendor name, o…
get_itemGet a single item with all details. Includes images[] array — each entry's url is a public HTTPS download URL (Firebase Storage token URL), fetch directly with curl/WebFetch, no auth required.
search_itemsSubstring filter across `name`, `description`, `sku`, `source`, `notes`, and `amount`. Case-insensitive. Picking between this and list_items: - Partial vendor name, or any keyword that might appear in source or notes → search_items (here). - Exact vendor string, or other structured filters (status,…
create_item[mutating] Create a new item. When creating a physical copy from a source item or receipt line, pass the source name exactly, byte-for-byte. Duplicate names are valid; never add unit/copy/duplicate/sequence suffixes unless the user explicitly supplied a distinct name or source evidence distinguishes…
bulk_create_itemsCreate multiple items in one batch. Top-level transactionId and projectId are defaults applied to all items unless overridden per-item. Repeated identical names are explicitly valid. When expanding one source item or receipt line into multiple physical documents, repeat its name exactly for every co…
update_itembulk_update_itemsbulk_update_items_by_iddelete_itemDelete an item and atomically remove it from the parent transaction's itemIds array.
attach_item_image[mutating] Attach an image or file to an item. Uploads an item-owned object plus image thumbnails. Use isPrimary to atomically demote the old primary; use position to insert at a specific array index. The first attachment automatically becomes primary.
set_primary_item_image[mutating, storage-safe] Make one current item image primary. Atomically moves it to images[0], clears every other primary flag, and never copies, moves, or deletes Storage objects.
reorder_item_images[mutating, storage-safe] Atomically reorder an item's complete images array without changing attachment metadata or Storage. orderedImageUrls must exactly match the current set. Omit primaryImageUrl to preserve the existing primary.
detach_item_image[mutating, non-destructive] Remove an attachment reference from an item without deleting or modifying any Firebase Storage object. If the removed image was primary, the next image becomes primary.
delete_item_image[DESTRUCTIVE] Permanently delete an item-owned image and item-owned thumbnails, then remove its Firestore attachment reference. Objects outside accounts/{accountId}/items/{itemId}/ are never deleted; such attachments are detached only and return a warning.
get_item_historyGet chronological movement history for an item, with project and transaction names resolved.
get_project_movementsGet all item movements into or out of a project.
add_project_note[mutating] Add a note to a project. Each note is a separate document in the project's notes subcollection with its own createdAt timestamp — no date prefix needed in the text.
list_project_notesList notes for a project, newest first.
search_project_notesSearch notes within a project by text substring (case-insensitive).
list_projectsList all projects. Returns name, client, notes, archive status, and denormalized budget summary. The notes field may contain client-specific context useful for matching receipts to projects — payment method details (e.g. card last 4 digits), billing address variations, or other identifiers.
get_projectGet a single project with full details including budget summary and an `itemCounts` scope check (total / withImages / withoutImages). The notes field may contain client-specific context useful for matching receipts to projects — payment method details (e.g. card last 4 digits), billing address varia…
get_project_budgetCompute live budget breakdown for a project from transactions. Shows per-category budget vs. spent with variance.
create_project[mutating] Create a new project. Optional `notes` is written as the first entry in the project's notes subcollection.
update_project[mutating] Update project fields. `notes` is optional — if provided, appended to the project's notes subcollection (not replaced). updatedAt records the audit trail; use add_project_note directly if you want to add context without other field changes.
archive_projectArchive or unarchive a project.
list_inventory_purchase_intents[read-only] List inventory resale acquisitions planned for projects, enriched with current project/category names and a derived follow-up state. General inventory without intendedProjectId is excluded by default.
update_inventory_purchase_intent[correction] Set, change, clear, or explicitly resolve the intended project/category on one inventory resale acquisition. This changes planning metadata only; it does not create a sale.
correct_inventory_purchase_to_project_reimbursement[correction] Correct a vendor Purchase mistakenly routed to inventory into a direct project reimbursement. This does not invent an inventory sale. The transaction and its active items move atomically; project price defaults to purchase price. Defaults to dry-run.
list_quick_draft_items[read-only] List item quick drafts from accounts/{accountId}/protoItems. These are photo-first draft captures that are not real items until promoted. Default summaries include direct user-authored notes; read them before inferred metadata or routing markers. Supports exact-match filters and paginati…
get_quick_draft_item[read-only] Get one item quick draft with all details, including direct user-authored notes and photos[]. Notes take precedence over inferred metadata and the isFromInventory routing marker.
search_quick_draft_items[read-only] Search item quick drafts by name, notes, SKU, extracted text, barcodes, and SKU candidates.
audit_legacy_quick_draft_transaction_candidates[read-only] Audit legacy candidateTransactionId metadata. Candidates are never treated as confirmed; use update_quick_draft_item(transactionId: ...) only after human confirmation.
create_quick_draft_item[mutating] Create a photo-first item quick draft. This does not create a real item or touch transactions. Quantity remains draft metadata; if a later workflow expands it into separate physical item documents, every unit must preserve the resolved draft/source name exactly, without generated suffixes…
update_quick_draft_item[mutating] Update quick draft item metadata. Use promote_quick_draft_item when it is ready to become a real item.
delete_quick_draft_item[mutating] Delete one quick draft item document. This does not delete Storage media.
mark_quick_draft_item_in_review[mutating] Mark a quick draft item as in_review.
promote_quick_draft_item[mutating] Promote one quick draft item into a real item, then mark the draft converted. Full-resolution photos are copied and verified in the destination item's Storage namespace, item-owned thumbnails are generated, and draft originals are preserved. The draft primary is used unless primaryImageUr…
describe_schema[read-only] Return enum values, key fields, and business rules for ledger entities. Call this ONCE per session instead of guessing. Omit `entity` for the full manifest.
list_spacesList spaces with item counts. Use projectId='inventory' for business inventory spaces.
get_spaceGet a space with its items and checklist progress.
create_spaceCreate a new space.
update_spaceUpdate space fields.
attach_space_imageAttach an image or file to a space. Uploads to Firebase Storage and appends an AttachmentRef to the space's images array. For images, generates sm (300px) and md (800px) thumbnails. Returned URLs are public HTTPS download URLs (Firebase Storage token URLs) — fetch directly with curl/WebFetch later, …
detach_space_imageRemove an attachment from a space. Deletes the file and its thumbnails from Firebase Storage and removes the AttachmentRef from the space's images array. If the removed image was primary, promotes the next image.
correct_transaction_and_its_items[correction, mutating] Correct one ordinary transaction and every currently attached item as one atomic aggregate. Supports project → Business Inventory, Business Inventory → project, and project → project without creating a Sale, Return, or other financial movement. Preserves transaction/item assoc…
list_transactionsList transactions by EXACT-match structured filters (projectId, type, source, budgetCategoryId, purchasedBy, isComplete, etc.). Supports pagination via offset + limit. Returns formatted amounts. Picking between this and search_transactions: - Exact vendor string, or other structured filters (type, …
get_transactionGet a single transaction with all linked, returned, and sold items resolved. Returns three item arrays: items (currently linked via itemIds), returnedItems (items that LEFT this transaction via return, resolved from lineage edges — still count toward audit total), soldItems (items that LEFT via sale…
search_transactionsSubstring filter across `source`, `type`, `notes`, `purchasedBy`, and `amount`. Case-insensitive. Picking between this and list_transactions: - Partial vendor name, or any keyword that might appear in source or notes → search_transactions (here). - Exact vendor string, or other structured filters (…
create_transaction[mutating] Create a new transaction. Starts with isComplete: false — auto-updates when completeness criteria are met via Cloud Function. NOTES CONVENTION: `notes` is the optional user-facing description of the transaction (what it is, what it covers). Plain prose. The createdAt/createdBy audit trai…
update_transaction[mutating] Update transaction fields. isComplete recomputes automatically via Cloud Function. For a data correction that moves an ordinary transaction to business inventory, pass `projectId: null`; `budgetCategoryId` is cleared automatically, canonical item ownership is removed, and linked project i…
bulk_update_transactionsUpdate a field across multiple transactions matching a filter. Uses Firestore batched writes (max 500 per batch). Returns count of updated documents.
cancel_transactiondelete_transaction[DESTRUCTIVE] Permanently delete one proven, fully superseded transaction. This is not a substitute for a return, reversal, or correction. A non-empty deletion note is required. Start with dryRun: true. Execution default-denies unless the transaction is canceled, budget-neutral, item-free, attachmen…
delete_transactionsattach_transaction_fileAttach an image or PDF to a transaction. Uploads to Firebase Storage and appends an AttachmentRef to the transaction's receipt or other images array. For images, generates sm (300px) and md (800px) thumbnails. Returned URLs are public HTTPS download URLs (Firebase Storage token URLs) — fetch directl…
detach_transaction_fileRemove an attachment (receipt or other image) from a transaction. Deletes the file and its thumbnails from Firebase Storage and removes the AttachmentRef from the Firestore array.
Disclosed vulnerabilities in this server's declared npm dependencies (via OSV). Whether each is reachable depends on the installed versions.
When Vitest UI server is listening, arbitrary file can be read and executed
sharp inherited vulnerabilities in libvips: CVE-2026-33327, CVE-2026-33328, CVE-2026-35590, CVE-2026-35591
sharp: Vulnerabilities in libheif: GHSA-g89c-p67h-r497 and GHSA-2jg2-4ch7-h545
Vitest: Path Traversal / Arbitrary File Read via @vitest/mocker Redirect Mock
FIREBASE_API_KEYFIREBASE_PROJECT_IDFIRESTORE_EMULATOR_HOSTUse the real Firebase project for local MCP work. The repo's .mcp.json should point at the built server and a Firebase Admin service-account key. Do not set for normal MCP development or validation.GOOGLE_APPLICATION_CREDENTIALSAlternative: omit --credentials and set =/path/to/service-account.json in env.GOOGLE_CLIENT_IDLEDGER_ACCOUNT_IDLEDGER_USER_UIDMCP_STATIC_BEAREROAUTH_TOKEN_SECRETIMPORTANT: Always use --update-env-vars (not --set-env-vars). --set-env-vars replaces ALL env vars, which would wipe and invalidate all existing OAuth tokens.PUBLIC_URLPORTTool annotations
2/90 tools have annotations
Add readOnlyHint or destructiveHint annotations to every tool so hosts can warn users before invoking.
All four hints declared on every tool
88/90 tools missing one or more hints — server_info (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint); list_accounts (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint); switch_account (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint), +85 more. OpenAI's directory rejects tools where any of the four hints are missing or non-boolean.
For every tool, set all four hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) to explicit true/false values that match the handler’s actual behaviour.
License file
No license file
Add a LICENSE file (MIT, Apache-2.0, etc.).
No hardcoded API keys
1 live-looking API key in source: 1 Google API key
Move secrets to environment variables (process.env.X) or your secret manager.
Tool test coverage
28/90 tools referenced in tests (31%)
Write tests that reference each tool by name so every tool has at least one test.
Production dependencies are patched
0 critical, 2 high severity in production deps — sharp@0.34.5 (high), sharp@0.34.5 (high)
Run npm audit fix, or upgrade the affected packages to a non-vulnerable version.
Dev dependencies
1 critical/high in dev-only deps (does not ship to users)
Upgrade dev dependencies when convenient.
Claim the listing to review these findings one by one and send us a correction where you disagree, straight to the team. Claiming also means we tell you when the grade moves, and reach you first if we find anything urgent.
[](https://m8ven.ai/mcp/nine4-team/ledger-mobile)?variant=verified from the URL.Vetting this one by hand? Tool Check is an MCP that scores other MCPs. Add it once and ask Claude, ChatGPT, or any MCP client to grade a server, surface CVEs, check the publisher, and suggest safer alternatives — before you install.
https://m8ven.ai/api/mcp/tool-check