mcp-office-suite
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-office-suite Start a timer for the client presentation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Office Suite
MCP server for small business accounting and paperwork: invoices, PDFs, spreadsheets, Word documents, time tracking and expenses. One local config entry for invoicing, documents, time tracking and supplier checks.
Works with Claude Desktop, Claude Code, Cursor and any Model Context Protocol client. Runs on your own machine: this one has no hosted endpoint, so install it from the bundle or from source.
Product page: https://mcp.zovo.one/s/office-suite - capabilities, free limits and supported installation paths.
Install
Claude Desktop, one click. Download office-suite.mcpb from the bundle catalog and double-click it.
From source. The mirror is self-contained: every @theluckystrike/* dependency is vendored, so a fresh clone builds with no extra setup.
git clone https://github.com/theluckystrike/mcp-office-suite.git
cd mcp-office-suite
npm install && npm run buildThen point your client at the built entry point:
{
"mcpServers": {
"office-suite": {
"command": "node",
"args": ["/absolute/path/to/mcp-office-suite/dist/index.js"]
}
}
}
@theluckystrike/mcp-office-suiteis not published on npm yet, so annpx -y @theluckystrike/mcp-office-suitecommand will fail. The three paths above are the working ones and each is exercised by CI.

Read-only mirror of mcp-servers/servers/office-suite. See MIRROR.md.
Run the freelancer office from one MCP config entry. The v0.25.0 bundle initializes 50 local child servers and exposes 453 tools, measured over MCP on 2026-10-26. It includes time tracking, invoices, spreadsheets, quotes, expenses and the supplier-invoice three-way matcher duplicate invoice candidate review, and supplier statement open-item checks against AP ledger exports. The proxy forwards tools, resources and prompts to the child that owns them; each child keeps its own storage and free tier.
Built by theluckystrike. MIT. Support: support@zovo.one.
Related MCP server: Multi MCP
Install
For Claude Desktop, download office-suite.mcpb v0.25.0 and open it. Verify it using the release's SHA256SUMS.txt.
The download catalog lists explicit archive versions. The latest GitHub release is not a complete collection of all server bundles. This proxy is local stdio only; it has no hosted endpoint. Its npm package and internal dependencies are not published, so use the bundle or build from source.
Source installation requires Node.js 22 or newer for the current repository build tooling:
git clone https://github.com/theluckystrike/mcp-servers.git
cd mcp-servers
npm install
npm run buildThe root build bootstraps the license/timezone engine dependency and builds the child servers. Use your checkout's absolute path in the config. For Claude Desktop, merge this entry into mcpServers in its config file:
{
"mcpServers": {
"office-suite": {
"command": "node",
"args": ["/absolute/path/mcp-servers/servers/office-suite/dist/index.js"]
}
}
}For Cursor, merge the same entry into .cursor/mcp.json or your user MCP config. For Claude Code:
claude mcp add office-suite -- node /absolute/path/mcp-servers/servers/office-suite/dist/index.jsRestart the client, call license_status, and read office://tools_map to discover the children and exact exposed tool names. A successful tools list confirms discovery; run a real task to verify the workflow you need.
Tools and collision names
Entry | Behavior |
Child tools | The child's own tools, arguments and free/Pro rules. |
| Per-child license state and the bundle checkout URL. |
| Forwards a key to every connected child and reports every result. |
| Maps exposed tool names to their child and original name. |
When child names collide, the proxy exposes names prefixed with the child, such as invoice_business_set. Child result payloads, including JSON source records, raw CSV, HTML and prose, retain their original values. Each forwarded result adds collision mappings under _meta["office-suite/tool-names"] and points to office://tools_map; explicit retrieval tool hints in matcher report envelopes use the exposed names. Read the runtime map rather than guessing a prefix or relying on an older static tool table.
The v0.25.0 manifest's 453 names and descriptions match the actual running bundle, including collision prefixes. Measured inventory and artifact evidence are available. This verifies discovery and matcher delivery through the proxy; it is not a feature test of every child tool.
Supplier statement review and tool names
The new supplier_statement_check compares two supplied open-item exports by exact entity, supplier, currency, document type and reference. It retains both source lists and reports missing items, amount/date differences and ambiguous repeated references. It does not reconcile balances, allocate payments, extract PDFs or approve payment. Full diagnostics and CSV are free; the supplier server's Pro upgrade removes only its saved-report count cap.
Its report helpers are named supplier-statement-check_report_get, supplier-statement-check_report_page, supplier-statement-check_report_export_csv, supplier-statement-check_report_list and supplier-statement-check_report_delete. Explicit retrieval hints use those names. Original references and CSV cells remain unchanged even when they contain a tool name.
The v0.25.0 inventory retains every exposed tool name from the prior published v0.22.9 bundle and adds six supplier tools. Use office://tools_map for the authoritative map; no bare report_get alias is added.
Free and Pro
Free | Pro bundle |
Each child's documented free tier; no subscription required | $39 one time, removes the applicable limits across the children |
Get the $39 bundle, then call license_activate with the bundle key or set MCP_LICENSE_KEY in the server environment. Keys verify offline. A $19 single-server key upgrades its own product; it does not unlock the whole suite.
Activation returns an error if any connected child rejects the key, with an OK/FAILED result for each child. Accepted activations are not rolled back: use the result table and license_status, correct the key or failing child, and retry. Do not interpret a partial activation as all children being Pro.
Local execution and privacy
Every child runs as its own stdio process and stores its documents under its own data directory, normally ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/<name>/. The proxy adds no document store. Individual tools may make public network requests, for example price, currency or backlink checks; read the relevant child's documentation. Your AI client or model provider has its own data handling.
Child stderr is drained into the proxy's stderr with the child name. An unexpected child exit rejects pending requests and gets one restart attempt; an interrupted mutation must be checked before retrying it.
Available Tools
129 toolsalerts_pendingPending alertsA
Answer whether anything you watch got cheaper: every watch at or below its target_price, or down 5% or more since the previous observation, with the change %. Reads stored data only: run watch_refresh first.
Inputs: no named parameters.
business_daysCount business daysA
Count business days between two dates in a place, inclusive, with the calendar total and the weekend and holiday counts. It has NO holiday calendar: without holidays, only weekends are excluded.
Inputs: to (required), from (required), zone (required), holidays.
cache_statusRate cache statusARead-onlyIdempotent
Report the ECB rate cache here: which dates are held, how old they are and when they refresh. Reads only. Check it before trusting a rate after time offline; a cache that no longer parses is quarantined and named.
Inputs: no named parameters.
calendars_listList imported calendarsARead-onlyIdempotent
List imported calendars: name, event-definition count, size, source, import time and free-tier use of the 2 slots. It also names stored .ics files with no calendar row. With none it prints the export steps.
Inputs: no named parameters.
clause_addAdd a clauseA
Save a reusable contract or proposal clause to the library. Returns the stored clause id, title, category, tags and the variables detected in its body, plus how many clauses of your own the library now holds.
Inputs: body (required), title (required), category (required), tags, +3 more.
clause_deleteDelete a clauseADestructive
Delete one clause by id or exact title and report how many are left. There is no undo, and a deleted starter clause is not re-seeded. Use clause_update to change one you want to keep.
Inputs: id (required).
clause_exportExport clausesARead-onlyIdempotent
Call this tool to write the whole library to one file and return the path, format and count. It is written in contract order, so it re-imports the same way. markdown is free; json is Pro.
Inputs: path (required), format (required), overwrite.
clause_getRead one clauseARead-onlyIdempotent
Return one clause in full by id or title: body, category, tags, jurisdiction, variables and the revision count, which stays 0 on free. A partial title matching several is refused with the candidates.
Inputs: id, title.
clause_importImport clausesA
Call this tool to load clauses from a .md or .json file, reporting added, replaced, skipped and capped counts. A duplicate title is skipped unless overwrite. json is Pro. Free: 10 of your own.
Inputs: path (required), overwrite.
clause_listList clausesARead-onlyIdempotent
List the library as id, title, category, tags and variables, in contract order by category then title, which is the order contract_assemble uses. Narrow with category; use clause_search for words.
Inputs: category.
clause_searchSearch clausesARead-onlyIdempotent
Ranked search over clause titles, tags, categories and bodies. Title and tag matches outrank body matches. Jurisdiction filtering is free; the tag filter is Pro and is skipped rather than refusing the search.
Inputs: query (required), tags, category, jurisdiction.
clause_updateUpdate a clauseA
Change the text, category, tags, variables or jurisdiction of a clause. In Pro the previous text is kept as a version; in the free tier the change is applied without history.
Inputs: id (required), body, tags, title, +4 more.
client_addAdd a clientA
Store a client so invoice_create can refer to them by name. Re-adding the same name updates the stored address, email and VAT id; a record identical to a stored one is refused, naming the id that already holds it.
Inputs: name (required), email, vat_id, address.
client_deleteDelete a clientADestructive
Delete one stored client that nothing refers to. A client named on any invoice, quote, credit note, purchase order, deposit, statement or schedule is refused with those documents listed.
Inputs: client (required).
client_listList clientsARead-onlyIdempotent
List every stored client with id, address, email and VAT id. No arguments, and it writes nothing. With none stored it says so: invoice_create also creates a client from the name you pass.
Inputs: no named parameters.
conflictsFind double bookingsA
Find double bookings: every PAIR of timed events that overlap, with the minutes they collide, across all calendars unless you name one. Whole-day events are reported apart. Free: 31 days. free_busy shows gaps.
Inputs: to (required), from (required), calendar.
contacts_listList saved contactsARead-onlyIdempotent
List saved contacts with their zone, local time now, working hours and whether they are inside them; weekends count as outside. It also prints YOUR zone from the shared business profile.
Inputs: no named parameters.
contacts_setSave a contact's zoneA
Save one person's zone and working hours so later calls can name them. Returns the resolved zone and their local time now. Saving the same name REPLACES that contact and says so. Free: 5 contacts.
Inputs: name (required), zone (required), work_end, work_start.
contract_assembleAssemble a contractA
Call this tool to build a contract from library clauses as .docx or markdown. A variable you omit stays as a bracketed prompt, never invented. clause_ids order is document order. Free: 8 clauses.
Inputs: title (required), client, format, values, +4 more.
contract_createCreate a service agreementA
Call this tool to produce a freelance service agreement .docx. Returns the reference, the fee and the file path. It is a template skeleton for a lawyer to review, not legal advice. Free tier: 3 agreements per month.
Inputs: fee (required), client (required), services (required), start_date (required), +5 more.
convertConvert an amountA
Call this tool to convert an amount between any two ECB-quoted currencies, today or on a past date. Returns the converted amount, the cross rate to 6 decimals, the rounding applied and the rate date used.
Inputs: from (required), amount (required), to, date.
convert_manyConvert one amount into several currenciesA
Convert one amount into many currencies off the SAME ECB rate date, each rounded to its own minor units. For several lines at once (mixed-currency invoice lines), call it once per line: every line then shares one rate date. Unknown targets are listed, never failed.
Inputs: to (required), from (required), amount (required).
convert_timeConvert a time between zonesA
Convert one time from from_zone into every zone in to_zones, marking any day change, plus the UTC instant. The time is wall-clock in from_zone unless it carries an offset or a trailing Z. '3pm tomorrow' works.
Inputs: time (required), to_zones (required), from_zone (required), gap, +1 more.
cover_letter_createWrite a cover letter .docxA
Call this tool to write a one-page cover letter .docx from the stored profile and return the path, word count and bracketed prompts. Nothing from the posting is restated as yours. Free: 3 a month.
Inputs: role (required), company (required), tone, out_path, +4 more.
currencies_listCurrencies the ECB quotesARead-onlyIdempotent
Every currency in the ECB daily set with its rate against the euro and its decimal places. This is the whole domain: a code not on this list cannot be converted, quoted or historised here.
Inputs: no named parameters.
doc_createCreate a Word documentA
Call this tool to write a real .docx file from structured sections. Returns the file path, the number of blocks written and the layout used. Free and unlimited.
Inputs: title (required), sections (required), date, style, +3 more.
doc_fill_templateFill a Word templateA
Call this tool to replace {{placeholders}} in a .docx and write a new file, reporting what was filled, unfilled or ignored. Call it with no values to list them. Free: templates up to 10 placeholders.
Inputs: template_path (required), values, out_path, overwrite.
doc_from_markdownMarkdown to WordA
Call this tool to turn markdown into a .docx, returning the file and a count of blocks by type. Headings, lists, GFM tables and code fences are honoured. Empty markdown is refused, and so is overwriting without the flag.
Inputs: markdown (required), style, title, out_path, +1 more.
doc_readRead a Word documentBRead-onlyIdempotent
Call this tool to extract the text of an existing .docx. Returns an outline of the headings and the full text in document order, or the block structure. Free and unlimited.
Inputs: path (required), format.
doc_to_htmlWord document to HTMLA
Call this tool to convert a .docx to semantic HTML you can open in a browser and print to PDF. Returns the path of the .html file. This is the supported PDF route; no PDF is rendered here. Free and unlimited.
Inputs: path (required), out_path, overwrite.
docx_business_setSet your business detailsA
Store the sender details printed on every proposal, contract and letter, plus the currency, VAT, terms and prefix defaults. It writes the SAME shared profile as the invoice server's business_set.
Inputs: name (required), vat, bank, iban, +13 more.
dst_changesDaylight-saving changesA
The clock changes in a place for a year, with the exact UTC instant and the offset before and after. Use it to check whether a recurring call moves for one of you in March or October.
Inputs: zone (required), year.
duplicate_invoice_checkReview duplicate invoice candidatesB
Group up to 1000 supplied records by exact/normalized reference or exact amount/date within exact entity, supplier, type and currency. All evidence is free. Candidates require review; no payment approval.
Inputs: records (required), save.
entry_addAdd time entryA
Log time already worked as one entry and return its id, duration and amount. Give start plus end or minutes. rate is hourly in MAJOR units and is frozen on the entry, so a later rate change never moves it.
Inputs: start (required), project (required), end, note, +6 more.
entry_deleteDelete time entryADestructive
Delete one logged entry by id and report the project and hours removed. It never touches a running timer. A billed entry goes too, losing the invoice record, so correct one with entry_edit instead.
Inputs: id (required).
entry_editEdit time entryA
Change one logged entry by id; only the fields you pass move. minutes keeps start and moves end, an end at or before start is refused, tags REPLACES the list, and rate is hourly in MAJOR units.
Inputs: id (required), end, note, rate, +7 more.
entry_listList time entriesARead-onlyIdempotent
List logged entries as a table of id, day, start, project, task, hours, billable, tags and note, newest first, with total hours. Free reads the last 7 days and says so; Pro reads the whole history.
Inputs: to, from, limit, project.
entry_logLog work timeA
Log work time for a client/project in one step: minutes worked plus an optional note. The entry starts now minus the minutes, so it lands on today's day and week summaries.
Inputs: client (required), minutes (required), note, project.
entry_mark_billedMark time entries as billedA
Close the loop after an invoice is issued: stamp the tracked hours that went on it with the invoice number, so report and invoice_summary stop offering them and the same hours are never billed twice.
Inputs: invoice_number (required), to, ids, from, +2 more.
event_exportExport events to a .ics fileARead-onlyIdempotent
Call this tool to write chosen events to a new .ics file you can send or import elsewhere. Pass either ids (from events_list) or a from/to window. Times are written in UTC so the file lands correctly in any client.
Inputs: out_path (required), to, ids, from, +1 more.
events_listList events in a windowARead-onlyIdempotent
Every event between two dates, recurring expanded to occurrences, sorted by start. Times shown in your zone (profile's, else this machine's) unless zone passed. Each id works for event_export or event_to_time_entry.
Inputs: to (required), from (required), zone, calendar.
events_searchSearch eventsARead-onlyIdempotent
Find events whose title, description, location or attendees contain a phrase. Searches every imported calendar. Without from/to it looks a year back and a year forward on Pro, and the free window either side of today.
Inputs: query (required), to, from.
event_to_time_entryTurn a meeting into a time entryB
Take one event and return the exact arguments for the time-tracker's entry_add, so a meeting that already happened becomes billable time without retyping it. Writes nothing: pass the JSON straight to entry_add.
Inputs: project (required), event_id (required), rate, currency.
export_csvExport entries to CSVA
Call this tool to export the timesheet to a CSV file (excel-friendly) you can hand to a bookkeeper: one row per entry with hours, billable, rate, currency and amount. Returns the file path written.
Inputs: to, from, path, project.
find_meeting_slotsFind meeting slotsA
Rank the times when every participant is inside their own working hours. Returns each slot as a UTC instant with the local time for every participant and a fairness score, best first.
Inputs: participants (required), days, limit, recurring, +2 more.
forecastRevenue forecastA
Expected invoiced revenue per calendar month per currency from active schedules. Invoiced and skipped periods are excluded and paused schedules listed apart. Free: 3 months; Pro: up to 120.
Inputs: months.
free_busyBusy blocks and free windowsA
Merged busy blocks and the free gaps inside your working hours over a day range. Events marked free do not count; whole-day events block the day. Free: 31 days. Use conflicts for overlapping pairs.
Inputs: to (required), from (required), zone, work_end, +2 more.
fx_rates_forFX rates in the shape expense-tracker wantsA
Call this tool when a rebill or an invoice spans more than one currency, instead of asking the user for rates. Returns the fx_rates object expense_to_invoice takes, plus the rate date to write on the invoice.
Inputs: currencies (required), target.
ics_createWrite a calendar inviteA
Call this tool to write a .ics for one meeting and return the path plus the start in UTC and in your zone. Times are stored in UTC so it lands correctly in any client. Free: 3 files a month.
Inputs: zone (required), start (required), title (required), duration_minutes (required), +8 more.
ics_forgetForget a calendarA
Remove one imported calendar by name and delete this server's local copy of its .ics, freeing a slot. Your own calendar and the source file are untouched. ics_import replaces a name in place.
Inputs: name (required).
ics_importImport a calendar (.ics)A
Call this tool to read a calendar export and keep it under a name. Give path (.ics file), text (contents), or url (public .ics/webcal feed; Pro). Google, Apple, Outlook exports read. Re-importing a name replaces it.
Inputs: name (required), url, path, text.
invoice_business_setSet your business detailsA
The ONE business profile for the whole suite: name, address, VAT id, bank details and defaults (currency, tax rate, terms, prefix, timezone). Saved to the shared profile every other server reads. Call it once, first.
Inputs: name (required), vat, bank, iban, +12 more.
invoice_createCreate an invoiceA
Create an invoice from line items and return the record with its next, never-reused number. unit_price is in MAJOR units; lines are rounded then summed. One currency per invoice. Free: 3 a month.
Inputs: items (required), client (required), notes, currency, +3 more.
invoice_from_hoursInvoice from hoursA
Shortcut for the common case: bill one client for N hours at an hourly rate. Creates and returns a single-line invoice, converting the rate into target_currency when you supply fx_rates, and echoing back any entry_ids.
Inputs: rate (required), hours (required), client (required), notes, +10 more.
invoice_generate_dueGenerate the invoices that are dueA
Create a real invoice in the invoice server for every schedule occurrence on or before as_of that has not been invoiced yet, and render each PDF. Returns what was created, what was skipped and what is still due.
Inputs: as_of, dry_run, schedule_id.
invoice_getGet one invoiceARead-onlyIdempotent
Return the full stored record for one invoice number, including every line, tax breakdown, and the balance still open after any credit note issued against it (see credited_minor).
Inputs: number (required).
invoice_listList invoicesARead-onlyIdempotent
List invoices by number: client, dates, currency, subtotal, discount, tax lines, total, status, paid, credited and the balance still due after any credit note. Filter by status, client and date range.
Inputs: to, from, client, status.
invoice_mark_paidMark an invoice paidA
Record a payment on one invoice. amount is in MAJOR units and ADDS to what is paid, never replaces it; omit it to settle the rest. An overpayment is refused, naming the open balance.
Inputs: number (required), amount, method, paid_date, +1 more.
invoice_pdfRender invoice PDFARead-onlyIdempotent
Call this tool to write one stored invoice as an A4 PDF and return the path: issuer, BILL TO, dates, items, taxes and totals. Free stamps a credit line and no logo; Pro renders it unbranded with your logo.
Inputs: number (required), out_path.
invoice_summaryInvoice summaryARead-onlyIdempotent
Turn tracked billable time into invoice lines for one project: hours, hourly rate, amount per task and the total, one line per rate so two rates never average. Hours already marked billed are left out. Free: last 7 days.
Inputs: to (required), from (required), project (required), unbilled_only.
license_activateA
Activate one Pro key on every connected server in a single call and return which accepted it. Any rejection fails the whole call, because one server on Pro and another free is invisible to the user.
Inputs: key (required).
license_statusA
Report the licence tier of every server connected to this bundle, one row each, plus the single checkout URL that upgrades them all. A server that failed to start is reported with its error.
Inputs: no named parameters.
next_eventNext eventA
The first event not yet started, within the next 366 days, across every imported calendar or one you name. Returns title, times in your zone, how long until it starts, location, attendees and its id.
Inputs: calendar.
nowCurrent time in zonesA
The current time in one or more places, each with the zone it resolved to and the local date, time and offset, under one UTC instant. Accepts IANA zones, cities, countries and abbreviations.
Inputs: zones.
overdue_reportOverdue reportARead-onlyIdempotent
List every invoice not paid in full whose due date has passed, worst first, with days overdue and the amount, then a total per currency. Free. Use invoice_list for everything still open.
Inputs: as_of.
overlapDaily working-hours overlapB
The window each day when every listed place is inside working hours. Computed on a real date, so a DST week that widens or narrows the overlap is reflected.
Inputs: zones (required), date, work_end, work_start.
pdf_countCount pages in several PDFsB
Page count per file plus the total, for any number of PDFs, with how many were readable. A file that cannot be read is reported on its own row and the others still count. Read-only. Free and unlimited.
Inputs: paths (required).
pdf_infoInspect a PDFB
Call this tool to inspect a PDF: page count, page sizes in points/mm, paper name, metadata (title, author, producer, dates) and whether it is encrypted. Read-only, never modifies the file. Free tier: unlimited.
Inputs: path (required).
pdf_mergeMerge PDFs into one fileA
Call this tool to join several PDFs into one, in the order given. Page sizes are kept as-is, so a merged file may have mixed sizes, and the answer says so. Inputs are never modified. Free tier: up to 5 files per merge.
Inputs: paths (required), out_path (required), overwrite.
pdf_pagesExtract pages into a new PDFA
Call this tool to pull selected pages into one new PDF, in the order written: "2,4-6" gives four pages. Asking for a page twice copies it twice. The input is never modified. Free tier: files up to 30 pages.
Inputs: path (required), pages (required), out_path (required), overwrite.
pdf_reorderReorder the pages of a PDFA
Call this tool to write a new PDF with pages in the order you give. The order must name every page exactly once, so nothing drops by accident; use pdf_pages for a subset. Pro.
Inputs: path (required), order (required), out_path (required), overwrite.
pdf_rotateRotate pagesA
Call this tool to turn pages by a multiple of 90 degrees, clockwise for positive. Rotation is added to whatever the page already had, for a sideways scan. Writes a new file. Free tier: files up to 30 pages.
Inputs: path (required), degrees (required), out_path (required), pages, +1 more.
pdf_splitSplit a PDF into several filesA
Call this tool to write one new PDF per range. Ranges are 1-based and may be open-ended: "1-3,5,7-" gives pages 1-3, page 5, and 7 to the end. The input is never modified. Free tier: files up to 30 pages.
Inputs: path (required), ranges (required), out_path_pattern (required), overwrite.
pdf_stampStamp text on a PDFA
Call this tool to draw a word such as PAID or DRAFT across the pages, in a colour and position you choose. Writes a new file; input untouched. Free tier: the PAID and DRAFT presets in their preset colours.
Inputs: path (required), text (required), out_path (required), color, +5 more.
pdf_textRead the text of a PDFARead-onlyIdempotent
Call this tool for best-effort text extraction from standard-font PDFs. Returns nothing for a scan (no OCR), or glyph indices for a custom-encoded font, and says which case applies. Read-only. Free tier: unlimited.
Inputs: path (required), pages.
pdf_watermark_businessStamp your business details in the footerB
Call this tool to put your business name and VAT id in the footer of every page, from the shared profile mcp-invoice and mcp-docx write. Use it before sending a document out. Pro.
Inputs: path (required), out_path (required), pages, overwrite.
price_add_manualRecord a price by handA
Call this tool to store a price you read yourself where a shop blocks fetching: it creates the watch if new and returns the amount and the observation count. An unreadable price is refused. Free: 3 watches.
Inputs: url (required), price (required), label, currency.
price_checkCheck a price nowARead-onlyIdempotent
Call this tool for any product URL; fetching the page with a generic web tool returns raw HTML without the price. Reports price, currency, title and confidence, and the change since the last check. It creates no watch.
Inputs: url (required).
price_historyPrice historyA
Call this tool to list one watch's stored observations, oldest to newest, each with price, currency, source and confidence, plus min and max. Nothing is fetched. Free shows the last 30.
Inputs: id, url, limit.
profile_getShow the stored profileARead-onlyIdempotent
Return the stored CV profile exactly as resume_create, cover_letter_create and tailor_to_job will use it, plus the variant read and every stored variant name. Call it before any rewrite.
Inputs: variant.
profile_setStore your CV factsA
Store the profile every resume and cover letter is built from: contact details, summary, skills, roles with bullets, education, certifications and languages. Returns a count of what was stored.
Inputs: name, email, links, merge, +11 more.
project_set_rateSet project rateA
Set the hourly rate and currency used to turn tracked hours into money for a project or client. Returns the new rate and, when re-rating is asked for, how many already logged entries changed.
Inputs: project (required), hourly_rate (required), currency, only_missing, +1 more.
proposal_createCreate a proposalA
Call this tool to produce a client-ready .docx proposal from summary, scope, deliverables, timeline, price and terms. Returns the reference, the total and the file path. Free tier: 3 proposals or contracts per month.
Inputs: price (required), client (required), project_title (required), scope, +6 more.
proposal_updateUpdate a proposalA
Rewrite an existing proposal in place from its reference. Only the fields you pass change; the rest comes from the data stored at creation. Returns the fields that changed and the file path.
Inputs: reference (required), price, scope, client, +5 more.
rate_historyRate history for a pairA
Call this tool for the ECB rate of one currency pair across a window. Returns one row per published day plus the min, max, average and the change. A window wider than the free 90 days is shortened, not refused.
Inputs: to (required), from (required), days, to_date, +2 more.
rate_onRate on a given dateA
Call this tool for the ECB rate of one pair on one date. Returns both directions and the rate date, so a reciprocal is never reported as the published figure. A date beyond the free window is shortened, never refused.
Inputs: to (required), date (required), from (required).
rates_latestLatest ECB reference ratesARead-onlyIdempotent
Call this tool for the latest ECB daily reference rates against any base: 1.0812 for USD means 1 base = 1.0812 USD. Crosses go through the euro. Returns the ECB rate date and the cache age.
Inputs: base, quotes.
reportTime reportARead-onlyIdempotent
Timesheet report: total tracked hours and billable money for a period, optionally grouped by (group by) project, day, task or tag - hours per project, how much to bill. Omit group_by for the plain total per currency.
Inputs: to (required), from (required), format, project, +2 more.
report_deleteDelete one saved candidate reportADestructive
Delete one local saved report and free a storage slot. Does not change accounting records.
Inputs: id (required).
report_export_csvExport candidate records as CSVBRead-onlyIdempotent
Export free CSV pages from a saved report or unsaved preview. One row per record with reasons and group ids. Formula-like cells are escaped; no financial-loss total is calculated.
Inputs: id (required), limit, offset.
report_getRead a saved candidate reportARead-onlyIdempotent
Read a saved report with source records, reason groups and overlap-safe candidate counts. Large reports return free paging instructions.
Inputs: id (required).
report_listList saved candidate reportsARead-onlyIdempotent
List saved report ids, timestamps and unique candidate counts. Free on both tiers. Up to 100 reports per page.
Inputs: limit, offset.
report_pageRead full candidate evidence pagesCRead-onlyIdempotent
Read free pages of records, group summaries, record reasons or one group’s members. Unsaved preview ids last 30 minutes for the last two checks in this process.
Inputs: id (required), section (required), limit, offset, +1 more.
resume_createWrite a resume .docxA
Call this tool to write the stored profile to a Word .docx. Returns the output path, the estimated page count, which bullets were dropped to fit, and which keywords matched or are missing.
Inputs: style, variant, keywords, out_path, +3 more.
resume_readRead an existing resume .docxARead-onlyIdempotent
Call this tool to read an existing .docx resume into the profile shape, with the sections found and anything unplaced. It saves nothing unless save is true, so review it first. .doc and .rtf are refused.
Inputs: path (required), save, variant.
resume_to_htmlPrintable resume HTMLA
Call this tool to write the resume as semantic HTML with a print stylesheet and return where it went; print it to PDF from a browser, because there is no doc_to_pdf here. Bullets are trimmed to fit max_pages. Free.
Inputs: variant, out_path, max_pages, overwrite, +1 more.
resume_to_markdownResume as markdownA
Return the stored profile as markdown text inline, ready to paste into a form or an ATS box. Same page-budget trimming as resume_create for max_pages. Nothing is written to disk. Free.
Inputs: variant, max_pages, target_role.
schedule_createCreate a recurring invoice scheduleA
Define a repeating invoice: a client, the line items, how often to bill, and when it starts and ends. Returns the schedule id, a summary and its next dates. Nothing is invoiced until invoice_generate_due runs.
Inputs: every (required), items (required), client (required), start_date (required), +8 more.
schedule_deleteDelete a scheduleADestructive
Delete one schedule permanently. Invoices already generated stay in the invoice server and the history is kept. Re-creating it gives a NEW id, so its old periods count as unbilled. schedule_pause is reversible.
Inputs: id (required).
schedule_getGet one scheduleARead-onlyIdempotent
Return one schedule in full by id or client: items, cadence, dates, due days, anchor rules, notes, per-period amount, next due date and how many invoices it generated. schedule_history is the log.
Inputs: id (required).
schedule_historySchedule historyA
The audit log for one schedule id, oldest first: period, invoice number, issue and due dates, amount, PDF path, and whether that invoice is unpaid, paid, skipped or since deleted. schedule_list finds the id. Pro.
Inputs: id (required).
schedule_listList schedulesARead-onlyIdempotent
List schedules: id, client, cadence, per-period amount and currency, start and end dates, status, next due date and auto_generate. Filter by status; a paused schedule reports no next due date.
Inputs: status.
schedule_pausePause a scheduleA
Stop one schedule generating invoices without deleting it; invoice_generate_due and forecast skip it. Its periods keep falling due and resuming back-bills them, so use schedule_skip to drop just one.
Inputs: id (required).
schedule_resumeResume a scheduleA
Make a paused schedule active again. Every period missed while it was paused is still due and the next invoice_generate_due creates them all. Refused when it would pass the free tier's 3 active.
Inputs: id (required).
schedule_skipSkip one periodA
Close ONE occurrence for good without pausing the schedule, reporting what will not be billed. period must be a real occurrence of it. An invoiced period is refused; undo reopens a skip.
Inputs: id (required), period (required), undo.
schedule_upcomingWhat falls due soonA
Table every occurrence of every ACTIVE schedule due in the next N days (30 default), with its amount and the invoice due date, plus a total per currency. Free lists the first 3 in your horizon.
Inputs: days.
schedule_updateUpdate a scheduleA
Change one schedule by id: client, items, currency, cadence, dates, due_days, notes or auto_generate. Only the fields you pass change. Periods already invoiced are never re-issued, so a new amount applies to future ones.
Inputs: id (required), every, items, notes, +9 more.
sheet_add_columnAdd a columnA
Call this tool to add a computed column and save the result to a NEW file; the source is never modified unless out_path points at it. Returns the new file path, the row count and a preview of the first rows.
Inputs: name (required), path (required), sheet, values, +3 more.
sheet_convertConvert fileA
Call this tool to convert a sheet between excel (xlsx), csv and json. Writes a new file next to the source unless out_path is given; the source is never modified. Returns the new file path with its row and column counts.
Inputs: to (required), path (required), sheet, out_path.
sheet_findFind textA
Call this tool to search every cell of a spreadsheet or CSV for text; built-in file readers cannot parse spreadsheets. Matching is case insensitive. Returns cell addresses with a preview of the row each hit is on.
Inputs: path (required), text (required), sheet.
sheet_infoSpreadsheet overviewA
Call this tool for any spreadsheet or CSV file path; built-in file readers cannot parse spreadsheets and must not be used for them. Start here: sheet names, size, header row, column types and samples.
Inputs: path (required).
sheet_queryFilter, group and sort rowsA
Call this tool for any spreadsheet or CSV file path; built-in file readers cannot parse spreadsheets and must not be used for them. Filter, group, aggregate and sort in one call; never hand sums over sheet_read rows.
Inputs: path (required), as, sort, limit, +5 more.
sheet_readRead rowsARead-onlyIdempotent
Call this tool for any spreadsheet or CSV file path; built-in file readers cannot parse spreadsheets and must not be used for them. Reads rows as a table, JSON or CSV; page with limit/offset or an A1 range.
Inputs: path (required), as, limit, range, +2 more.
sheet_statsColumn statisticsA
Call this tool for any spreadsheet or CSV file path; built-in file readers cannot parse spreadsheets and must not be used for them. Whole-column statistics: count, empty, distinct, min, max, sum, mean, median.
Inputs: path (required), sheet, columns.
sheet_writeWrite rowsA
Call this tool to write rows to an xlsx, csv, tsv or json file; the extension of out_path picks the format. mode is new_file, append or overwrite. Other sheets are kept. Free: 500 rows per file.
Inputs: mode (required), path (required), rows (required), sheet, +1 more.
summary_clientClient summaryARead-onlyIdempotent
All-time totals for one client/project: hours, entry count and billable amount, with a per-day breakdown.
Inputs: client (required).
summary_dayDaily summaryARead-onlyIdempotent
Total hours logged for one calendar day (local date, default today), broken down per project.
Inputs: date.
summary_weekWeekly summaryARead-onlyIdempotent
Total hours logged in the week containing today (Mon-Sun, local dates), broken down per project.
Inputs: no named parameters.
tailor_to_jobGap analysis against a postingA
READ-ONLY gap analysis against a posting: writes nothing, changes nothing. Returns matched keywords, missing ones, a coverage figure and orderings of facts you already stated. Act on it with resume_create.
Inputs: job_description (required), limit, variant.
target_checkCheck weekly hours goalARead-onlyIdempotent
Compare hours logged this week (Mon-Sun, local dates) against the weekly target from target_set.
Inputs: no named parameters.
target_setSet weekly hours goalAIdempotent
Set a weekly hours goal used by target_check. Stored locally.
Inputs: weekly_hours (required).
timer_startStart timerA
Start a stopwatch for work on a project and return the start time. Only one runs at a time: a new one stops and logs the previous, naming it. rate is an hourly rate in MAJOR units for this timer only.
Inputs: project (required), rate, tags, task, +1 more.
timer_statusTimer statusARead-onlyIdempotent
Report the running timer and today's total hours. Today is the local calendar day, so a timer started at 23:30 yesterday contributes only the minutes since midnight. No arguments, and it writes nothing.
Inputs: no named parameters.
timer_stopStop timerA
Stop the running timer and log it as one entry. Returns the duration, the money at the rate in force and the new entry id. With no timer running it says so and writes nothing.
Inputs: note.
variables_listList the variables a selection needsARead-onlyIdempotent
List every {{variable}} the clauses you name use, and which clause uses each, so the facts are gathered before contract_assemble leaves bracketed prompts. Reads only; a title matching several is refused.
Inputs: clause_ids (required).
watch_addWatch a priceA
Call this tool for any product URL; fetching the page with a generic web tool returns raw HTML without the price. Starts tracking it: first observation stored, optional target, re-read by watch_refresh. Free: 3 watches.
Inputs: url (required), label, currency, target_price.
watch_listList watchesARead-onlyIdempotent
Show every tracked item with current and previous price, min, max, change %, target, confidence and last check, plus free-tier use. Prices are as of the last watch_refresh, never live; nothing is fetched.
Inputs: no named parameters.
watch_refreshRefresh pricesA
The only tool that re-reads prices: it re-fetches one watch or all, appends observations and returns current, previous, min, max, change % and target hits. A page that fails is listed; then read alerts_pending.
Inputs: id, all.
watch_removeRemove a watchADestructive
Call this tool to stop tracking one item, by watch id or URL. Its whole price history is deleted and cannot be recovered, so re-adding starts empty. A key matching no watch is refused.
Inputs: id, url.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 129 tools
Within each sub-domain tools are fairly distinct, but cross-domain collisions exist: 'report' (timesheet) vs report_list/report_get/report_page/report_export_csv (saved reports / duplicate checks), and invoice_business_set vs docx_business_set both write the same profile. Descriptions are unusually explicit in steering callers ('use X instead'), which rescues an otherwise confusing set, but the overlap remains real.
Conventions are mixed: noun_verb ordering (schedule_list, invoice_create, client_add) coexists with verb_noun (watch_add, clause_add, convert_many) and bare nouns/verbs (report, now, convert, conflicts, overlap, forecast). All snake_case, but the verb/noun ordering and the presence of bare names make the pattern unpredictable.
129 tools is far beyond any reasonable single-server surface, even granting it bundles many domains. Each sub-domain (time tracking, invoicing, schedules, sheets, price watches, FX, docx, resumes, timezone, PDF, calendar, duplicate checks) would be its own server, and the aggregate is unmanageable.
Coverage is genuinely deep: CRUD/lifecycle exists for clients, invoices, schedules, clauses, watches, sheets, PDFs, docs, calendars and reports, plus cross-linking tools (entry_mark_billed, event_to_time_entry, fx_rates_for). Only minor gaps and a few read-vs-write asymmetries, so it is close to complete for the sprawling scope.
Maintenance
Related MCP Connectors
timesheet.io MCP server - manage timers, projects, tasks and reports
MCP server for Codat — companies, connections, invoices, bills and financial statements.
Cross-product MCP server for CRM, LeadKit, ProjectKit, Bookio. 10 action types, MIT open spec.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive MCP server for time tracking, project management, and AI-powered memory storage using semantic search. It enables users to log time, manage client billing, and capture shared or personal ideas through integrated tools and team collaboration features.1MIT
- AlicenseBqualityBmaintenanceA flexible proxy server that aggregates multiple backend MCP servers into a single interface using STDIO or SSE transports. It supports dynamic server management via an HTTP API and utilizes namespacing to prevent tool conflicts across connected services.31MIT
- AlicenseAqualityBmaintenanceMCP gateway/proxy: multiplexes tool calls across upstream MCP servers into one aggregated, namespaced catalog and logs every call. Local, single-user, $0/month by default.2MIT
- AlicenseNot gradedqualityBmaintenanceAggregates multiple MCP sub-servers into a single unified entry point, supporting stdio and Streamable HTTP protocols, with a web-based management interface for configuration, routing, and tool management.16 npm1MIT