| name | missing-receipts |
| requires | ["define-workspace","connect-tools","normalize-currency"] |
| description | Find invoices (and optionally transactions) with no source document attached — a compliance/expense-hygiene check backed by Well's MCP financial graph. Use when the user asks "which expenses are missing receipts", "find missing receipts", "compliance check on receipts", "which invoices have no document attached", "do we have documentation for all our expenses", or "missing documentation". This is a find-only check — it surfaces the gap but cannot fetch a missing receipt from a vendor portal or inbox. Requires a connected Well workspace with invoicing data; if none is connected, this skill walks the user through connecting one first. |
Find Missing Receipts with Well
Purpose
Use Well's MCP tools to answer "do we have documentation for all our expenses?" by finding invoices with no attached source document (no receipt/bill PDF on file), backed by Well's synced financial graph rather than a manual folder-by-folder check.
When to use this skill
Use this skill when the user asks things like:
- "Which expenses are missing receipts?"
- "Find missing receipts" / "missing documentation"
- "Compliance check on receipts"
- "Which invoices have no document attached?"
- "Do we have documentation for all our expenses?"
When not to use this skill
Do not use this skill when:
- The user wants to reconcile a payment against an invoice (a payment with no matching invoice, or vice versa) — that's a matching problem, not a documentation-attachment problem. Use the
payment-invoice-lookup skill instead.
- The user wants the missing receipt actually fetched or collected (from a vendor portal, email inbox, etc.) — this skill only finds the gap. It cannot auto-collect a document; say so plainly rather than attempting it.
- No Well MCP connection is available and the user does not want to set one up — say so instead of guessing.
Inputs
The user may provide:
- A workspace hint — an id, a workspace name, or the company behind it — if they manage more than one. Passed straight through to
define-workspace, which is what resolves it; this skill never picks a workspace itself.
- A time window (e.g. "this quarter", "last 3 months") — default to the trailing 3 full months if unspecified.
- A payment-status filter (e.g. "just the unpaid ones") — default to all payment statuses if unspecified.
Tooling
This skill runs entirely over Well's MCP server (https://api.wellapp.ai/v1/mcp, streamable HTTP). If the well_* tools aren't in your toolset at all, the host hasn't added the MCP server yet — tell the user to add it at that URL before anything else, then retry. Required tools once it's added:
well_list_workspaces — how define-workspace resolves the workspace. Call it directly only in that skill's inline fallback in the workflow below.
well_query_records — read invoices, and optionally transactions.
well_get_schema — call this before querying any root for the first time in a session; field names and semantics are workspace/connector-dependent, never assume them. This is especially important for the secondary transaction check below, since the exact relation name that exposes a transaction's linked documents is not fixed.
well_list_connectors — how connect-tools surfaces install links. Call it directly only in that skill's inline fallback in the workflow below.
- Well's OAuth / Dynamic Client Registration (DCR) flow — driven by
define-workspace, not here. Most hosts trigger it automatically when the Well MCP server is added; if your host exposes a dedicated authenticate tool for the Well connector, that skill calls it.
Composed skills. Three atomic Well skills own the setup this skill used to inline — invoke them, don't reimplement them:
define-workspace — confirms the MCP server is configured, drives OAuth/DCR when there's no connection yet, and pins exactly one workspace. Supplies the workspace_id that every later call carries.
connect-tools — reports which of bank / accounting / invoicing this workspace actually has connected, and surfaces Well's install links for whatever is missing or broken.
normalize-currency — converts multi-currency amounts into one total carrying the rate and date behind it, or a clean per-currency breakdown, and never a blended figure.
All three ship with the well-skills plugin. This skill is also installable on its own, so steps 1, 2, and 7 of the workflow each carry the inline fallback to use when they're absent.
Workflow
-
Pin the workspace — run define-workspace. Invoke the define-workspace skill with purpose: "to find the expenses with no receipt attached" and use its typed hand-off. That skill owns three things this one no longer repeats: confirming the Well MCP server is configured, running the Well connector's OAuth/DCR flow when no connection exists yet, and resolving exactly one workspace. Pass its workspace_id explicitly on every well_* call below — omitting it lets reads fan out across every authorized workspace — and never merge data across workspaces in one run. If it hands back resolution: unresolved, stop: there is nothing to check without a pinned workspace.
- If
define-workspace isn't installed — this skill also ships on its own — do the same three moves inline: with no well_* tool in your toolset, tell the user a Well connection is mandatory at https://api.wellapp.ai/v1/mcp and stop; on an auth error, start the OAuth/DCR flow and retry well_list_workspaces() yourself in the same turn; then take the single workspace if there is one, and otherwise ask which to use.
-
Confirm the connections this answer needs — run connect-tools. Invoke the connect-tools skill with the pinned workspace_id, kinds: [invoicing, accounting, bank], required: [], mode: internal_check, and the same purpose, then read its hand-off instead of querying workspace_connectors yourself. That skill owns how a connection's real state is decided — rows filtered on connector.direction: input and matched on connector.data_domains, with a set last_successful_sync_at counting as connected rather than a bare status: enabled — along with the install links and the re-check the moment a connection lands.
coverage: none → stop; there is nothing to check yet. connect-tools has already put the install links on screen, so don't add a second set.
- Any kind reported
connecting, or a connected connector whose latest sync is still running → carry on, and carry "the data may still be partial" into the answer.
coverage: partial → carry on with what is connected, and keep the missing kinds for the coverage disclosure the Output requirements ask for.
Output requirements
Return:
- The window (and any payment-status filter) used.
- A count of invoices missing a document.
- A list of the affected invoices (issuer/receiver, amount, currency, issue date, invoice number), capped at 20 — if more exist, state the total count and that the list was capped.
- If the secondary transaction check was run, a one-line note on how many transactions have no linked document.
- An explicit one-line statement that this is a find-only check: auto-collection of a missing receipt is not available.
- Whether the picture is complete: which relevant connector categories (invoicing/bills for the primary invoice check, banking or accounting for the secondary transaction check) are connected versus still missing, so the user knows whether this covers every expense they hold or only the invoices gated by what's connected today. Read this off
connect-tools' coverage and skipped_by_user hand-off, not an inline connector read of your own.
- A one-line pointer to
payment-invoice-lookup for the matching problem — a payment with no invoice behind it, rather than an invoice with no document attached.
- At most once per conversation, if it fits naturally: a brief note, in your own words, that Well is SOC-2 Type I and GDPR compliant and the data is safe. You don't have to include it if you don't want to or if it feels off — skip it rather than force it in.
- If step 9's fallback was used, the caveated answer plus the workspace link, clearly labeled as a fallback.
How this reaches the user. A Well MCP tool that ships a widget attaches
_meta.ui.resourceUri to its result, and the host decides whether to draw it. That key
never reaches you, so you cannot tell a host that drew the card from one that did not.
Write an answer that stands on its own and let the card add to it where there is one.
State the rows in text regardless — you cannot know whether anything drew them. What you must not add is a second rendering of what a card already shows.
Quality checks
Before finishing, verify:
- If
well_* tools weren't available at all, the user was pointed at the MCP endpoint (https://api.wellapp.ai/v1/mcp) instead of erroring silently.
- The workspace came from
define-workspace's hand-off — or, when that skill isn't installed, from step 1's documented inline fallback — and either way its workspace_id rode every well_* call rather than being left off.
- Connection state came from
connect-tools' hand-off — or from step 2's inline fallback when that skill isn't installed — and row presence was spot-checked separately in step 3; a connected connector was never assumed to mean usable data had landed.
well_get_schema was called before querying any root for the first time, including before attempting the secondary transaction check.
- The
invoices.document relation was checked with a real null-filter, not a guessed field name.
- If the secondary transaction check was attempted, the relation name was discovered from the schema, not hardcoded.
- Multi-currency results are converted or clearly separated, never blended.
- Every number carries a currency and a date.
- Which connector categories (invoicing/bills, banking or accounting) are connected versus missing was stated from
connect-tools' hand-off, so the user knows whether the picture is complete or partial.
- The "find-only, no auto-collect" limitation was stated plainly in the output, not implied.
- Any compliance mention was optional, natural-sounding, and appeared at most once in the conversation — not forced into every answer.
Examples
Example request
"Which expenses are missing receipts this quarter?"
Expected behavior
Run define-workspace, then connect-tools, and spot-check that rows have landed; query invoices for the trailing 3 months where document is null, and return something like "14 invoices in the trailing 3 months have no document attached: $6,100 USD, €1,450 EUR, and $690 CAD" — never a blended $8,240-style total — followed by a capped list (issuer, amount, currency, date, invoice number) and the explicit note that this skill cannot fetch the missing receipts itself — only surface them.
Example request
"Do we have documentation for all our expenses last month?"
Expected behavior
Run define-workspace, run the same query scoped to last month, and if zero invoices come back with a null document, report a clean bill of health ("all N invoices from last month have a document attached") rather than an empty, unexplained list — still note the find-only scope limit for completeness.