- Brand
- MosoFin
- Category
- Finance
- Primary Subcategory
- Financial Planning & FP&A Analytics
Integration details
Description
MosoFin MCP gives authenticated financial professionals and business owners workspace-scoped, read-only access to connected financial data. Each client or entity stays separate, so users can review, explain, and trust their data, replay analyses, and save reusable skills only with explicit consent.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Financial Planning & FP&A Analytics
- Secondary Subcategories
- None listed
- Brand
- MosoFin
- Access
- Account required
- First tracked
- 2026-10-10
- Tool count
- 7
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for MosoFin
Get updates when MosoFin’s Discoverability Score or category rank changes.
Competing in ChatGPT Financial Planning & FP&A Analytics
View Category7 tools agents can invoke
Persist a proven workflow as a reusable Skill. SAFETY: Does not overwrite or delete anything. This tool WRITES — it saves a new skill to your Mosofin skill library (and, when you choose that destination, sends it to Claude). Saving again never replaces an earlier skill: each save is kept as a new version and previous versions remain. It cannot edit or remove an existing skill, and it never touches your accounting or business data in any connected platform. It only runs after you explicitly confirm the save. PREREQUISITES: workspace confirmed via list_workspaces + the user's explicit, POST-RESULTS confirmation to save at all (native elicit accept, or confirmed="yes" — server-enforced, not just advisory; see below) + destination (required — ask the user in chat first) + ``files=`` (the complete bundle; validated + secret-scanned). When destination includes ``mosofin``, the bundle is pushed BLOCKING (45s timeout) to the Django backend's skill library (``POST /api/mcp/skills/upload/``) — no local write, no best-effort swallow. On any failure nothing was saved and a structured error envelope is returned. Args: name: Human-readable name. Used as the display title and to derive the kebab-case ``slug`` identifier. description: ~100-word description that triggers the skill in future conversations (e.g. "use when the user asks for ..."). destination: One of ``"mosofin"`` / ``"claude"`` / ``"both"``. REQUIRED — ask the user in plain chat first, then pass the answer here. (Inline elicit picker exists as a fallback but is unreliable in some clients — don't rely on it.) files: REQUIRED JSON-encoded mapping of ``{relative_path: text_content}``. The server persists EXACTLY these files (Claude composes the bundle, including any custom artifacts like ``references/*.md`` or ``scripts/render.py``). The bundle MUST include ``SKILL.md`` at its root with valid YAML frontmatter (name + description). Datasource-backed workflows MUST also include ``references/run-recipe.json`` — one step per invoke made during the chat (exact params, ``{workspace_id}`` placeholder, ``inputs`` declaring run-time values like dates with the question to ask the user, ``returns`` per payload, optional ``scripts/`` transform) — enforced, not advisory. ``.html``/``.css``/``.svg`` files are rejected. Limits: ≤50 files, ≤1MB per file, ≤5MB total. Path-traversal (``..``, absolute paths, null bytes) rejected. COMPANY FILES (multi-entity): when the workspace can connect the same platform more than once — several QuickBooks companies, say — and this run read one of them, the recipe MUST record which. Declare the input:: {"name": "data_source_id", "type": "data_source", "connector_key": "quickbooks", "ask": "Which company should this run use?"} and put ``"data_source_id": "{data_source_id}"`` on every step that read it, so a replay asks once and reuses the answer. Use a LITERAL id there instead only when the user explicitly pinned this skill to one company (e.g. "Monthly close — Acme LLC"); the replay then never asks. Omit both when the platform can only ever have one connection. datasources: Comma-separated datasource ids the skill reads from — REQUIRED whenever the workflow invoked a datasource; must exactly match the run-recipe steps (enforced). Recorded as the skill's sources metadata. Returns ``SkillUploadResult`` with: - ``skill_id`` (backend hashid) + ``name`` (always) - ``files_committed`` listing every pushed file with its SHA-256 (computed client-side from the pushed bundle content) - ``claude_bundle`` (when ``claude`` in destinations) — file tree + install instructions for Claude Code / Claude.ai On a backend failure (any ``ValidAccessError``), returns a structured error envelope dict instead — nothing was persisted. Save confirmation gate: mirrors ``get_my_skill``'s consent pattern (server-enforced, not just advisory). Show the user the completed results/analysis FIRST, then ask "save this as a reusable skill?" as its own question — a general earlier go-ahead ("yes, run it and save it") is not a substitute and must not be passed through as ``confirmed="yes"``. Runs BEFORE any backend/persist call, so a decline touches nothing. When the client supports native elicit, this prompt IS the confirmation and no separate ``confirmed`` value is needed.
create_skill
List the LIVE datasources connected in a Mosofin workspace. SAFETY: Does not change any of your data. This tool only reports which platforms and company files are connected and whether each connection is live. It does not connect, disconnect, or reauthorize anything, and it does not read business data from the platforms themselves. This is the live "what is ACTUALLY connected" view, read straight from the Django backend. It is the counterpart to ``get_datasource_tools`` (which is the STATIC "what is possible" catalog view). Each datasource carries its raw ``status`` plus a derived ``connected`` flag (true iff the status is ACTIVE, case-tolerant), so the model can tell the user whether a platform is really wired up before attempting to invoke any of its tools. Returns EVERY datasource in the workspace — including disconnected/retired ones (which surface with ``connected: false`` and a null ``agent_slug``). ``agent_id`` is an OPTIONAL best-effort filter (the agent's catalog id, e.g. 'bea'): when given, the list is narrowed to that agent's datasources BUT unlinked/retired rows (no agent attribution) are still surfaced so a stale connection is never hidden. Omit ``agent_id`` for the full per-tenant list. PRESENTING THE ANSWER: read ``agents`` — it is already grouped and sorted the way the user wants it shown: each agent by name, under it each platform by name, and under a platform with several accounts the list of account names. A platform with one account carries that account's name and status inline. ``datasources`` is the same data as a flat index. MULTIPLE COMPANIES: a workspace can connect the same platform more than once — several QuickBooks company files, for example. Each is a separate row here with its own ``data_source_id``. When more than one row for a platform is ``connected``, ASK THE USER which company they mean and pass that row's ``data_source_id`` on every ``invoke_datasource_api_tool`` and ``get_datasource_tools`` call. Refer to companies by ``display_name``; never show the raw ``data_source_id``. To compare companies, invoke once per company and label each result. (Invoking without a choice when several are live returns an ``entity_required`` error listing them.) Resolution order for ``workspace_id``: tool arg → JWT claim → elicit.
get_agent_datasources
List the API tools available on a datasource, each with its policy. SAFETY: Does not change any of your data. This tool only describes which read tools exist on a connected platform and whether you are allowed to use them. It does not run any of them and does not contact the platform's data API. PREREQUISITES: workspace confirmed. Agent-permission gate applies (agent must include the datasource in its permitted set). This is the ONLY way to surface per-datasource API tools to the client — they are intentionally hidden from the top-level ``list_tools`` to keep the surface focused on workflow navigation. Returns a structured list of tools each with: short ``name`` (e.g. 'list_invoices'), ``qualified_name`` (e.g. 'quickbooks.list_invoices') matching the ``Skill.tools`` references, ``description``, and ``effective_policy`` (enabled / permission / disabled). Use this to discover which tools exist AND their policies before invoking. A tool with ``effective_policy: "permission"`` is still callable — call ``invoke_datasource_api_tool`` and the server prompts the user for one-time approval (native ``ctx.elicit`` dialog when the transport supports it; otherwise an ``approval_required`` envelope for chat consent). Only ``disabled`` means do not invoke. The candidate tool SET is sourced from the live backend ``api_tools_tool`` MENU (the product owner's source of truth for what a connector exposes), NOT the static catalog. Before exposure, every candidate passes through the canonical read-only operation filter. Write-capable tools (e.g. ``create_journal``) are hidden from this MCP surface even if the backend menu contains them. Each remaining tool's ``effective_policy`` is resolved override-else-default: a per-workspace ``api_tools_apitoolpolicy`` override (keyed on the tool id) beats the tool's factory ``default_policy``. ACTIVE-gated: the listing is EMPTY when there is no live connection. If the workspace has no ACTIVE ``agents_datasource`` row for the connector, there is nothing to configure, so ``api_tools`` is ``[]`` (see ``get_agent_datasources`` for the live connection view). The agent-permission check is strict: passing a datasource the agent does not include in its ``datasources[]`` raises ``ValueError`` so the model self-corrects rather than calling a forbidden datasource. Resolution: workspace_id → tool arg / JWT / elicit. agent_id → tool arg / elicit. datasource → tool arg (validated) / elicit (limited to the agent's permitted set).
get_datasource_tools
Fetch one saved skill's bundle (manifest, or specific files in full). SAFETY: Does not change any of your data. This tool only opens a skill you already saved so its steps can be read. It does not edit, re-save, or delete the skill, does not run the steps inside it, and never touches a connected platform. It only runs after you confirm. PREREQUISITES: workspace confirmed via list_workspaces + skill_id (owner-only) + user confirmation (native elicit accept, or `confirmed="yes"` after an explicit chat yes). The consent gate is server-enforced, not just advisory: once `get_skills` returns a list, the model cannot silently replay a skill -- the user must explicitly approve it first. A refused call (elicit-unsupported, declined, cancelled, or explicit "no") returns no bundle content. Default (no ``paths``): returns the skill's metadata, SKILL.md body (always inline), and a MANIFEST of every bundled resource -- small text/markdown references and ``references/run-recipe.json`` are inlined (<=8KB per file, 48KB total budget); everything else (assets, oversize references) is omitted (content_omitted=True). Re-call with ``paths=[...], confirmed="yes"`` to fetch those files' FULL content (no size cap) -- the result's ``resources`` then contain only the requested entries. An unknown path raises ValueError listing the valid paths. REPLAY: when the manifest contains ``references/run-recipe.json``, replay by FIRST asking the user each of its ``inputs`` entries (put the ``ask`` question verbatim -- dates are never silently defaulted), then executing the steps in order (same-``parallel_group`` steps batched in one message), substituting ``{workspace_id}`` and the collected inputs into each step's params. A ``type: "data_source"`` input means WHICH connected company file the run should read. Resolve it by calling ``get_agent_datasources`` and asking the user to pick by ``display_name`` (never show the raw id); if exactly one is connected for that ``connector_key`` you may use it without asking. Pass the chosen id as the ``data_source_id`` argument of every ``invoke_datasource_api_tool`` call whose step carries ``"data_source_id": "{data_source_id}"``. A step with a LITERAL id instead of the placeholder is deliberately pinned to one company -- use it as written and do not re-ask. Owner-only: a skill owned by someone else, archived, unknown, or a malformed id all return the SAME error — never infer existence from it.
get_my_skill
List the caller's own saved skills, scoped to the resolved workspace. SAFETY: Does not change any of your data. This tool only lists the skills you have already saved. It does not create, edit, run, or delete a skill, and it never touches a connected platform. PREREQUISITES: workspace confirmed via list_workspaces. OPTIONAL discovery — invoke_datasource_api_tool does NOT require this call first. **When to call:** When the user asks what skills are available, whether a saved workflow covers their ask, or describes a repeatable task (e.g. "expense dashboard for June"). Match rows by ``name`` and ``description``. Optional ``dashboard_slug`` on a row is an ignored legacy field from the backend — do not route to show-tools; always replay via ``get_my_skill`` + SKILL.md + ``invoke_datasource_api_tool``. On a confident match, present the skill to the user BY NAME and get their explicit yes before replaying it — the user decides, never auto-replay. Only after that explicit yes, call ``get_my_skill(skill_id, confirmed="yes")`` next and follow SKILL.md directly. When no skill matches (or the list is empty), answer directly via ``invoke_datasource_api_tool``. Backend-stored (docs/django-api/10-skills-api-handoff-2026-07-03.md), NOT a static catalog: sourced live from ``GET /api/mcp/skills/``. Skills are workspace-scoped (D56, docs/django-api/11-create-skill-cutover-handoff-2026-07-09.md §1.3) — this returns only skills where ``owner = JWT user AND tenant = the gated workspace``; identity is ``(tenant, owner, name, data_source)``. A skill saved in one workspace is NOT listed under another workspace. Each row carries ``skill_id`` (opaque hashid — feed into ``get_my_skill`` for the full bundle), plus ``creator``, ``agents[]``, ``datasources[]``, ``enabled``, ``visibility``, ``review_status``, ``version``. Returns a ``PersonalSkillList`` shape (dumped to a dict — the return annotation stays ``dict[str, Any]`` because the strict schema type lives in ``app.mcp.skills.schemas``, which cannot be imported at THIS module's top level without re-entering the ``app.mcp.skills`` package-init cycle; see the local import below) on success, or a structured error envelope (``to_error_envelope``) on any backend/gate failure.
get_skills
Invoke a per-datasource API tool to read business data. SAFETY: Does not change any of your business data. This tool only reads from the platforms connected to your workspace — QuickBooks, Stripe and the rest. It cannot create, edit, delete, send, or pay anything: the server refuses any operation that is not a read, so no accounting record, invoice, payment, or customer is ever modified. It DOES reach out over the internet to those third-party platforms to fetch your data, which is why it is marked open-world. PREREQUISITES: workspace confirmed via list_workspaces — that is the ONLY workflow gate. Per-call agent-permission / live-status / policy gates still apply. Multiple calls to this tool may run IN PARALLEL — batch independent reads (e.g. P&L + balance sheet + aging) as concurrent invocations instead of serializing them. Optionally call ``get_skills`` first to check whether a saved skill covers the user's ask, and ``get_datasource_tools`` to discover valid tool names — neither is required before invoking. QuickBooks is a LIVE, read-only connector: responses come from the user's real QuickBooks Online company via the Intuit REST API (using the workspace's stored OAuth connection) and are stamped ``"mock": false``. Other datasources may still be fixture-backed (``"mock": true``) until they are wired live — always check the ``mock`` field before telling the user whether numbers are real. Mosofin is strictly READ-ONLY: no create / update / delete tool is exposed on any datasource (PERM-05). GROUNDING (enforced contract, echoed in every result): every figure you give the user must come from data returned by this tool in this conversation — do NOT tag individual figures with source citations; instead end each data-backed answer with a single 'Data sources' line grouping the calls used by datasource (each result carries a ``provenance`` block — datasource, tool, params, fetched_at, mock). If the fetched data does not cover part of the question, say so and name the tool that could fetch it instead of estimating. Routing: - ``datasource``: the platform id (e.g. ``"quickbooks"``). - ``tool_name``: the API tool's plain name (e.g. ``"search_invoices"``). Valid names come from the workspace's connector catalog / conversation context; an ``UNKNOWN_TOOL`` error also lists the valid names. - ``params``: a JSON object of tool-specific filters (e.g. ``{"start_date": "2025-12-01", "end_date": "2025-12-31", "max_results": 50}``). - ``approved``: set ``True`` ONLY after the user has EXPLICITLY approved (in chat) a tool whose policy is ``permission``. The model relays the user's consent via this flag — there is NO native human-in-the-loop channel in this server's stateless transport, so a ``permission`` tool first returns an ``approval_required`` envelope; ask the user, and on their explicit yes re-invoke this SAME tool with ``approved=True``. Never set it without the user's explicit yes. Pagination for search/query-kind tools: a QuickBooks ``search_*`` tool's ``result`` is shaped as ``{"rows": [...], "pagination": {"offset", "max_results", "start_position", "total_count", "has_more", "next_offset"}}``. Once a date range is set, the server returns as many rows as fit under the response size cap per call (up to 1000 rows/page — QBO's hard maximum). If a page is too large, the server automatically shrinks the page size and retries internally, so you do NOT need to manually guess a small ``max_results`` defensively — omit ``max_results`` entirely to get the largest page that fits. When ``pagination.has_more`` is ``true``, re-invoke this SAME tool with ``params.offset`` set to the previous response's ``pagination.next_offset`` to fetch the next page; ``pagination.max_results`` reflects the ACTUAL page size used, which may be smaller than requested if the server had to shrink it. Budgets — two-step flow: first call ``search_budgets`` to LIST which budgets exist (lightweight, headers + names). Then call ``get_budget_details`` with ``budget_id`` or ``budget_name`` to get the NUMBERS for exactly one budget — it always returns full BudgetDetail line items (no summary mode). For very large budgets, narrow the result with ``detail_start_date``/``detail_end_date``, ``detail_account``, or ``detail_rollup`` (``"account"`` or ``"month"``). ``search_budgets`` still returns full detail by default too (pass ``include_details: false`` on ``search_budgets`` for header-only summaries); prefer ``get_budget_details`` once you know which budget you want. Required date ranges: QuickBooks transaction-search tools (``search_bills``, ``search_invoices``, ``search_payments``, etc.) and period reports (``get_profit_and_loss``, ``get_cash_flow``, ``get_trial_balance``, ``get_general_ledger``, ``get_customer_sales``, ``get_vendor_expenses``) REQUIRE both ``start_date`` and ``end_date`` (``YYYY-MM-DD``) in ``params``. Compute concrete ISO dates from relative phrases like "last month" or "this quarter" BEFORE invoking — e.g. resolve "last month" to a concrete ``{"start_date": "2026-06-01", "end_date": "2026-06-30"}`` pair. Omitting either returns an ``invalid_params`` error naming the missing field. As-of reports (``get_balance_sheet``, ``get_aged_receivables``, ``get_aged_payables``, ``get_customer_balance``, ``get_vendor_balance``) default to today's date and need no dates; an optional ``report_date`` can override. Three orthogonal gates must ALL pass before dispatch: 1. Static permission gate: the chosen ``agent_id`` must include ``datasource`` in its permitted ``datasources`` list ("is this agent ALLOWED to use it"). 2. Live status gate: the datasource's live ``agents_datasource.status`` must be ACTIVE in this workspace ("is it actually LIVE right now"). A non-ACTIVE datasource is refused with a structured ``datasource_not_active`` envelope (never dispatched), so a stale/disconnected connection is never silently attempted. 3. Policy gate (fail-closed): the tool's effective policy (``COALESCE(override.policy, default_policy)`` for this workspace + datasource) must be ``enabled`` or ``permission`` ("is this tool allowed by policy right now"). A ``disabled``/``unknown``/malformed policy is refused with a structured ``tool_policy_disabled`` envelope (never dispatched). ``permission`` requires the user's explicit consent: it returns a pending ``approval_required`` envelope until the call is re-invoked with ``approved=True``; write access is globally off regardless. If the workspace has no connected account, the OAuth token is expired, or the datasource is not ACTIVE, the tool returns a structured ``"status": "error"`` envelope with ``reason`` of ``connection_unavailable`` or ``datasource_not_active``, a human-readable ``error``, and a ``reconnect_url`` pointing at the Mosofin data-sources page — never a 500. Tell the user to open that URL, sign in, and reconnect before retrying. Catalog tools without a live mapping return ``mock_not_implemented`` listing what IS available, so the model can self-correct.
invoke_datasource_api_tool
List or confirm the workspace(s) the current user can access. SAFETY: Does not change any of your data. This tool only reads the list of workspaces you already belong to and remembers which one you picked for this conversation. It creates nothing, edits nothing, and deletes nothing — in Mosofin or in any connected platform. PREREQUISITES: none — the root tool, always safe to call first. Records workspace confirmation — the only gate before data tools. Covers active memberships in non-archived tenants, deterministically ordered by membership.created_at (WR-04). When the user has **one** workspace, this tool auto-confirms it. When they have **multiple**, the first call (no confirm args) returns ``selection_required`` — ask in chat whether the task is **single-** or **multi-workspace**, then ask which workspace(s) by name, then call again with ``workspace_ids`` + ``mode`` before any other Mosofin tool. Each entry's ``workspace_id`` is an OPAQUE handle (``ws_…``), NOT the raw integer tenant PK — pass it straight back as the ``workspace_id`` arg to any tool (Phase E: the raw id never crosses to the client).
list_workspaces
MosoFin ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve MosoFin's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are MosoFin alternatives on ChatGPT?
As of 2026-10-10, MosoFin competes with Aleph, Alvore Finance, Cube, Datarails FinanceOS, Drivetrain, Findash, GrowPanel, Kometrics and 9 more in ChatGPT Financial Planning & FP&A Analytics, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.