Emerald
NPM · EMERALD-MCP
The database under the chat: a local SQLite file a model asks for rows, not notes to re-read.
Available components
Last scanned (19 hours ago)
Scores higher than 40% of npm servers
Category Databases
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- No production dependencies, so there is no dependency health to assess. View diagnostics → Pass
Provenance & Transparency48
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (AGPL-3.0-only).Pass
- Actively maintained (last published 0 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability35
- 0% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Fail
- AI-judged instruction clarity (good).Pass
- Context-footprint check failed: tool/resource definitions use about 26594 tokens (~309/item across 86 items; 85 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management53
- Stability observed for 16 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 87 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
- Supports UI / widget rendering.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 4 Nov 26 +26
- Malware scan: unverified → pass ▲ security
- Known CVEs: unverified → pass ▲ security
- Dependency health: unverified → pass ▲ functional
- 3 Nov 26 −25
- Malware scan: pass → unverified ▼ security
- Known CVEs: pass → unverified ▼ security
- Dependency health: pass → unverified ▼ functional
- Package version: 0.2.0 → 0.3.0 functional
- 31 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.
- 29 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.
- 27 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.
- 24 Oct 26 +26
- Malware scan: unverified → pass ▲ security
- Known CVEs: unverified → pass ▲ security
- Dependency health: unverified → pass ▲ functional
- 23 Oct 26 −25
- Malware scan: pass → unverified ▼ security
- Known CVEs: pass → unverified ▼ security
- Dependency health: pass → unverified ▼ functional
- Package version: 0.1.6 → 0.2.0 functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 4 Nov 2026 · Analysed npm/emerald-mcp@0.3.0
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | npm |
Background: How many MCP packages publish verified provenance →
Dependencies 0 packages
| Packages resolved | 0 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
answer_transfers Answer transfers between the person’s own accounts ~175
Answers the pairs `transfers` lists — **a list in one call**. `transfer`: one transfer between two of the person’s accounts, so neither row is income or spending (the end on an ordinary account counts as money moved, the end on an account with holdings is in no total). `not_a_transfer`: two rows that only looked like one; both stay what they were and are never suggested again. `undecided` takes an answer back. **Dry-runs by default**; the document is copied to a timestamped .bak first.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews; true writes. |
| pairs | array | yes | One entry per pair. Up to 500 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
apply_rules Apply a rule set ~186
Run a rule set over every row it sets — a write applies it by itself. A person’s value is never touched; a tie is named. With `link`, fill that link’s empty cells by its `found_by` instead; a set link is never moved, and a row with no match or two is named. Dry run until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Write it. Omit or false for the dry run. |
| format | string | yes | The format whose rows are the rules — or, with `link`, the one the link is on. |
| link | string | – | A link column found by a date (`found_by`): fill the rows where it is empty. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| rule_set | string | – | By name; optional when there is one. |
No output schema declared.
No examples provided.
arrange_views Arrange a format’s views ~254
How the app shows a format: on its entry, a column’s `show_as`, `header` line, `hidden`, `new_entry` and the `order`; a board’s lanes; a table column’s `width`; a column’s `setting` in a list, a roadmap, a ready list or a start-here question; `view: saved`, a `name` and what it keeps (`today` stays that phrase) — on one saved, only what is given changes; `match:{}`, `search:""`, `order:""`, `columns:{}` empty one — or `rename`, or `delete: true`; `kind: input` takes `fields`, `defaults`, `default`; `view: dashboard` `add`s, `size`s, `order`s and `remove`s blocks (no `format`: the document’s). `formats` with a `format` shows the arrangement and each column’s ways. Dry-runs until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Write it; omit for the dry run. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| settings | array | yes | Up to 200. |
No output schema declared.
No examples provided.
assign_category Assign categories to transactions ~214
Categorize the transactions with no category — **many merchants in one call**. Send every merchant-to-category decision you have worked out as one `assignments` list rather than calling this once per merchant. **Dry-runs by default**: it returns what the whole batch would change and writes nothing until you call it again with commit true, so show the user the table and let them answer once. Rows categorized by hand are never touched, rows assigned by a rule are left to the rule, and every row it does change is marked AI so the batch stays findable. The document is copied to a timestamped .bak before anything is written. A row covered by two assignments refuses the batch rather than picking one.
| Name | Type | Req | Description |
|---|---|---|---|
| assignments | array | yes | One entry per category-and-scope. Up to 200 in a call. |
| commit | boolean | – | Default false. False previews the whole batch and writes nothing; true makes it. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
category_tree Category tree ~94
The document category taxonomy: every category full path (Living → Utilities → Electricity), its id, its kind and its Plan bucket. Read this before suggesting a category for anything — the ids here are what the write tools take, and two categories may share a short name.
| Name | Type | Req | Description |
|---|---|---|---|
| include_archived | boolean | – | Include archived categories. Default false. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
choose_categories Archive or restore categories ~222
Put categories away, or bring them back. Give `archive_ids` and `restore_ids` to say exactly which — these work at any time. On a document that holds no account and no transaction yet, `keep_ids` is also accepted and archives everything not listed, which is the fast way to trim the shipped list; it is refused afterwards, when one forgotten id would archive a category out from under a year of transactions. Archiving is not deleting — the history stays and comes back with it — and system categories are never touched. Ids come from category_tree. On a document that already holds work it takes a timestamped .bak first.
| Name | Type | Req | Description |
|---|---|---|---|
| archive_ids | array | – | Categories to put away. Their transactions keep pointing at them. |
| keep_ids | array | – | Empty document only: every id to keep. Everything else is archived. Refused once the document holds an account or a transaction. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| restore_ids | array | – | Archived categories to bring back. |
No output schema declared.
No examples provided.
claim_units Claim units ~247
In a document that keeps the `development` pack, take units by `ref`: `planned` to `in_progress` with `taken_by`, the git `branch` they are taken on and `started` (default today), the batch refused unless every one is still planned. With `take_over`, take units already `in_progress` from that taker — a session that stopped mid-unit — refused unless each is held by exactly that taker; `started` is reset and the taker replaced is kept on `taken_over_from`. Writes nothing until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| branch | string | – | The git branch they are taken on. |
| commit | boolean | – | Write it. Omit or false for the dry run. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| started | string | – | `YYYY-MM-DD`; today if left out. |
| take_over | string | – | The `taken_by` whose claim this replaces, for units already in progress. |
| taken_by | string | yes | Who takes them: the host’s name for its session. |
| units | array | yes | Refs, up to 50. |
No output schema declared.
No examples provided.
connect_formats Connect two formats ~590
Join two formats this document **already** declares: a `link` column on `format`, so each of its rows belongs to one row of `target` — each `recipe_line` belongs to one `recipe` — and, optionally, a total on `target` along it (an `aggregate`): `recipe.total_kcal`, the sum of `amount_g / 100 * ingredient.kcal` over the lines that name it. This is how a format gets a total of another declared after it, which `declare_format` cannot do. Name an existing link as `column` to add only the total. **It only adds**: a link may be empty, so rows already there lose nothing; `required: true` on a format that has rows is refused. A connection is removed with `extend_format` `remove` (the link column once its cells are emptied, or the total); re-pointing one is done at `#/connections` in the app. Returns what it would add and writes nothing until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| aggregate | object | – | The total `target` keeps of the rows that name it: a `name` in `snake_case`, an `of` — one of sum, count, average, minimum, maximum — a `works_out` expression over each of those rows in their own voc… |
| column | string | – | The link column’s name, `snake_case`. Defaults to the target’s name, suffixed if taken. Name an existing link to it to add only the total. |
| commit | boolean | – | Write it. Omit or false for the dry run. |
| format | string | yes | The format that gets the link — the many side, `recipe_line`. |
| found_by | string | – | How the link fills itself while empty: `date in period` (this date’s month) or `date on paid_on` (the same day). No row or two is refused by name; a link a person set stays. |
| note | string | – | What the link means. Kept with the declaration, word for word. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| required | boolean | – | Every row must name one. Refused on a format that already has rows. |
| target | string | yes | The format each row belongs to one of — `recipe`, the one side. |
No output schema declared.
No examples provided.
count_card_charges Count a card payment with no statement as spending ~167
The card payments in a bank statement for a card this document has no statement of — that month of card spending is otherwise missing. Without `cards`, lists them. With `cards` (the last four digits, or `unknown`), counts each card’s payments as the spending they stand for, so Home stops asking; the rows already count, so no figure moves. Reading the card’s statement later still makes them card payments to answer. **Dry-runs by default**; the document is copied to a timestamped .bak first.
| Name | Type | Req | Description |
|---|---|---|---|
| cards | array | – | Last four digits per card, or `unknown`. |
| commit | boolean | – | Default false. False previews; true writes. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
create_category Create categories ~228
Add categories the document does not have — **a list of them in one call**. `choose_categories` only keeps or archives the ones already there, so this is what answers "none of these fit". Give a `parent_id` or `parent_name` to put it under another, in which case it takes the parent’s kind and `kind` is ignored. Categories nest three levels at most (Living → Utilities → Electricity): a top-level category is a heading — Living, Lifestyle, Income — and a Plan bucket for it counts everything under it. Entries are applied in order, so a parent and its children go in the same call. If a category of the same name already sits in the same place nothing is created: a live one is reported back with its id, an archived one is brought back rather than twinned. Writes immediately — the change is additive, so there is nothing to preview.
| Name | Type | Req | Description |
|---|---|---|---|
| categories | array | – | One entry per category. Up to 100 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
create_debts Create debts ~164
Add debts — **several in one call**. A debt is the original principal plus a stream of payments; **the balance is derived, never stored**, so there is nothing here that sets one. Optionally set how payments are discovered: a merchant pattern for a standing order, or a category. **Dry-runs by default**; the document is copied to a timestamped .bak first. Editing, closing and deleting a debt are app-only, as is promoting a card installment group.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews the batch; true writes it. |
| debts | array | yes | One entry per debt. Up to 60 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
create_document Create an Emerald document ~187
Create a new .emd document at a path that does not exist yet; never overwrites. It keeps the `packs` named and no other, and **none when omitted**: a document starts empty and holds what the person declares. Name a pack only when the work is what it is for — `development` for a project’s memory, `ledger` for their finances. With no path the user may be shown a form; otherwise ask them.
| Name | Type | Req | Description |
|---|---|---|---|
| packs | array | – | The packs the document starts with, by id; `[]` for none. One of: `development` (a project’s memory: milestones, units, decisions, open questions, an inbox), `ledger` (personal finance, from statemen… |
| path | string | – | Full path for the new document, ending in .emd. Omit to ask the user. |
No output schema declared.
No examples provided.
create_goals Create goals ~257
Add goals — **several in one call**. A goal has a name; a target amount and a target date are optional, and an open-ended goal is a real answer. Its kind is optional and drives nothing (EARMARKED when left out, as the goal form makes it); how many months of expenses the bank should hold is the cushion (`set_cushion`). **Dry-runs by default**; the document is copied to a timestamped .bak before anything is written. **The goal form’s one question is `default_holding`**: a bank account’s Cash, a place kept by hand or a new one takes `already_there`; a holding a broker’s rows buy is followed by its rows, with nothing to type; a bank account’s Cash can count the transfers into it (`from_transfers`). Editing, closing and deleting a goal are app-only, except its default holding (`set_goal_deposit_categories`).
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews the batch; true writes it. |
| goals | array | yes | One entry per goal. Up to 60 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
create_rule Create a categorization rule ~348
Create a standing rule that categorizes matching transactions into a category, now and on every future import. **This is the widest write here** — it reaches the whole history — so it needs two calls: the first returns the transactions the rule would match plus a confirmation token, and the second must quote that token back. Show the user the matches before you commit; the token expires the moment the match set changes. Rows categorized by hand are never touched.
| Name | Type | Req | Description |
|---|---|---|---|
| account_id | string | – | Restrict the rule to one account. |
| amount_max | number | – | Restrict by amount, as a magnitude in major units. |
| amount_min | number | – | Restrict by amount, as a magnitude in major units. |
| apply_to_existing | boolean | – | Default true: also categorize the transactions it already matches. False creates the rule for future imports only. |
| category_id | string | yes | The category the rule assigns. Ids come from `category_tree`. |
| commit | boolean | – | Default false. True requires `confirmation` from the preview. |
| confirmation | string | – | The token the preview printed. Required to commit. |
| kind | string | – | One of EXACT_MERCHANT, CONTAINS, REGEX, PROVIDER_CATEGORY, AMOUNT_RANGE, ACCOUNT. Default CONTAINS, which survives the branch numbers and spacing that vary between two statements of the same shop. |
| name | string | – | Optional. Defaults to the pattern, which is the name of most rules. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| pattern | string | – | What the rule matches on. Required for every kind but ACCOUNT and AMOUNT_RANGE. |
No output schema declared.
No examples provided.
debt_projection Debt projection ~91
What each open debt will have left in N months, by plain addition of its monthly payment and the extra Plan puts toward it (no interest counted), and when it is paid off with and without the extra. The same view as the Debts screen.
| Name | Type | Req | Description |
|---|---|---|---|
| months | number | – | How many months ahead. Default 12. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
debts Debts ~88
Every debt with its principal, what has been paid, what is outstanding, how far along it is and when it projects to be paid off — plus the totals and what card installments still commit the user to. Open debts by default.
| Name | Type | Req | Description |
|---|---|---|---|
| include_closed | boolean | – | Include closed debts in the table. Default false. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
declare_format Declare a new format ~2,237
Bring a **new** kind of thing into a document: a format, compiled to a real table with real types and checks. Call `formats` first. Each column has a `snake_case` `name`, a `type` — one of `text`, `integer`, `real`, `date`, `boolean`, `enum`, `money`, `link`, `quantity`, `decimal`, `month`, `instant`, `links`, `percent`, `time`, `enums`, `elsewhere`, `file` — and optionally a `unit` (`g`, `kcal`), `required`, `unique` (no two rows share it — a name a row is known by; text, integer, decimal, date, month or link), `values` for an enum or enums, `minimum`/`maximum`, a `scale` for a `decimal` (6 for a rate) and a `note` saying what it means. **A format declares its claims** — `claims`, equations over its numeric columns with a tolerance, like `4*protein_g + 4*carbs_g + 9*fat_g = kcal` within 2%; they make a row provable and never refuse one. **Ask the user whether any figures relate** before answering (a total and its parts, a price and a quantity); a list — books, contacts — makes none, needs no claims, and still gets every refusal. A figure worked out rather than typed is a `computed` column. **`money` is two columns**, minor units beside a currency, so no figure is a float. **`quantity` is two as well**, a figure beside the unit *that row* is in — only when the unit varies by row; otherwise a `real` with a `unit`. Neither takes a `unit`. A **ratio** has a `unit` and a `per` — `density`, `g` per `ml` — the only way a figure crosses dimensions: a claim writes `amount in g via ingredient.density`. No free-text check, no expression. **Across two columns of one row** is a `constraint`, one of four sentences: `isbn is required when kind is BOOK` (`required only when` adds *and empty otherwise*), `at most one of book, article, video`, `score is at most 10 when kind is QUIZ` (or `at least`), and `one row per course, week` (`when status is DONE` limits it) — a row breaking one is refused. `notes` is prose kept word for word: where the figures come from and what was decided.…
| Name | Type | Req | Description |
|---|---|---|---|
| aggregates | array | – | What this format works out from the rows of another that point at it. Each has a `name` in `snake_case`, an `of` — one of sum, count, average, minimum, maximum, latest, earliest — an `over_format` an… |
| claims | array | – | What is claimed about one of these, proved or failed on every row. Each has a `name` in `snake_case`, an `expression` — one `=` with arithmetic over this format’s own numeric columns on either side —… |
| columns | array | – | The columns, in the order they should read. Up to 64. `text` — Words. A name, a note, a code — anything not measured. `integer` — A whole number, with no fractional part at all. `real` — A number tha… |
| commit | boolean | – | Write it. Omit or false for the dry run. |
| computed | array | – | Computed columns, worked out rather than typed, each `{ name, works_out, note }`: a claim’s expression with no `=` — `price * (1 + vat)`, `amount in g`, `link.column`, an aggregate’s name, another co… |
| constraints | array | – | Rules across the columns of one row, each `{ rule, note }` — `rule` is one of `x is required when kind is A, B`, `x is required only when kind is A, B` (and empty otherwise), `at most one of a, b, c`… |
| format | string | – | The name of the format, `snake_case` — `ingredient`. It names the table. |
| formats | array | – | Several new formats, each `{ format, title, columns, … }`. |
| notes | string | – | Prose about the format. Kept verbatim, never parsed. Optional but wanted. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| rollups | array | – | Figures per month over this format’s rows, each `{ name, works_out, note }`: `sum of minutes by month of done_on or started_on and project where status is DONE` — sum, count, average, minimum or maxi… |
| rule_sets | array | – | Rows of this format as rules setting a link of another, each `{ name, sets, note }`: `note.topic from target when title matches pattern by kind (EXACT equals, PART contains) first by priority, record… |
| title | string | – | What a person calls one of these — `Ingredient`. |
No output schema declared.
No examples provided.
delete_format Remove a format and every row in it ~131
Remove a declared format: its declaration, its table and **every row in it**. Refused while another format links to it or folds its rows. The dry run says how many rows go; show that to the user, and call again with `commit: true` only on a plain yes. To remove some rows, use `delete_format_rows` instead.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Remove it. Omit or false for the dry run. |
| format | string | yes | The format to remove, by name. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
delete_format_rows Remove rows of a declared format ~185
Remove rows from a declared format by id — **a list of them in one call**. **Refused while any other row still links to one of them** — the dry run names those rows; re-link or clear them first. The app removes one row at a time from `#/formats/<name>`; this is how thirty go at once, after printing every one of them in full. Writes nothing until `commit: true`; a copy of the document is taken first, and it is the only way back.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Remove them. Omit or false for the dry run. |
| format | string | yes | The declared format, by name. |
| ids | array | yes | Row ids, as `format_rows` printed them. Up to 200. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
dismiss_fixed_expense_candidates Say no to suggested recurring charges ~129
Record that these merchants are not recurring bills, so the detector stops offering them — to this conversation and to every later one. A dismissal lasts until it is cleared; pass restore to clear it and let the merchant be suggested again. Writes immediately: it changes no transaction, no category and no bill.
| Name | Type | Req | Description |
|---|---|---|---|
| merchants | array | yes | Normalized merchant names, exactly as `fixed_expense_candidates` printed them. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| restore | boolean | – | Default false. True clears these dismissals instead of making them. |
No output schema declared.
No examples provided.
dispatch_plan Dispatch plan ~137
In a document that keeps the `development` pack, before handing units out: for unit refs (every ready unit if left out), which can run at once and which share a path in their `paths` — one per line — and so go one after another, beside any unit in progress; a unit with no paths is unknown, never safe. Then each one’s brief, the units it waits on and the decisions it names. Read-only.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | Absolute path to a .emd file on this machine. |
| units | array | – | Refs, up to 50. Omit for every ready unit. |
No output schema declared.
No examples provided.
document_info Emerald document info ~115
Describe an Emerald document (a .emd file): whether this plugin will serve it, the formats it declares with how many rows each holds, and — when it keeps the ledger — its accounts, transactions, categories and reporting currency. Call it when a tool refuses a document — every tool refuses one whose schema does not match, and this is the one that says so in a sentence the user can act on. Reads the file; never modifies it.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
edit_categories Rename, colour, move, merge, archive or delete categories ~348
Change categories that exist — **a list of edits in one call**. Per entry: `name`, `parent_id` (any category of its kind with room — three levels at most — or null for the top level), `move` (up or down), `archived`, `monthly_target` (major units, null clears — the category’s Plan bucket in the plan in use: one figure, shared with Plan), `color` (category-1 … category-11, null for automatic), `icon`, or, alone in the entry, `merge_into` (a category id) or `delete: true` — with `move_to` (a category id of the same kind) when rows, rules, subcategories, Plan buckets, bills, debts or goals still use it. This is the Categories screen’s rename, colour, move, merge, archive and delete, and its Plan bucket. A heading (Living, Income…) is a top-level category, renamed and moved like any other. Adding categories is `create_category`. **Dry-runs by default**: it says what each entry would do and which it refuses (a taken name, a fourth level, a delete with nowhere to move what uses it) and writes nothing until you call again with `commit: true`. The document is copied to a timestamped .bak first. Ids come from `category_tree`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews and writes nothing; true makes the changes. |
| edits | array | – | One entry per category. Up to 100 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
edit_fixed_expenses Edit, end or stop tracking bills ~252
Change bills that exist — **a list in one call**. Per entry: `name`, `expected_amount` (the whole charge, major units — a yearly premium is the year’s figure), `cadence`, `category_id` (null clears), `is_discretionary`, `day_of_month` (null clears), `ended_on` (YYYY-MM-DD or "today": it keeps its history and drops out of every plan); or, alone, `stop_tracking: true`, which removes it and what every plan said about it — its charges stay on Transactions. How it is recognised in the ledger is not changed here. Adding is `track_fixed_expenses`; what it does to a plan is `set_fixed_expense_roles`. **Dry-runs by default**; `commit: true` writes. The document is copied to a timestamped .bak first. Ids come from `plans` or `fixed_expenses`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews; true writes. |
| edits | array | yes | One entry per bill. Up to 100 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
extend_format Change a format ~1,086
Change a format this document **already** declares, as its table does: add `columns`, `claims`, `computed` columns, `unique`, `constraints`, `rollups` and `aggregates` as `declare_format` takes them; `rename`, `change` or `remove` what it has; `order` the columns. A rename keeps its values. Refused, naming the rows: a `required` column on rows, removing a column holding values, a list the rows do not fit, a type or unit change over values. Writes nothing until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| aggregates | array | – | New totals, as `declare_format` takes them. A `count` needs no `works_out`. |
| change | array | – | Columns it has, named, with what changes: `{ name, type: "enum", values }`. |
| claims | array | – | New claims, each with a `name`, an `expression` with one `=`, an optional `tolerance` and a `note` — as `declare_format` takes them. |
| columns | array | – | The new columns, after the ones it has. Up to 64. `text` — Words. A name, a note, a code — anything not measured. `integer` — A whole number, with no fractional part at all. `real` — A number that ca… |
| commit | boolean | – | Write it. Omit or false for the dry run. |
| computed | array | – | New computed columns, as `declare_format` takes them. |
| constraints | array | – | New row constraints, each `{ rule, note }` as `declare_format` takes them — refused, naming the rows, while any row already breaks one. |
| format | string | yes | The format to change, by name. |
| order | array | – | Every column, new ones too, once each, in order. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| remove | array | – | Names of columns, claims, totals, computed columns, rollups or rule sets. |
| rename | object | – | `{ old: new }`. |
| rollups | array | – | New rollups, as `declare_format` takes them. |
| rule_sets | array | – | New rule sets. |
| unique | array | – | Columns it already has that should become unique — refused, naming the repeated values, while two rows share one. |
No output schema declared.
No examples provided.
fixed_expense_candidates Recurring charges the ledger suggests ~210
What looks like a recurring bill in the imported transactions but has not been confirmed as one: the merchant, the typical charge and its amortized monthly share, the cadence, how many months it was seen in, how much the amount and the day move, and how confident the detector is. Merchants already tracked or previously dismissed are excluded. This is the question `fixed_expenses` answers the other half of — that one lists what is already committed. Reads the document; changes nothing.
| Name | Type | Req | Description |
|---|---|---|---|
| ending_at | string | – | The newest month of the window, as YYYY-MM. Default this month. |
| include_dismissed | boolean | – | Also list the merchants that were said no to. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| window_months | number | – | How many months of history to look at, 2–24. Default 3. A window cannot see a cadence longer than itself: use 12 to find yearly charges. |
No output schema declared.
No examples provided.
fixed_expenses Bills ~94
The bills the document tracks: what each is expected to cost, its amortized monthly equivalent, its cadence, whether the amount is fixed or variable, what it is matched against in the ledger, and whether the user marked it cuttable. Active ones by default.
| Name | Type | Req | Description |
|---|---|---|---|
| include_inactive | boolean | – | Include ended bills. Default false. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
format_problems What looks wrong in declared formats ~96
What the engine can see is wrong in a format’s rows, without a rule anybody wrote: a link empty where most rows fill it, rows the same in every column, claims failed or unchecked. `read_onto_format` says it after every read. Reads only.
| Name | Type | Req | Description |
|---|---|---|---|
| formats | array | – | By name. Omit for every one. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
format_rollup A rollup of a declared format ~141
A rollup a format declares, run: a figure per month, and per linked row. `formats` lists them. A month with a row that cannot answer is `unchecked`, naming it; money stays per currency. Reads only.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | yes | The declared format, by name. |
| from | string | – | First month, `YYYY-MM`. |
| limit | number | – | Groups. Default 25. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| rollup | string | – | By name; optional when there is one. |
| to | string | – | Last month, `YYYY-MM`. |
No output schema declared.
No examples provided.
format_rows Rows of a declared format ~592
The rows this document holds of one declared format. Ask `formats` first for the column names — they belong to the document. `match` filters on exact values (text and enum members case-insensitively; a list column, the rows holding the one named), `search` a substring in every column as shown (a price as 12.90, a link by its row’s name) but yes/no, and `order` sorts by any column, computed too — by default the one a row is named by, which is its first text column. Narrow `columns` to get a table of just those — a computed column (a total, or one worked out from the row) by its name too; leave it out and each row comes back in full with its empty columns left out, **and with what its claims say about it** — proved, failed, or unchecked when the row has nothing in a column one of them names. Every row carries the id the other tools use to correct or remove it. Reads the file; never modifies it.
| Name | Type | Req | Description |
|---|---|---|---|
| columns | array | – | Column names to show, as a table — stored or computed. Omit for every column. |
| descending | boolean | – | Sort the other way. Defaults to false. |
| format | string | yes | The declared format, by name. `formats` lists them. |
| limit | number | – | Rows to return. Defaults to 25, at most 200. |
| match | object | – | Column name to the value it must equal. Text and enum columns match without regard to case; money or a quantity, a range: `10..50 ILS`. A list is any of them (`[planned, in_progress]`; a list column… |
| offset | number | – | Rows to skip first — the `offset` a cut-short answer hands back for the rest. |
| order | string | – | A declared column to sort by. Defaults to the column a row is named by — its first text column — which is what the screen sorts by too. Ordering by the generated id shuffles, since an id is generated… |
| path | string | yes | Absolute path to a .emd file on this machine. |
| search | string | – | A substring, in every column as shown but yes/no. |
| values | string | – | A column: each value it holds and how many rows, under the other filters. |
| view | string | – | A saved view’s name: its match, search, order and columns, under any given here. |
No output schema declared.
No examples provided.
formats Declared formats ~139
What kinds of thing this document holds — every format declared in it, with its columns, their types, units, bounds and enum members, and the prose the author wrote around them. The columns are declared per document: `start_here` ends with one line per format, enough to write a row, and this is the whole declaration. Name a `format` for its full column list; omit it for the list of what is declared. Reads the file; never modifies it.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | One declared format by name, for its full column list. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
frame_copy The document, for a view drawn in the conversation ~98
Not for a model: a view drawn in the conversation calls it with its own key to fetch its document, and any other call is refused. Read rows with `format_rows`.
| Name | Type | Req | Description |
|---|---|---|---|
| key | string | yes | The drawn view’s own key. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| since | string | – | The stamp of the copy the view holds; no copy comes back while it still holds. |
No output schema declared.
No examples provided.
funds Pension and hishtalmut funds ~233
Every pension, study fund, provident fund and managers’ insurance the document tracks: the latest transcribed balance and how old it is, the management fee as stated and as measured against what was actually charged, what the dormant ones cost a year, and — the point of the feature — **whether the paychecks and the fund’s own report agree about what was deposited**. A fund finds its paycheck lines through the deduction types that pay into it — `set_deduction_types` sets that link. Name one with fund_id to also get its readings, its return window by window, and the working behind that check. Reads the document; changes nothing.
| Name | Type | Req | Description |
|---|---|---|---|
| fund_id | string | – | Narrow to one fund and add its working — readings, returns, and the expected-versus-actual table behind the deposit verdict. Ids come from this same tool. |
| include_archived | boolean | – | Include archived funds. Default false. A fund can be archived with a gap still open in it, so ask for them when chasing one. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
goal_projection Goal projection ~90
What each open goal will hold in N months, by plain addition of the amount Plan puts toward it each month (no interest counted), and what a month would have to be to reach it on its date. The same view as the Goals screen.
| Name | Type | Req | Description |
|---|---|---|---|
| months | number | – | How many months ahead. Default 12. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
guide_status Guide: what to set up, and what is done ~133
In a document that keeps the ledger: the places worth setting up, in order — reading statements and paychecks, making the list of categories yours, giving each merchant a category, the bills, the plan, the opening balance and the cushion — with which are done and what the document shows for each, and the tool that does each one. The same list and the same checks as the app’s Guide me. Call it after create_document, or when the user asks what is left to set up. Reads the document; changes nothing.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
import_statement Import a statement ~463
Import a card or bank statement into an account, through the app’s own pipeline: the same parse, the same dedupe by natural key, the same rules applied on commit. **Dry-runs by default** — it reports what it would import and how the parse compares with the total the file prints for itself, and writes nothing until commit is true. **A file whose printed total does not reconcile is refused**, because importing over it puts numbers in the ledger the file itself says are wrong. Re-importing the same statement is safe: duplicates are matched and skipped.
| Name | Type | Req | Description |
|---|---|---|---|
| account_id | string | – | The account to import into. Ids come from `document_info`. Or `new_account`. |
| amount_convention | string | – | One of SIGNED_SINGLE, POSITIVE_IS_CHARGE, SEPARATE_DEBIT_CREDIT. Usually read from the roles you map — state it only when a single amount column needs saying which sign is a charge. |
| columns | object | – | Column number → role, from what the user confirmed in `statement_preview`. Omit when a reader already recognises the file. |
| commit | boolean | – | Default false. False previews the import and writes nothing. |
| file | string | yes | Absolute path to the statement file. One of .xlsx, .xls, .csv. |
| header_row | number | – | Force the header row number, when the guess is wrong. |
| ignore_printed_total | boolean | – | Import even though the parse disagrees with the total the file prints. Default false, and it should stay false unless the user is certain the file’s own figure is wrong. |
| new_account | object | – | Instead of `account_id`, on a document that has no account for this file yet: the account the statement is for, made on commit — or found, when one of that kind already has these last 4 digits, as th… |
| path | string | yes | Absolute path to a .emd file on this machine. |
| save_mapping_as | string | – | Keep these columns as a reader under this name, so the next statement of the same shape imports without asking. |
| sheet | string | – | Which sheet, when the file has more than one. |
No output schema declared.
No examples provided.
keep_copy Back up a document now ~124
Backs the document up now: a copy as it is, in Emerald’s folder, named for what it comes before (`work.before-20261006T120512-cleanup.emd`), and says where. A read or batch of 100+ rows keeps one by itself; ask before anything else worth undoing. The last 3 are kept, apart from the rolling copies.
| Name | Type | Req | Description |
|---|---|---|---|
| before | string | – | What it comes before, in a few words: `the cleanup`. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
keep_packs Keep packs in a document ~223
Keep packs in an existing document (the Packs screen’s *Keep … here*): declares the pack’s formats it lacks, adds missing optional columns to those it holds, renames a column the pack renamed with its values, changes no row; a pack kept already is brought up to date this way, its formats’ and columns’ notes and views’ settings too wherever the document still holds an earlier build’s — one a person changed is kept, and the dry run names it. Refused, naming the column, where a format of the same name is not the pack’s. Dry run until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Keep them. Omit or false for the dry run. |
| packs | array | yes | The packs to keep, by id. One of: `development` (a project’s memory: milestones, units, decisions, open questions, an inbox), `ledger` (personal finance, from statements, paychecks and fund reports). |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
land_units Land units ~333
In a document that keeps the `development` pack: a unit’s closing pass in one call, for a list of units by `ref`: their new `decisions` (date, milestone, scope and `state: live` default to the unit’s), the unit to `built` with `landed` (default today), `files` and `decision` (default its first new one), its `review_entries` (`state: open` default), `close_milestone`, its git `commit` (refused without one unless `same_commit: true`) and `branch` (another than the claim’s refused unless `other_branch`), and the `report` of the session that built it. Or `inbox`: ids of a child’s proposals — an inbox row, `state: new`, `refs` its unit, its `body` one ```json block of one unit’s landing (no `close_milestone`), written to the document path the hooks printed — each landed as written and moved to `applied`. Each step is `record_format_rows` or `update_format_rows`, judged as they are, run in that order; all of it applies or none. Diff by format; writes nothing until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Write it. Omit or false for the dry run. |
| inbox | array | – | Inbox row ids of landing proposals, or `{id, other_branch}`. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| units | array | – | Up to 50. |
No output schema declared.
No examples provided.
month_summary Month summary ~123
One month already added up: income, expenses, balance, savings rate; how each compares with last month, the three-month average and the same month last year; the category breakdown rolled up to parents; the fixed-versus-variable split; and where the income came from. Defaults to the current month. Every figure comes from the same call the app own Insights screen makes, so they cannot disagree.
| Name | Type | Req | Description |
|---|---|---|---|
| month | string | – | The month as YYYY-MM. Defaults to the current month. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
note_merchant_suggestions Note what was suggested about merchants ~123
Remember what this conversation suggested for merchants that were **not** categorized — a category the user declined, or a name nobody could identify — so the next conversation does not ask about the same names again. Shown in the Asked about column of uncategorized_merchants, cleared automatically when a merchant is categorized. Writes immediately: it changes no transaction, no category and no rule.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | Absolute path to a .emd file on this machine. |
| suggestions | array | yes | One entry per merchant. Up to 200 in a call. |
No output schema declared.
No examples provided.
pause_goals Pause goals ~163
Pause goals for a number of months, or start them again, **several in one call**. A paused goal is skipped by the projection and gives its monthly amount back to what is left in Plan for those months; it is not deleted and keeps its history. `months` counts this month: 1 skips this month only. 0 starts the goal again. Plan's own bucket is left alone. **Dry-runs by default**; the document is copied to a timestamped .bak first.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews; true writes. |
| goals | array | yes | One entry per goal. Up to 60 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
paychecks Paychecks ~169
Every paycheck recorded in the document — gross, net, the employer’s own contributions, total compensation, the effective tax rate, what payroll put away, and whether each itemization reconciles to its net. Plus the salary months with no paycheck at all, per-year totals, and **the deduction-type vocabulary with its ids**, which is what a line of a new paycheck has to name. Reads the document; changes nothing.
| Name | Type | Req | Description |
|---|---|---|---|
| include_lines | boolean | – | Also print each listed paycheck’s itemization, line by line. Default false. |
| limit | number | – | How many paychecks to list, newest salary month first. Default 24, maximum 500. The yearly totals and the vocabulary are never capped. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
plan_month Work a plan out for a month, and use it ~338
One plan worked out for one month: net pay, the bills out of net, what is left to split, each bucket’s amount and share, what it actually got lately, when a goal is reached at this rate, money with no job to do — and what *using* the plan for that month would write (a planned deposit into a goal, a planned payment on a debt). **Dry-runs by default**, which is also how you read it; `commit: true` writes those suggestions and gives the month this plan. `months` instead gives a list of months this plan and writes nothing else, and `back_to_default` puts months of this plan back on the default — the Plan screen’s month checkboxes. A month nobody gave a plan is on the default. `only_buckets` writes just those buckets’ suggestions. A fund or an account is pointed at and writes nothing. The document is copied to a timestamped .bak first.
| Name | Type | Req | Description |
|---|---|---|---|
| back_to_default | array | – | Months as YYYY-MM of this plan to put back on the default plan. |
| commit | boolean | – | Default false. False shows the month and writes nothing; true uses the plan. |
| month | string | – | The month as YYYY-MM. Default this month. |
| months | array | – | Months as YYYY-MM to give this plan. Records nothing. |
| only_buckets | array | – | Bucket ids from `plans`. Default: all. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| plan_id | string | – | Ids come from `plans`. Default: the default plan. |
No output schema declared.
No examples provided.
plans Plans: bill choices and buckets ~135
The Plan screen as rows: each plan with what every bill does to it (out of net, part of the split, or ignored) and its buckets — what each is for (a goal, a debt, a category, a fund, an account or nothing) and how it is sized. Ids are here for `set_plan`, `set_fixed_expense_roles` and `edit_fixed_expenses`. The worked-out figures for a month are `plan_month`.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | yes | Absolute path to a .emd file on this machine. |
| plan_id | string | – | One plan. Default: all of them. |
No output schema declared.
No examples provided.
read_onto_format Read a file onto a declared format ~1,100
Read what the user already keeps onto a declared format: any .csv, .xlsx (or .xls) or .json of rows, a file row per table row; or **a folder of Markdown notes**, a note per row: `title`, `file`, each frontmatter key, `inline tags`, `body links` and `body`, with a link read from `[[name]]` or `[text](file.md)`; a body link naming no row is left out and named, the note still read; a hidden file is not read; links between notes of one folder are filled; `items` reads list items or table rows onto another format, each linked to its note. **Dry-runs by default**: the reader with each key’s header cell and first value, the rows as stored, the rows that would not type and why, and **what the format claims, checked before a row exists**. Writes on `commit: true`. Keys come from `formats`. **The user maps the columns; this only guesses** — show the reader, correct it with `columns`. `fixed` gives a key one value for the file (a currency, a unit, the row every line belongs to). A column fills a `link` only by the exact unique name of its row, and a line naming none is refused; a link is guessed only from a header that names it. `header` writes the file’s total, period or card as one row of another format that every line links to. **A source read again updates its rows** by note file name, and any file by a unique column (so a later export updates what an earlier one wrote): changed, added and gone named; gone kept unless `remove_gone`. `supersede_reading` takes a reading back. **Several files in one call**: `files`, each `{ file, format }` with its own columns — read in the order their links need, so a line names a row from a file above it; one dry run for the lot, written whole or not at all.
| Name | Type | Req | Description |
|---|---|---|---|
| columns | object | – | Column number → key of the format, from what the user confirmed, or → null to read nothing from that column. Applied over the reader the dry run showed, so send only what changes; a column not named… |
| commit | boolean | – | Write it. Omit or false for the dry run. |
| date_order | string | – | How a written date is ordered: one of dmy, mdy, ymd. Inferred from the file when omitted. |
| file | string | – | Absolute path to the file to read: one of .xlsx, .xls, .csv, a .json file of rows (an array of objects, or an object holding one), a Markdown note (.md), or **a folder of notes** — every .md file in… |
| files | array | – | Instead of `format` and `file`: each `{ file, format }`, plus that file’s own columns. |
| fixed | object | – | Key → one value for every row of this file. A currency for a `money` column, a unit for a `quantity` one, or the row a `link` points at, by id or unique name. |
| format | string | – | The declared format to read onto, by name. Not with `files`. |
| header | object | – | `{ format, link, cells, fixed }`: the one row of another format this file writes and every line links to through `link`. `cells` is key → [row, column], **a position, never a value**, from 0; a negat… |
| header_row | number | – | Force the header row, from 0, when the guess is wrong — exports often have a preamble. |
| items | string | – | "list" or "table": a folder’s list items or table rows as rows of `format`, each linked to its note’s row (read the notes in the same `files`, or before). |
| path | string | yes | Absolute path to a .emd file on this machine. |
| recursive | boolean | – | A folder of notes: its subfolders’ notes too (not a hidden one), with a `folder` column, the path under it. |
| remove_gone | boolean | – | Read again: remove rows whose line is gone (else named, kept). Per file in `files`. |
| separators | object | – | Key → what splits one cell into several members, for a column holding several of a list (`enums`): `{ "tags": "," }` reads `vegan, quick` as two. Never guessed; without one a cell is one member, and… |
| sheet | string | – | Which sheet, or key of a .json object; defaults to the first. |
| under | string | – | With `items`: only those under this heading. |
No output schema declared.
No examples provided.
readers A format’s readers ~124
List a declared format’s readers — one per kind of file it has read — or name and forget them. Dry-runs until `commit: true`. Forgetting takes back no row.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Do it. Omit or false for the dry run. |
| forget | array | – | Reader ids. |
| format | string | yes | The format, by name. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| rename | array | – | `{ reader, name }`, by id; an empty name restores the file’s. |
No output schema declared.
No examples provided.
record_debt_payments Record debt payments ~161
Record payments against a debt — **several in one call**. The amount is a magnitude; the direction is known. A payment is **all principal** unless it names an interest portion, because v1 has no amortization schedule. Paying more than is outstanding is allowed and is flagged. **Dry-runs by default**; the document is copied to a timestamped .bak first. Payments the app discovered at import are a separate thing and are confirmed in the app.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews the batch; true writes it. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| payments | array | yes | One entry per payment. Up to 60 in a call. |
No output schema declared.
No examples provided.
record_deposits Record savings movements ~231
Record money moving in a goal — **several in one call**. Six modes: DEPOSIT, WITHDRAWAL, TRANSFER between holdings, OPENING for what was already there when tracking started, and GAIN / LOSS for what the market did. **The mode carries the direction; the amount is always positive.** OPENING, GAIN and LOSS are in the balance but are not money the user set aside, so they are kept out of the savings rate. **Dry-runs by default**; the document is copied to a timestamped .bak first. Editing and deleting a movement are app-only. A DEPOSIT here is money **set aside** by hand, still inside the bank; deposits **read from the bank** come from the Money moved category a goal reads (`set_goal_deposit_categories`).
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Default false. False previews the batch; true writes it. |
| deposits | array | yes | One entry per movement. Up to 60 in a call. |
| path | string | yes | Absolute path to a .emd file on this machine. |
No output schema declared.
No examples provided.
record_format_rows Record rows of a declared format ~348
Write rows into a declared format — **a list of them in one call**. The columns belong to the document — `start_here` lists them, `formats` in full — and a key the format has not got refuses the batch rather than being dropped, because a figure you believe you stored and did not is worse than one you know is missing. A `money` column takes the amount in major units beside its own `<column>_currency` key, and a `quantity` column takes the figure beside a `<column>_unit` key naming a unit this document knows — `amount: 200` with `amount_unit: ml`. A `link` takes the row’s id, its name (first text column) when one row has it — `recipe: "Pancakes"` — or columns that find one: `{name: "Salt", brand: "Fine"}`, or one unique column alone: `course: {notion_id: "a1b2"}`; a row may name another of the same batch. Types, bounds and enum members are checked before anything is written and the whole batch applies or none of it does. Returns the diff and writes nothing until `commit: true`.
| Name | Type | Req | Description |
|---|---|---|---|
| commit | boolean | – | Write it. Omit or false for the dry run. |
| format | string | yes | The declared format, by name. |
| path | string | yes | Absolute path to a .emd file on this machine. |
| rows | array | yes | One object per row, keyed by declared column name. Up to 200 in a call. |
| view | string | – | An input view: its defaults fill left-out fields. |
No output schema declared.
No examples provided.
How do I install the Emerald MCP server?
Emerald runs locally as an npm package, launched with npx -y emerald-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · emerald-mcp
claude mcp add kfireliyahu-emerald -- npx -y emerald-mcp
What is the Emerald MCP server?
Emerald is an MCP server listed in the public MCP registry as io.github.kfireliyahu/emerald. The database under the chat: a local SQLite file a model asks for rows, not notes to re-read. This page covers its npm package (emerald-mcp).
Is the Emerald MCP server safe to use?
Emerald scores 71 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 4 November 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Emerald MCP server expose?
Emerald exposes 85 tools: formats, declare_format, connect_formats, extend_format, delete_format, and 80 more. Their descriptions and schemas cost roughly 22,653 tokens of context every time the server is loaded.
Is the Emerald MCP server still maintained?
Emerald is still listed as active in the MCP registry. We last reached this channel on 4 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the Emerald MCP server under?
Emerald declares the AGPL-3.0-only licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.