<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: berthelius</title>
    <description>The latest articles on DEV Community by berthelius (@brthls).</description>
    <link>https://dev.to/brthls</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3785060%2F0355f24b-0223-4eb8-b6c3-f48e6afcec24.jpeg</url>
      <title>DEV Community: berthelius</title>
      <link>https://dev.to/brthls</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brthls"/>
    <language>en</language>
    <item>
      <title>Zero Admin: The Complete Stack to Run Your Business on Autopilot</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Sun, 05 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/zero-admin-the-complete-stack-to-run-your-business-on-autopilot-3mbl</link>
      <guid>https://dev.to/frihet/zero-admin-the-complete-stack-to-run-your-business-on-autopilot-3mbl</guid>
      <description>&lt;p&gt;Picture this: a client accepts your quote on a Tuesday at 11:00 AM. At 11:01, the invoice is in their inbox. Thursday, they pay. The payment reconciles against the invoice automatically. At the end of the quarter, your sales tax is calculated, your tax forms are pre-filled, and you have not opened a spreadsheet in three months.&lt;/p&gt;

&lt;p&gt;This is not a fantasy. It is a stack you can build today, in under an hour.&lt;/p&gt;

&lt;p&gt;This guide is a complete blueprint. Not "which tool to use" but the entire flow: from the first client handshake to your quarterly tax filing. Step by step, no filler.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Zero Admin actually means (and what it does not)
&lt;/h2&gt;

&lt;p&gt;Zero Admin is not zero effort. It is zero &lt;em&gt;unnecessary&lt;/em&gt; effort.&lt;/p&gt;

&lt;p&gt;The distinction matters. Every business has two kinds of administrative work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mechanical work:&lt;/strong&gt; copying data between platforms, categorizing expenses by hand, matching bank transactions to invoices, calculating quarterly tax, filling out tax forms. This work does not require human intelligence. It requires time. And it steals 10+ hours from your week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intellectual work:&lt;/strong&gt; approving an unusual expense, deciding whether a project is profitable, negotiating payment terms with a client, choosing between investing and saving. This work actually needs you.&lt;/p&gt;

&lt;p&gt;:::quote&lt;br&gt;
Zero Admin = the system handles data, calculations, filing, and repetition. You handle relationships, strategy, and decisions.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;The goal is not to eliminate management. It is to eliminate the management that adds nothing. Let the back office run as a silent system in the background while you do the work that matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The complete flow, step by step
&lt;/h2&gt;

&lt;p&gt;This is what happens when the right pieces talk to each other. An end-to-end flow, from the moment a client says "yes" to the moment the tax authority has its numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Client accepts → Invoice sent
&lt;/h3&gt;

&lt;p&gt;The client accepts your quote. Frihet converts that quote into an invoice with one click. Same data, same line items, same client. Nothing re-typed.&lt;/p&gt;

&lt;p&gt;The invoice is sent automatically via email with a payment link (if you have Stripe Connect active). The client receives a professional PDF and can pay directly from the email.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens without your intervention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sequential numbering assigned (series + atomic counter)&lt;/li&gt;
&lt;li&gt;SHA-256 hash generated (compliance chain)&lt;/li&gt;
&lt;li&gt;PDF created with your branding&lt;/li&gt;
&lt;li&gt;Email sent to the client&lt;/li&gt;
&lt;li&gt;Status: "Sent" on your dashboard&lt;/li&gt;
&lt;li&gt;Due date calculated from your defaults&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; one click to confirm the accepted quote becomes an invoice. If your quotes are already solid, it is a 2-second gesture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Payment received → Revenue recognized
&lt;/h3&gt;

&lt;p&gt;The client pays. Stripe processes the charge. Frihet receives a webhook notification and marks the invoice as paid. Automatically.&lt;/p&gt;

&lt;p&gt;If you do not use Stripe, bank sync imports the transaction and Frihet matches the amount to the outstanding invoice. Same result, different route.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens without your intervention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment reconciled against the corresponding invoice&lt;/li&gt;
&lt;li&gt;Status updated: "Paid"&lt;/li&gt;
&lt;li&gt;Cash flow dashboard updated in real time&lt;/li&gt;
&lt;li&gt;Revenue categorized by service/product type&lt;/li&gt;
&lt;li&gt;Client payment history updated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; nothing. Literally. If the amount matches an outstanding invoice, the system closes the loop on its own. If there is a discrepancy (partial payment, different amount), it alerts you to decide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Expense → Auto-categorization
&lt;/h3&gt;

&lt;p&gt;You receive a vendor invoice. Snap a photo with your phone. Frihet's AI (OCR + classification) extracts the data: vendor, amount, date, tax, description.&lt;/p&gt;

&lt;p&gt;Then it categorizes: supplies, rent, materials, professional services? And flags whether it is tax-deductible under your filing status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens without your intervention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OCR extracts document data (vendor, tax ID, subtotal, tax, total)&lt;/li&gt;
&lt;li&gt;AI categorizes the expense (8 standard categories)&lt;/li&gt;
&lt;li&gt;Tax deductibility evaluated automatically&lt;/li&gt;
&lt;li&gt;Expense matched to bank transaction if one already exists&lt;/li&gt;
&lt;li&gt;Document stored as supporting evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; verify the AI got it right (most of the time, it does) and approve. Two taps on your phone. If the AI misclassifies, you correct it and the system learns for next time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Bank → Reconciliation
&lt;/h3&gt;

&lt;p&gt;Every day, Frihet syncs your bank transactions. Each incoming transaction is matched against your outstanding invoices. Each outgoing transaction is matched against your recorded expenses.&lt;/p&gt;

&lt;p&gt;The ones that match, reconcile themselves. The ones that do not match get grouped as "pending review" — not as errors, but as questions that need your answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens without your intervention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transactions imported (OFX/CSV or banking API)&lt;/li&gt;
&lt;li&gt;Automatic matching by amount + date + description&lt;/li&gt;
&lt;li&gt;Fuzzy matching for variations (rounding, bank fees)&lt;/li&gt;
&lt;li&gt;Anomalies flagged: unexpected charges, duplicates, discrepancies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; review the anomalies. If your flow is clean, there are few. A reconciliation that used to take 2 hours per month now takes 15 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Taxes → Auto-preparation
&lt;/h3&gt;

&lt;p&gt;End of quarter arrives. Instead of opening 4 spreadsheets and reviewing 90 days of invoices, Frihet already has the numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales tax collected&lt;/strong&gt; (from your issued invoices)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input tax paid&lt;/strong&gt; (from your recorded expenses)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Net amount due or refundable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tax forms pre-filled&lt;/strong&gt; with the quarter's data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estimated income tax&lt;/strong&gt; liability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What happens without your intervention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuous calculation of quarterly tax obligations&lt;/li&gt;
&lt;li&gt;Alerts before filing deadlines&lt;/li&gt;
&lt;li&gt;Tax forms pre-populated with the quarter's figures&lt;/li&gt;
&lt;li&gt;Invoice ledger (issued and received) kept up to date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; review the numbers, confirm everything checks out, and file (or hand the data to your accountant). A weekend's worth of work compressed into 30 minutes of review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Reporting → Decisions
&lt;/h3&gt;

&lt;p&gt;Everything above generates data. Data that, without additional effort, Frihet converts into visibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time P&amp;amp;L:&lt;/strong&gt; revenue vs expenses, net margin, monthly trend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cash flow forecast:&lt;/strong&gt; how much money is coming in and going out over the next 30/60/90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client profitability:&lt;/strong&gt; who generates the most value vs who consumes the most resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expenses by category:&lt;/strong&gt; where your money goes, visualized&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business KPIs:&lt;/strong&gt; average ticket, collection rate, DSO (days sales outstanding)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you do:&lt;/strong&gt; open the dashboard. Everything is there. No CSV exports, no report requests, no waiting for month-end close. You make decisions with today's data, not data from 45 days ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  The integration layer: what connects to what
&lt;/h2&gt;

&lt;p&gt;The flow above works because the pieces communicate. These are the key connections:&lt;/p&gt;

&lt;h3&gt;
  
  
  Frihet ↔ Stripe
&lt;/h3&gt;

&lt;p&gt;Bidirectional connection. Stripe Connect lets you collect payments directly from Frihet invoices (client pays, Frihet knows instantly). Stripe Revenue Sync imports Stripe charges as invoices automatically — ideal if you already collect with Stripe and want your books in order without duplicating work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frihet ↔ Bank
&lt;/h3&gt;

&lt;p&gt;Transaction import via OFX, CSV, or direct banking API. Transactions sync and the reconciliation engine matches each one against recorded invoices and expenses. No manual intervention for clean matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frihet ↔ n8n / Zapier / Make
&lt;/h3&gt;

&lt;p&gt;For custom flows: automatic payment reminders, weekly summaries via Slack or Telegram, unusual expense alerts, invoice creation when a deal closes in your CRM. 14 webhooks + open REST API. No call limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frihet ↔ AI agents via MCP
&lt;/h3&gt;

&lt;p&gt;Frihet's MCP server lets Claude, GPT, and other models access your account programmatically. An agent can: query outstanding invoices, create reminders, generate reports, and answer questions about your business using real data. Not hallucinated data — yours.&lt;/p&gt;

&lt;p&gt;:::callout&lt;br&gt;
All integrations are included in every plan. No premium modules, no add-ons, no surprises.&lt;br&gt;
:::&lt;/p&gt;

&lt;h2&gt;
  
  
  What you still do manually (and why that is a good thing)
&lt;/h2&gt;

&lt;p&gt;Zero Admin does not eliminate your involvement. It eliminates the involvement that adds no value. This is what stays yours:&lt;/p&gt;

&lt;p&gt;:::checklist&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Approve unusual expenses.&lt;/strong&gt; A new charge the AI does not recognize needs your confirmation. As it should.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review anomalies.&lt;/strong&gt; A partial payment, a duplicate charge, a transaction with no matching invoice. Frihet surfaces them. You decide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make business decisions.&lt;/strong&gt; Raise prices? Drop a client? Invest in equipment? The dashboard gives you data. The decision is yours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Talk to your clients.&lt;/strong&gt; The human relationship does not get automated. Nor should it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review quarterly numbers.&lt;/strong&gt; Preparation is automatic. The sign-off is yours. There should always be a human who says "this is correct."
:::&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a limitation. It is intentional design. Systems that make every decision for you are dangerous. Systems that handle the mechanical decisions and leave you the important ones — those actually work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before vs After: the real comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The traditional workflow
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Weekly time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Excel / Google Sheets&lt;/td&gt;
&lt;td&gt;Invoice tracking, payment follow-up&lt;/td&gt;
&lt;td&gt;2h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Banking app&lt;/td&gt;
&lt;td&gt;Review transactions, download statements&lt;/td&gt;
&lt;td&gt;1h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invoicing software&lt;/td&gt;
&lt;td&gt;Create invoices, send PDFs&lt;/td&gt;
&lt;td&gt;1.5h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email&lt;/td&gt;
&lt;td&gt;Payment reminders, follow-up threads&lt;/td&gt;
&lt;td&gt;1h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expense folder&lt;/td&gt;
&lt;td&gt;Organize receipts, classify&lt;/td&gt;
&lt;td&gt;1h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tax spreadsheet&lt;/td&gt;
&lt;td&gt;Calculate sales tax, prep quarterly filing&lt;/td&gt;
&lt;td&gt;1.5h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your accountant&lt;/td&gt;
&lt;td&gt;Calls, send documents, resolve questions&lt;/td&gt;
&lt;td&gt;1h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRM / notes&lt;/td&gt;
&lt;td&gt;Update client status&lt;/td&gt;
&lt;td&gt;1h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~10h/week&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;15+ tools. 10+ hours per week. Fragmented data. Transcription errors. And at the end of every quarter, a weekend lost reconciling numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Zero Admin stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Weekly time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frihet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Invoicing, expenses, clients, reporting, taxes&lt;/td&gt;
&lt;td&gt;1h (review)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stripe&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Payments, payment gateway&lt;/td&gt;
&lt;td&gt;0 (automatic)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bank&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Transaction sync&lt;/td&gt;
&lt;td&gt;15min (review anomalies)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;n8n&lt;/strong&gt; (optional)&lt;/td&gt;
&lt;td&gt;Reminders, alerts, custom flows&lt;/td&gt;
&lt;td&gt;0 (automatic)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~1.5h/week&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;4 tools. 1.5 hours per week. A single source of truth for all your financial data. And at the end of the quarter, 30 minutes of review.&lt;/p&gt;

&lt;p&gt;:::quote&lt;br&gt;
The difference is not technological. It is structural. One connected system vs 15 disconnected tools. Data that flows vs data you copy by hand.&lt;br&gt;
:::&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set it up in under 1 hour
&lt;/h2&gt;

&lt;p&gt;You do not need a weekend. You need one focused hour.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minute 0-15: Your Frihet account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create your account at &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;app.frihet.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Complete the welcome wizard: tax details, logo, invoice series&lt;/li&gt;
&lt;li&gt;Import your clients (CSV or manual — if you have a handful, manual is faster)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Minute 15-30: Connect Stripe
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to Settings → Integrations → Stripe&lt;/li&gt;
&lt;li&gt;Connect your Stripe account (OAuth, one click)&lt;/li&gt;
&lt;li&gt;Enable Revenue Sync if you already collect with Stripe (it will import historical invoices)&lt;/li&gt;
&lt;li&gt;Enable Stripe Connect if you want to collect payments directly from Frihet invoices&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Minute 30-45: Connect your bank
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Import your first bank statement (OFX or CSV)&lt;/li&gt;
&lt;li&gt;Review the automatic reconciliation suggestions&lt;/li&gt;
&lt;li&gt;Confirm or correct the first matches — the system learns from your corrections&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Minute 45-60: Your first flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a quote for a real client&lt;/li&gt;
&lt;li&gt;Convert it to an invoice&lt;/li&gt;
&lt;li&gt;Log an expense with your phone camera&lt;/li&gt;
&lt;li&gt;Open the dashboard — you already have visibility&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From here, everything flows. Every new invoice, every new expense, every new payment feeds the system. No duplicate data entry, no copying between tabs, no "I will deal with it on Sunday."&lt;/p&gt;

&lt;h2&gt;
  
  
  The best admin is the admin you never do
&lt;/h2&gt;

&lt;p&gt;Administrative work is not your job. It is the infrastructure that supports your job. And like all good infrastructure, it should be invisible.&lt;/p&gt;

&lt;p&gt;Zero Admin is not a magic promise. It is an architecture. A system where each piece knows what to do with the information it receives, passes it to the next piece without asking permission, and only alerts you when it needs a decision that only you can make.&lt;/p&gt;

&lt;p&gt;The time you recover is not abstract. It is real hours you can spend on what generates value: closing projects, serving clients, building product, or simply not working on a Sunday.&lt;/p&gt;

&lt;p&gt;Setup takes one hour. The return starts in week one.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part 5 of "Building an AI-Native ERP". Available in &lt;a href="https://www.frihet.io/en/blog/zero-admin-stack-business-autopilot" rel="noopener noreferrer"&gt;17 languages&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;&lt;/strong&gt; — Free, AI-native ERP. &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;Try it&lt;/a&gt; · &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ai</category>
      <category>productivity</category>
      <category>saas</category>
    </item>
    <item>
      <title>The ERP Is Dead: Why Your Business Needs an AI Operating System</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Sat, 04 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/the-erp-is-dead-why-your-business-needs-an-ai-operating-system-25gc</link>
      <guid>https://dev.to/frihet/the-erp-is-dead-why-your-business-needs-an-ai-operating-system-25gc</guid>
      <description>&lt;p&gt;You open your ERP. Navigate three menus. Fill out a 14-field form. Hit save. Repeat. This is not management. This is work about work.&lt;/p&gt;

&lt;p&gt;And yet, for two decades, this has been the standard. Software that records what you already know, organizes what you already did, and shows you reports about what already happened. Millions of professionals open their ERP every day not because it gives them clarity, but because they have no alternative.&lt;/p&gt;

&lt;p&gt;That era is over.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ERPs got right (and why it is no longer enough)
&lt;/h2&gt;

&lt;p&gt;Credit where it is due: ERPs were revolutionary. Before SAP, Sage, or even QuickBooks, business management lived in filing cabinets, spreadsheets, and the accountant's memory. ERPs centralized data, standardized processes, and created a single source of truth for a company's finances.&lt;/p&gt;

&lt;p&gt;That leap was massive. From the folder called &lt;code&gt;INVOICES_FINAL_FINAL_v3&lt;/code&gt; to a system with automatic numbering and auditable records. From the expense notebook to a real-time balance sheet. From chaos to order.&lt;/p&gt;

&lt;p&gt;But order is not intelligence. And that is where ERPs froze.&lt;/p&gt;

&lt;p&gt;What was revolutionary in 2005 is baseline infrastructure in 2026. Centralizing data is not a competitive advantage -- it is the minimum. And most ERPs, including ones marketed as "modern" or "cloud-native," still operate with the same logic: you enter data, the software stores it, you query it.&lt;/p&gt;

&lt;p&gt;They are databases with nice forms. Spreadsheets with better UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three problems no traditional ERP can solve
&lt;/h2&gt;

&lt;p&gt;The limitation of legacy ERPs is not a missing feature list. It is an architecture problem. There are three structural flaws that updates cannot fix:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. They are reactive
&lt;/h3&gt;

&lt;p&gt;A traditional ERP does nothing until you do something. It does not alert you that a client is 45 days past due until you pull the aging report. It does not catch that you are applying the wrong sales tax rate until your accountant flags it at quarter-end. It does not suggest categorizing a purchase as a deductible capital expense because it does not know what a capital expense is.&lt;/p&gt;

&lt;p&gt;The software waits. You work. If you make a mistake, you find out late.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. They are silos
&lt;/h3&gt;

&lt;p&gt;Your ERP does not talk to your bank. It does not talk to Stripe. It does not talk to your e-commerce platform. It does not talk to your accountant's system. And when it "talks," it does so through brittle integrations that require manual configuration, CSV exports, and hand-matched reconciliations.&lt;/p&gt;

&lt;p&gt;The result is that your business data lives fragmented across 8 different tools. Your ERP has the invoices, the bank has the transactions, Stripe has the charges, the spreadsheet has the forecasts. And you are the human connector keeping everything in sync.&lt;/p&gt;

&lt;p&gt;That synchronization work eats 5 to 15 hours a week. It is not management. It is digital plumbing.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. They are one-size-fits-all
&lt;/h3&gt;

&lt;p&gt;A freelance designer in Brooklyn and a restaurant chain in Dallas use the same software with the same forms, the same menus, and the same reports. Customization, when it exists, means configuring which fields to show or hide.&lt;/p&gt;

&lt;p&gt;But real intelligence is not configuration. It is context. A good system should know that your business invoices 80% of clients in the EU and pre-apply reverse charge. It should know that you always invoice in multiples of 500 and flag when an amount deviates. It should know that every April you need your Q1 tax estimate and have it ready before you go looking for it.&lt;/p&gt;

&lt;p&gt;Traditional ERPs do not learn. They are identical the day you install them and three years later.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an AI operating system for business actually looks like
&lt;/h2&gt;

&lt;p&gt;The alternative is not an ERP with a chatbot glued on. It is a new category: software where artificial intelligence is the architectural foundation. Not a feature. The foundation.&lt;/p&gt;

&lt;p&gt;Here is what changes:&lt;/p&gt;

&lt;h3&gt;
  
  
  From reactive to proactive
&lt;/h3&gt;

&lt;p&gt;The software analyzes payment patterns and alerts you before a client falls behind. It detects tax anomalies when you create the invoice, not when the auditor calls. It calculates your estimated quarterly taxes in real time, not when your accountant asks for the data.&lt;/p&gt;

&lt;p&gt;It does not wait for you to ask. It anticipates.&lt;/p&gt;

&lt;h3&gt;
  
  
  From silo to connected ecosystem
&lt;/h3&gt;

&lt;p&gt;Integrations are not fragile bridges between islands. They are native connections. Stripe charges become invoices automatically. Bank transactions reconcile without intervention. Data flows between tools because the system was designed for it, not patched to simulate it.&lt;/p&gt;

&lt;p&gt;And with protocols like MCP (Model Context Protocol), connectivity goes beyond traditional integrations. An AI agent can query your revenue, generate quotes, or analyze your cash flow without you opening any application. Your business software becomes a tool that other systems can use autonomously.&lt;/p&gt;

&lt;h3&gt;
  
  
  From generic to personalized
&lt;/h3&gt;

&lt;p&gt;The system learns how you work. Which expense categories you use most. Which clients pay late. What type of invoices you issue most frequently. And it uses that context to accelerate every interaction.&lt;/p&gt;

&lt;p&gt;This is not personalization through configuration. It is personalization through observation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real examples: this works today
&lt;/h2&gt;

&lt;p&gt;This is not theoretical. These capabilities exist now in AI-native software:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic tax intelligence.&lt;/strong&gt; You create an invoice for a client in a different tax jurisdiction. The system detects the zone, applies the correct tax regime, adjusts withholding based on your filing status, and calculates the taxable amount. It does not ask. It does it. And if something does not add up, it flags it before you hit send.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expense categorization via OCR.&lt;/strong&gt; You photograph a restaurant receipt. The AI extracts the amount, date, vendor, and tax ID. It categorizes the expense as "client entertainment" based on your history. It links it to the correct project. Time spent: 3 seconds. Time saved versus doing it manually: 4 minutes. Multiply that by 200 expenses a month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conversational copilot with real context.&lt;/strong&gt; You ask your AI assistant: "How much do clients owe me this month?" No report to open, no date filter to set, no manual addition required. It responds with real-time data, broken down by client, with aging days for each invoice. And if you ask it to send a payment reminder to the most overdue account, it does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent interoperability.&lt;/strong&gt; Your accountant uses Claude with your ERP's MCP server. Without opening your application, they query your quarterly invoices, verify tax rates, and download the invoice ledger. Your software works for you even when you are not using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "adding AI" to legacy software does not work
&lt;/h2&gt;

&lt;p&gt;Here is the trap most vendors fall into. They take software designed 10 or 15 years ago, attach a chatbot, call it "AI-powered," and raise the price.&lt;/p&gt;

&lt;p&gt;It is like strapping a GPS to a horse carriage and calling it a self-driving vehicle.&lt;/p&gt;

&lt;p&gt;The problem is architectural. A legacy ERP has data in rigid tables, linear workflows, and an interface designed for the human to do all the work. Bolting AI on top of that structure limits it to what the structure allows: answering questions about data that already exists, in formats the system already knows.&lt;/p&gt;

&lt;p&gt;:::quote&lt;br&gt;
Bolt-on AI answers questions. Born-in AI makes decisions.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;In an AI-native system, artificial intelligence has access to the entire value chain. It is not confined to a chatbot in a corner. It can intercept an invoice before it ships to correct a tax error. It can reclassify an expense retroactively when it learns something new about your business. It can generate a cash flow forecast that combines bank data, outstanding invoices, and seasonal patterns.&lt;/p&gt;

&lt;p&gt;None of that is possible when AI is a superficial layer on top of a passive database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for in AI-native business software
&lt;/h2&gt;

&lt;p&gt;If you are evaluating tools, these are the signals that separate the real from the marketing:&lt;/p&gt;

&lt;p&gt;:::checklist&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI from day one, not as an update.&lt;/strong&gt; If the vendor shipped AI as a feature in a recent changelog, it is bolt-on. If AI is part of how the product works since its inception, it is born-in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation without configuration.&lt;/strong&gt; Repetitive tasks should automate without you building rules, flows, or "recipes." If you need a flowchart to automate something basic, it is not AI-native.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectivity as a principle.&lt;/strong&gt; Documented API, webhooks, MCP server, native integrations with the tools you already use. If exporting data requires a CSV or an email to support, run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context that improves with use.&lt;/strong&gt; The software should be faster and more useful after 6 months than on day one. If the experience is identical at the start and a year in, it is not learning anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency about what the AI does.&lt;/strong&gt; Every automated decision should be visible, explainable, and reversible. If the AI operates as a black box, do not trust it with your finances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your data, always.&lt;/strong&gt; Full export, open format, no exit fees. If the vendor charges you to extract your own data, their business model depends on you not being able to leave.
:::&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The shift is happening now
&lt;/h2&gt;

&lt;p&gt;You do not need to wait until 2030. The convergence of three forces is accelerating this transition today:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regulation.&lt;/strong&gt; Across the globe, governments are tightening requirements on invoicing software. In the EU, e-invoicing mandates are expanding. In the US, IRS reporting rules keep growing in complexity. Many businesses will have to change software anyway. That is the perfect moment to leap to a superior category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technology.&lt;/strong&gt; Language models, computer vision, and interoperability protocols (MCP, OpenAPI) have reached a maturity level that makes integrating real AI into business software viable without compromising reliability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expectations.&lt;/strong&gt; If your personal AI assistant can book a flight, manage your calendar, and summarize a 50-page document, why is your invoicing software still asking you to fill out forms by hand? Tolerance for passive interfaces is collapsing.&lt;/p&gt;

&lt;p&gt;Traditional ERPs will not vanish overnight. SAP will keep selling enterprise licenses. QuickBooks will still have customers. But the "ERP" category as we know it -- reactive, generic, siloed software -- is entering its terminal phase.&lt;/p&gt;

&lt;p&gt;What replaces it is not another ERP with more features. It is a different way of thinking about business software: a system that works with you, not one you work inside of.&lt;/p&gt;

&lt;p&gt;:::quote&lt;br&gt;
Management should not eat your week. It should disappear.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;That is what we are building at Frihet. Not an ERP with AI. A business operating system where artificial intelligence is not a feature -- it is the reason the software exists.&lt;/p&gt;

&lt;p&gt;Less management. More freedom.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part 4 of "Building an AI-Native ERP". Available in &lt;a href="https://www.frihet.io/en/blog/erp-is-dead-business-needs-ai-operating-system" rel="noopener noreferrer"&gt;17 languages&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;&lt;/strong&gt; — Free, AI-native ERP. &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;Try it&lt;/a&gt; · &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>startup</category>
      <category>productivity</category>
    </item>
    <item>
      <title>React + Firebase: Architecture Decisions for a Production ERP</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Fri, 03 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/react-firebase-architecture-decisions-for-a-production-erp-2lg4</link>
      <guid>https://dev.to/frihet/react-firebase-architecture-decisions-for-a-production-erp-2lg4</guid>
      <description>&lt;p&gt;Building an ERP is not a side project. It handles real money, real tax obligations, and real business data. Every architecture decision has consequences that compound over months.&lt;/p&gt;

&lt;p&gt;Here is what I chose for Frihet, and the reasoning behind each decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend:  React 18 + TypeScript + Vite 5
Styling:   Tailwind CSS + shadcn/ui + Radix
Backend:   Firebase (Auth, Firestore, Cloud Functions, Storage)
AI:        Google Gemini (2.5 Flash + Pro)
Payments:  Stripe Billing + Connect
Hosting:   Vercel (frontend) + GCP europe-west1 (backend)
Mobile:    Capacitor (iOS + Android from same codebase)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Firebase over a traditional backend
&lt;/h2&gt;

&lt;p&gt;I am a solo developer building a product that competes with companies backed by tens of millions. I cannot operate database clusters, manage migrations, handle connection pooling, and build features at the same time.&lt;/p&gt;

&lt;p&gt;Firebase gives me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; with email, Google, GitHub, Microsoft — zero custom code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firestore&lt;/strong&gt; with realtime subscriptions — data changes propagate instantly to all connected clients&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Functions&lt;/strong&gt; for server-side logic — scales to zero, no idle costs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Rules&lt;/strong&gt; that enforce data isolation at the database level, not in application code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff is vendor lock-in and a NoSQL data model. For a solo founder shipping fast, this tradeoff makes sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  The NoSQL challenge
&lt;/h3&gt;

&lt;p&gt;ERPs are traditionally relational. Making Firestore work required strict data modeling discipline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workspace isolation at the database level.&lt;/strong&gt; Each business tenant has its own data partition. Even if application code has a bug, cross-tenant data leakage is impossible because the security rules enforce it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Denormalize for reads, reference for writes.&lt;/strong&gt; Invoice list views show the client name without an extra query. But mutations always go through the canonical client record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Functions for complex aggregations.&lt;/strong&gt; Anything resembling a SQL JOIN or GROUP BY runs server-side, not client-side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach works well for 80% of use cases. The remaining 20% (complex reporting, cross-entity queries) requires more engineering effort than it would with PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  State management without a state library
&lt;/h2&gt;

&lt;p&gt;No Redux. No Zustand. No MobX.&lt;/p&gt;

&lt;p&gt;Firebase IS the state store. The data flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User action → hook → Firestore write → onSnapshot → React re-render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no local state to synchronize because Firestore is the source of truth. Optimistic updates handle the latency gap. When the write confirms, the snapshot listener fires and React re-renders with the persisted data.&lt;/p&gt;

&lt;p&gt;This eliminates an entire category of bugs: stale state, sync conflicts, cache invalidation. The database is always right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Financial calculations: one source of truth
&lt;/h2&gt;

&lt;p&gt;Spain has VAT (21/10/4%), Canary Islands has IGIC (7/3/0%), and freelancers have IRPF withholding (-15%). One wrong rounding operation means a tax filing error.&lt;/p&gt;

&lt;p&gt;Every tax calculation, total computation, and rounding operation is centralized. Never inline math in components. This means fixing a tax bug fixes it across every invoice, quote, expense, and report simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Every financial operation goes through the same engine&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;calculateTotal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/calculations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Whether it is an invoice, quote, or expense&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;taxType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;withholding&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI as a first-class citizen, not a bolt-on
&lt;/h2&gt;

&lt;p&gt;The AI copilot is not a chatbot wrapper around the UI. It has typed function definitions that operate on real user data through the same APIs the frontend uses.&lt;/p&gt;

&lt;p&gt;The key architectural decisions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Function calling, not RAG.&lt;/strong&gt; The AI does not search through documents. It calls structured functions with typed parameters. &lt;code&gt;create_invoice({ clientId, items, taxRate })&lt;/code&gt; is unambiguous. A natural language search is not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lazy loading.&lt;/strong&gt; The AI module is large. It only loads when the user first interacts with the chat. Preloading starts on hover over the chat button — by the time they click, the module is ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context injection.&lt;/strong&gt; The system prompt includes the user's actual business context: active clients, recent invoices, tax obligations. The AI does not guess — it operates on real data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security boundaries.&lt;/strong&gt; The AI uses the same permission model as the UI. It cannot access data the user cannot access. Function calls go through the same security rules.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  i18n at scale: 17 languages
&lt;/h2&gt;

&lt;p&gt;Not machine-translated labels. Full localization including fiscal terminology.&lt;/p&gt;

&lt;p&gt;The translation pipeline uses a 240K-entry Translation Memory first (97.8% match rate), then AI only for gaps. This dropped the cost from $3.36 to $0.30 per full translation run — a 91% reduction.&lt;/p&gt;

&lt;p&gt;All 17 languages are maintained in parity. A CI check blocks any commit that has missing translation keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance results
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse desktop:&lt;/strong&gt; 100/100/100/100&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First Contentful Paint:&lt;/strong&gt; under 1 second&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build time:&lt;/strong&gt; under 10 seconds (TypeScript check + Vite bundle)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code splitting:&lt;/strong&gt; every view is a lazy route, AI loads on demand&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;Firebase is not the "right" choice for an ERP. PostgreSQL would make reporting easier. A traditional backend would give me more control. But Firebase let me ship a production ERP with 17 languages, 41 integrations, full accounting, and AI — as a solo developer — in under 3 months.&lt;/p&gt;

&lt;p&gt;The architecture you can ship with is better than the architecture you are still building.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part 3 of "Building an AI-Native ERP". Previously: &lt;a href="https://dev.to/frihet/how-i-built-a-55-tool-mcp-server-that-runs-an-entire-business-temp-slug-6858792"&gt;55-Tool MCP Server&lt;/a&gt; · &lt;a href="https://dev.to/frihet/why-i-built-frihet-solo-one-developer-zero-investors-temp-slug-4953392"&gt;Why I Built It Solo&lt;/a&gt;. Next: why the traditional ERP is dead.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;&lt;/strong&gt; — Free, AI-native ERP. &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;Try it&lt;/a&gt; · &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;npm&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>firebase</category>
      <category>typescript</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why I Built Frihet Solo: One Developer, Zero Investors</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Thu, 02 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/why-i-built-frihet-solo-one-developer-zero-investors-43jd</link>
      <guid>https://dev.to/frihet/why-i-built-frihet-solo-one-developer-zero-investors-43jd</guid>
      <description>&lt;p&gt;Three years ago I was billing clients from a Google Sheet, tracking expenses in a second spreadsheet, reconciling bank transactions in a third, and manually moving numbers between all of them at quarter end. I had tried every ERP on the Spanish market. Each one solved part of the problem while introducing new ones: slow interfaces, features I'd never use, pricing that made no sense for a solo freelancer, and a general sense that the software was designed for a company with an IT department, not for one person working alone.&lt;/p&gt;

&lt;p&gt;So I built Frihet myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I was solving
&lt;/h2&gt;

&lt;p&gt;The Spanish ERP market is full of tools built for larger companies that were later "simplified" for freelancers. The architecture stayed the same -- heavy, slow, enterprise-grade. What changed was the interface: fewer menu items, a lighter color scheme, a smaller price tag.&lt;/p&gt;

&lt;p&gt;None of that addressed the actual problem. When you work alone or run a small team, the bottleneck is not which modules you have access to. The bottleneck is friction. Every unnecessary click, every form with twelve fields when you need three, every time you have to leave your work context to go find a number -- that adds up to hours every week. Hours you're not billing.&lt;/p&gt;

&lt;p&gt;I wanted a tool that operated at the speed of thought. Not "fast for an ERP." Actually fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision to build it myself
&lt;/h2&gt;

&lt;p&gt;I did not start with a business plan or a pitch deck. I started with a list of things I was doing manually that a computer could handle better. Automatic invoice numbering. OCR for receipts. A dashboard that shows the current state of my business without me having to generate a report.&lt;/p&gt;

&lt;p&gt;The first version ran locally and handled only my data. It took about two months before I showed it to anyone else. The second freelancer who tried it asked for features within forty-eight hours. That was the signal.&lt;/p&gt;

&lt;p&gt;I kept going. No investors, no co-founder, no team. Just the tool I needed, built the way I would build any software: incrementally, with real user data (initially just my own), and with the assumption that if I found something annoying, others would too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes Frihet different
&lt;/h2&gt;

&lt;p&gt;After a year of building and shipping daily, these are the things that actually distinguish Frihet from the alternatives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI-native, not AI-added.&lt;/strong&gt; Frihet's AI copilot is not a feature that was bolted onto an existing product. The 40+ Gemini function tools were designed into the architecture from the beginning. You can create an invoice, query your outstanding balance, or ask for a summary of Q1 expenses by talking to the assistant in plain language. The AI has full context of your actual data -- your clients, your invoices, your history -- not a generic financial knowledge base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keyboard-first.&lt;/strong&gt; Every action in Frihet is reachable via Cmd+K. New invoice, new expense, switch to dashboard, find a client -- all of it from the keyboard without touching the mouse. This sounds minor until you've used it for a week and tried to go back to a click-based ERP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer ecosystem.&lt;/strong&gt; Frihet has a complete REST API, 14 webhook event types, and an official MCP server published on npm as @frihet/mcp-server with 31 tools. If you use Claude Code, Cursor, or any MCP-compatible client, you can manage your entire invoicing workflow without opening a browser tab. I use this daily. The MCP server is open source under MIT -- the code is on GitHub if you want to see exactly what it does with your data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;40 integrations.&lt;/strong&gt; Stripe, Stripe Connect, WooCommerce, Shopify, Gumroad, Lemon Squeezy, Google Sheets, PayPal, GoCardless, Toggl, Clockify, Slack, Google Calendar, n8n, Zapier, Make, and more. 25 active today, 15 on the way. When a Stripe payment comes in, it appears in Frihet as an invoice automatically. When you log a Toggl time entry, it maps to a billable item. The integrations exist because I needed them, which means they were designed to solve real problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VeriFactu compliance.&lt;/strong&gt; Spain is rolling out mandatory invoice certification (VeriFactu) and Frihet is over 95% compliant ahead of the user-facing deadline. Phases 0 through 3 are done: immutability, SHA-256 hash chain, gap-free numbering, locked fields, corrective invoices, AEAT QR codes, invoice register, and the XML+SOAP submission layer to AEAT's backend. What remains is the configuration UI and sandbox testing. Your invoices are legally valid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The name
&lt;/h2&gt;

&lt;p&gt;Frihet means freedom in Swedish. I'm half Swedish and the name came naturally. The Spanish market uses "libertad" and the English market uses "freedom" -- both words carry a lot of baggage in product names. Swedish felt clean and unused.&lt;/p&gt;

&lt;p&gt;The name captures the actual goal: freedom from tools that slow you down. Freedom from spreadsheets patched together with formulas. Freedom from ERPs designed for companies ten times your size. Freedom to focus on the work, not the administration of the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical choices
&lt;/h2&gt;

&lt;p&gt;Some decisions I made early that shaped the product significantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React + Firebase.&lt;/strong&gt; Not the trendy stack, but the right stack for this. Firebase Auth, Firestore, and Cloud Functions gave me a backend that scales without ops overhead. The tradeoff is vendor lock-in, which I accept because the alternative is maintaining a server cluster alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini for AI.&lt;/strong&gt; Not OpenAI. Google Gemini's function calling is clean, well-documented, and the pricing is reasonable at scale. The AI features run through about 40 typed function definitions -- invoice creation, expense queries, client lookups, financial summaries. Every function call is logged so users can see exactly what the AI did.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capacitor for mobile.&lt;/strong&gt; One codebase for web, iOS, and Android. I built the web app first, then wrapped it with Capacitor. The native plugins (camera for OCR, haptics, push notifications) work well. I haven't published to the app stores yet because the web app needed to be solid first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No React Router.&lt;/strong&gt; Frihet's SPA uses a custom router. This sounds like an antipattern, but the custom router is about 50 lines and gives me precise control over navigation without fighting framework abstractions. I can change transition behavior in an afternoon instead of debugging router internals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open source where it makes sense.&lt;/strong&gt; The MCP server is open source (MIT). The API is public with documentation. Webhooks are documented and versioned. The core product is closed source -- I need revenue to keep building -- but the integration layer is open so developers can trust and verify it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest numbers
&lt;/h2&gt;

&lt;p&gt;Frihet launched on February 13, 2026. I'm not going to give you a vanity number to make the launch look better than it is.&lt;/p&gt;

&lt;p&gt;What I can tell you: the product works, it's being used by real customers billing real money, and it has not had a single outage since launch. The Stripe integration syncs correctly. The OCR on receipts works on phone photos taken in bad lighting. The AI assistant handles ambiguous queries without hallucinating numbers.&lt;/p&gt;

&lt;p&gt;The part I'm most proud of is not a metric -- it's that every feature in the product is something I use myself. There is no "enterprise tier" graveyard of features that exist only to justify pricing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The public roadmap is live. The immediate priorities are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VeriFactu UI + sandbox&lt;/strong&gt; -- the XML+SOAP submission backend is complete. What's left is the configuration screen for the user's digital certificate and testing against AEAT's sandbox. Mandatory before 2027.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More integrations.&lt;/strong&gt; Wise, Qonto, HubSpot, and WhatsApp Business are next. The integration framework is solid -- adding a new integration takes days, not months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advanced multi-currency.&lt;/strong&gt; We already support 40 currencies across 71 countries with precision-aware rounding. The next level is multi-currency dashboard analytics and automatic exchange rate tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mobile apps.&lt;/strong&gt; The Capacitor shell exists and works. iOS and Android publishing is a matter of weeks, not months.&lt;/p&gt;

&lt;p&gt;I post updates on what I ship and what I'm working on. The roadmap is honest about what's planned vs. what's live.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Frihet is available now at &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;app.frihet.io&lt;/a&gt;. Free plan with no time limit -- invoicing, expenses, clients, and products included. No credit card required.&lt;/p&gt;

&lt;p&gt;If you're launching from Product Hunt: use the code &lt;strong&gt;PRODUCTHUNT&lt;/strong&gt; for 30% off your first three months on any paid plan. 500 uses, valid through April.&lt;/p&gt;

&lt;p&gt;I built this because I needed it. If you're a freelancer, consultant, or small team who has been patching together tools that don't talk to each other, try it. The worst case is you spend ten minutes and go back to your spreadsheet.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Part 2 of the "Building an AI-Native ERP" series. Previously: &lt;a href="https://dev.to/frihet/how-i-built-a-55-tool-mcp-server-that-runs-an-entire-business-1lhf-temp-slug-6858792"&gt;How I Built a 55-Tool MCP Server That Runs an Entire Business&lt;/a&gt;. Available in &lt;a href="https://www.frihet.io/en/blog/why-i-built-frihet-solo" rel="noopener noreferrer"&gt;17 languages on our blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;&lt;/strong&gt; — Free, AI-native ERP for modern businesses. &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;API Docs&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt; · &lt;a href="https://github.com/berthelius/Frihet-ERP" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How I Built a 55-Tool MCP Server That Runs an Entire Business</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Wed, 01 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/how-i-built-a-55-tool-mcp-server-that-runs-an-entire-business-36f3</link>
      <guid>https://dev.to/frihet/how-i-built-a-55-tool-mcp-server-that-runs-an-entire-business-36f3</guid>
      <description>&lt;p&gt;Every ERP has a REST API. Ours has one too. But what made everything click was building an MCP server on top of it — 55 tools that let any AI agent manage invoices, expenses, clients, taxes, and accounting through natural language.&lt;/p&gt;

&lt;p&gt;This is the story of how I built it, what I learned, and why MCP might be the most underrated protocol in business software right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP, not just REST
&lt;/h2&gt;

&lt;p&gt;I had a perfectly good REST API. Cursor pagination, field selection, 6 filter types, OpenAPI spec. But here is the thing: &lt;strong&gt;APIs are designed for developers. MCP is designed for AI agents.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With REST, you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the docs&lt;/li&gt;
&lt;li&gt;Figure out the auth&lt;/li&gt;
&lt;li&gt;Chain multiple endpoints&lt;/li&gt;
&lt;li&gt;Parse responses&lt;/li&gt;
&lt;li&gt;Handle errors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With MCP, an AI agent gets a tool catalog with typed parameters, calls what it needs, and gets structured responses. No docs required. The schema IS the documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// REST: 4 calls, manual orchestration&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/v1/clients?q=Acme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/v1/invoices&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// MCP: 1 natural language instruction&lt;/span&gt;
&lt;span class="c1"&gt;// "Create an invoice for Acme Corp, 10 hours of consulting at €150/hr"&lt;/span&gt;
&lt;span class="c1"&gt;// The agent calls search_clients → create_invoice automatically&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The architecture: 55 tools in 6 domains
&lt;/h2&gt;

&lt;p&gt;I organized the tools by business domain, not by CRUD operations. This is the key insight — agents think in workflows, not in database tables.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invoicing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;create_invoice&lt;/code&gt;, &lt;code&gt;send_invoice&lt;/code&gt;, &lt;code&gt;record_payment&lt;/code&gt;, &lt;code&gt;generate_pdf&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Expenses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;create_expense&lt;/code&gt;, &lt;code&gt;scan_receipt&lt;/code&gt; (OCR), &lt;code&gt;categorize_expenses&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clients/CRM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;search_clients&lt;/code&gt;, &lt;code&gt;create_client&lt;/code&gt;, &lt;code&gt;client_health_score&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Products&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;list_products&lt;/code&gt;, &lt;code&gt;create_product&lt;/code&gt;, &lt;code&gt;update_stock&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accounting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;trial_balance&lt;/code&gt;, &lt;code&gt;profit_and_loss&lt;/code&gt;, &lt;code&gt;record_journal_entry&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;configure_webhook&lt;/code&gt;, &lt;code&gt;get_dashboard&lt;/code&gt;, &lt;code&gt;export_data&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Every tool has structured output
&lt;/h3&gt;

&lt;p&gt;This was a hard lesson. Early versions returned free-text descriptions. Agents would hallucinate field names, misparse amounts, confuse dates. Now every tool returns &lt;code&gt;outputSchema&lt;/code&gt; + &lt;code&gt;structuredContent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Tool definition with input AND output schema&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;create_invoice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Create a new invoice for a client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Client ID or search term&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;unitPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;taxRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tax rate (e.g., 21 for 21% VAT)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clientId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;outputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;draft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;issued&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;pdfUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5 Resources: static context without API calls
&lt;/h2&gt;

&lt;p&gt;Tools execute actions. But agents also need &lt;strong&gt;reference data&lt;/strong&gt; — tax rates, filing deadlines, expense categories. Making an API call every time the agent needs to know the VAT rate is wasteful.&lt;/p&gt;

&lt;p&gt;MCP Resources solve this. They are static data the agent can read at connection time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frihet://tax/rates          → VAT 21/10/4%, IGIC 7/3/0%, IRPF rates
frihet://tax/calendar       → Quarterly filing deadlines (Modelo 303, 130, 420)
frihet://config/categories  → 8 expense categories with deductibility rules
frihet://config/statuses    → Invoice lifecycle: draft → issued → sent → paid
frihet://api/schema         → All endpoints, auth methods, rate limits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent reads these once and has permanent context. No API calls consumed. No hallucinated tax rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Prompts: guided multi-step workflows
&lt;/h2&gt;

&lt;p&gt;This is where it gets interesting. A Prompt chains multiple tools into a workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monthly-close       → Review unpaid invoices + categorize expenses + tax summary
onboard-client      → Detect tax type by location + create record + welcome quote
quarterly-tax-prep  → Gather period invoices + calculate VAT/IGIC + IRPF preview
overdue-followup    → Find overdue invoices + draft reminders + schedule sends  
collections-report  → Aging analysis + risk scoring + action recommendations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A monthly close that takes an hour of clicking through dashboards becomes a 2-minute conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remote endpoint: zero install
&lt;/h2&gt;

&lt;p&gt;The server runs at &lt;code&gt;mcp.frihet.io&lt;/code&gt; — no npm install needed. Any MCP client can connect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frihet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.frihet.io/sse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer fri_your_api_key"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with Claude Desktop, Cursor, Windsurf, Cline, Gemini CLI, and any MCP-compatible client.&lt;/p&gt;

&lt;p&gt;Or install locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @frihet/mcp-server &lt;span class="nt"&gt;--api-key&lt;/span&gt; fri_your_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I learned building this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Domain-first, not CRUD-first.&lt;/strong&gt; &lt;code&gt;create_invoice&lt;/code&gt; is obvious. &lt;code&gt;monthly_close&lt;/code&gt; is where the real value is. Agents need business workflows, not database operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Structured output is non-negotiable.&lt;/strong&gt; Without &lt;code&gt;outputSchema&lt;/code&gt;, agents hallucinate field names across chained tool calls. One wrong field name cascades into a broken workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Resources eliminate the "context window tax".&lt;/strong&gt; Every time an agent asks "what is the VAT rate in Spain?" and you answer, that is context window wasted. Resources pre-load this knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Security annotations matter.&lt;/strong&gt; Each tool declares if it is &lt;code&gt;readOnly&lt;/code&gt; or mutating, and its &lt;code&gt;impact&lt;/code&gt; level (low/medium/high). Creating an invoice is &lt;code&gt;high&lt;/code&gt; — the agent knows to confirm before executing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The 55-tool ceiling is artificial.&lt;/strong&gt; I could have 200 tools. But agents perform better with fewer, well-designed tools that compose cleanly. 55 covers every business workflow without overwhelming the tool catalog.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;55 tools&lt;/strong&gt; across 6 business domains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 resources&lt;/strong&gt; for tax and configuration context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 prompts&lt;/strong&gt; for guided multi-step workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v1.5.4&lt;/strong&gt; on npm, 1,796 downloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;17 languages&lt;/strong&gt; supported in responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;365 fiscal positions&lt;/strong&gt; across 123 countries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero install&lt;/strong&gt; via remote endpoint at mcp.frihet.io&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The MCP server is open for any Frihet user (free plan included):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://app.frihet.io/register" rel="noopener noreferrer"&gt;Create a free account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Generate an API key in Settings → Integrations&lt;/li&gt;
&lt;li&gt;Add the server config above to your MCP client&lt;/li&gt;
&lt;li&gt;Ask your AI: &lt;em&gt;"Show me my dashboard"&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://docs.frihet.io/mcp" rel="noopener noreferrer"&gt;full documentation&lt;/a&gt; covers every tool, resource, and prompt with examples.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is Part 1 of the "Building an AI-Native ERP" series. Next: how we architected a production ERP with React + Firebase that handles real money.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;&lt;/strong&gt; is a free, AI-native ERP for modern businesses. &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;API Docs&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/sdk" rel="noopener noreferrer"&gt;SDK&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt; · &lt;a href="https://github.com/berthelius/Frihet-ERP" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automate Your Invoicing with Claude Code + n8n + a REST API</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Tue, 10 Mar 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/frihet/automate-your-invoicing-with-claude-code-n8n-a-rest-api-27b0</link>
      <guid>https://dev.to/frihet/automate-your-invoicing-with-claude-code-n8n-a-rest-api-27b0</guid>
      <description>&lt;p&gt;The average freelancer spends 5-8 hours per month on admin tasks that a computer could handle in seconds: sending payment reminders, classifying expenses, generating reports. These tasks aren't difficult. They just shouldn't require your attention.&lt;/p&gt;

&lt;p&gt;Here's how I automated 80% of my business admin with three tools: an ERP with a REST API (&lt;a href="https://frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;), an AI assistant (Claude Code), and a workflow automator (n8n). No coding required.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Pieces
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Your ERP&lt;/strong&gt; — Where invoices, clients, expenses live. The critical requirement: it must have a &lt;strong&gt;REST API&lt;/strong&gt; and &lt;strong&gt;webhooks&lt;/strong&gt;. Without these, automation is impossible. Most ERPs don't offer both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;n8n&lt;/strong&gt; — Visual workflow automator. If X happens, then do Y. Open source, self-hostable, drag-and-drop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code + MCP&lt;/strong&gt; — AI assistant that can interact with your ERP directly through the MCP protocol. You talk, it executes.&lt;/p&gt;

&lt;p&gt;All three have free tiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation 1: Payment Reminders (ROI: Immediate)
&lt;/h2&gt;

&lt;p&gt;The most profitable automation. Unpaid invoices without reminders = money that arrives late or never.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoice becomes overdue (webhook)
    → Wait 3 days (grace period)
    → Check: still unpaid? (API call)
    → Yes → Email reminder to client
    → Wait 7 more days
    → Still unpaid? → Second reminder (firmer tone)
    → Wait 8 more days
    → Still unpaid? → Notify YOU via Telegram
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  n8n Setup (5 nodes)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Webhook Trigger&lt;/strong&gt; — Receives &lt;code&gt;invoice.overdue&lt;/code&gt; event with invoice ID, client, amount, due date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait (3 days)&lt;/strong&gt; — Grace period&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Request&lt;/strong&gt; — &lt;code&gt;GET /v1/invoices/{id}&lt;/code&gt; to check if still unpaid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send Email&lt;/strong&gt; — "Reminder: Invoice [number] pending payment" with payment link&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If/Else&lt;/strong&gt; — Second reminder at day 10, personal notification at day 15&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tone progression matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Day 3: Informational ("We'd like to remind you...")&lt;/li&gt;
&lt;li&gt;Day 10: Direct ("This invoice has been overdue for 10 days")&lt;/li&gt;
&lt;li&gt;Day 15: For you ("Take action on this one")&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automation 2: Weekly Financial Summary
&lt;/h2&gt;

&lt;p&gt;Every Monday at 9:00 you receive your business metrics. No dashboards, no spreadsheets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cron: Monday 9:00
    → GET /v1/invoices?date_from=last_monday
    → GET /v1/expenses?date_from=last_monday
    → Calculate: issued, collected, pending, expenses, net
    → Format message
    → Send via Telegram/Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Included
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Invoices issued this week (count + total)&lt;/li&gt;
&lt;li&gt;Payments received&lt;/li&gt;
&lt;li&gt;Total pending collection&lt;/li&gt;
&lt;li&gt;Expenses recorded&lt;/li&gt;
&lt;li&gt;Net balance (collected - expenses)&lt;/li&gt;
&lt;li&gt;Urgent: invoices due this week&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flow only uses GET endpoints — reads data, presents it usefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation 3: Stripe → Invoice (Auto)
&lt;/h2&gt;

&lt;p&gt;If you collect via Stripe, invoices should create themselves.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stripe payment_intent.succeeded (webhook to n8n)
    → Extract: client email, amount, description
    → Lookup client in ERP by email
    → Client not found? → Create client
    → Create invoice with payment data
    → ERP sends invoice to client automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Client pays on your website → receives invoice in email in under a minute → invoice recorded in ERP with tax compliance. Zero human intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code + MCP: The AI Layer
&lt;/h2&gt;

&lt;p&gt;With an MCP server, Claude Code interacts directly with your ERP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: "Create an invoice for Company ABC for 3 hours
      of consulting at 80 EUR/hour, with 21% VAT"

Claude: [calls create_invoice via MCP]
→ Looks up "Company ABC" in your database
→ Creates invoice: 3 × 80 EUR + 21% VAT = 290.40 EUR
→ Confirms details
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No copy-pasting. No opening the ERP. No calculating VAT.&lt;/p&gt;

&lt;p&gt;Other things Claude can do via MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query current month's invoicing&lt;/li&gt;
&lt;li&gt;List invoices pending payment&lt;/li&gt;
&lt;li&gt;Create quotes for clients&lt;/li&gt;
&lt;li&gt;Search clients by name or tax ID&lt;/li&gt;
&lt;li&gt;Generate expense reports&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Most ERPs Can't Do This
&lt;/h2&gt;

&lt;p&gt;Automation requires three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open API&lt;/strong&gt; — Many ERPs charge extra for API access or don't offer one at all&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real webhooks&lt;/strong&gt; — Events that fire in real-time (not polling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; — For native AI assistant integration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without all three, you're stuck with manual work or fragile workarounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start With One
&lt;/h2&gt;

&lt;p&gt;Don't set up everything at once. Pick the automation that saves you the most time — for most freelancers it's payment reminders — and configure it this week.&lt;/p&gt;

&lt;p&gt;Once it works, add the next. Within a month, 80% of your admin runs on its own.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt; — an ERP with a REST API, 14 webhook events, and an MCP server. If you want to try these automations: &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;app.frihet.io&lt;/a&gt; (free plan). The MCP server is open source: &lt;a href="https://github.com/berthelius/frihet-mcp" rel="noopener noreferrer"&gt;github.com/berthelius/frihet-mcp&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
    <item>
      <title>I Built an MCP Server for My ERP — Here's What I Learned</title>
      <dc:creator>berthelius</dc:creator>
      <pubDate>Wed, 04 Mar 2026 00:44:08 +0000</pubDate>
      <link>https://dev.to/frihet/i-built-an-mcp-server-for-my-erp-heres-what-i-learned-59oe</link>
      <guid>https://dev.to/frihet/i-built-an-mcp-server-for-my-erp-heres-what-i-learned-59oe</guid>
      <description>&lt;p&gt;There's a new way to manage a business. Not an app, not a dashboard, not another browser tab. You talk to your AI assistant and it accesses your invoices, expenses, and clients directly.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt;, an AI-native ERP for freelancers. When Anthropic released the MCP protocol, I knew the ERP needed to speak it natively. So I built an MCP server. Here's what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the MCP Server Does
&lt;/h2&gt;

&lt;p&gt;31 tools across 6 resources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Operations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Invoices&lt;/td&gt;
&lt;td&gt;Create, read, update, delete, search, list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expenses&lt;/td&gt;
&lt;td&gt;Create, read, update, delete, list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clients&lt;/td&gt;
&lt;td&gt;Create, read, update, delete, list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Products&lt;/td&gt;
&lt;td&gt;Create, read, update, delete, list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quotes&lt;/td&gt;
&lt;td&gt;Create, read, update, delete, list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhooks&lt;/td&gt;
&lt;td&gt;Create, read, delete, list&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In practice, you tell Claude:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create an invoice for Acme Ltd for 2,500 EUR for January consulting"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The invoice is created with correct tax details, VAT calculated, and invoice number assigned. No browser needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → AI Assistant (Claude/Cursor)
         ↓ MCP Protocol
    @frihet/mcp-server (npm)
         ↓ REST API calls
    api.frihet.io/v1
         ↓ Auth (X-API-Key)
    Firebase Cloud Functions
         ↓
    Firestore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server is a thin bridge between any MCP client and Frihet's REST API. It runs in two modes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local (stdio):&lt;/strong&gt; For Claude Code, Cursor, Windsurf. Runs as a local process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frihet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@frihet/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"FRIHET_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fri_your_key"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remote (streamable-http):&lt;/strong&gt; Via &lt;code&gt;mcp.frihet.io&lt;/code&gt;, a Cloudflare Worker that accepts MCP connections from anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. MCP tools need great descriptions
&lt;/h3&gt;

&lt;p&gt;The AI reads your tool descriptions to decide which tool to use. Vague descriptions = wrong tool selection. I spent more time writing tool descriptions than writing the actual tool code.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: "create_invoice"
description: "Creates an invoice"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: "create_invoice"
description: "Create a new invoice for a client. Requires client_id, at least one line item with description and amount. Optionally accepts tax_rate, due_date, currency, and notes. Returns the created invoice with assigned number and calculated totals."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Input validation is critical
&lt;/h3&gt;

&lt;p&gt;AI models will send unexpected input shapes. Zod schemas for every tool input saved me from countless edge cases. The AI doesn't always respect your schema perfectly, so validate aggressively and return clear error messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Bilingual tool responses matter
&lt;/h3&gt;

&lt;p&gt;Frihet supports ES and EN. The MCP server accepts a &lt;code&gt;locale&lt;/code&gt; parameter and returns responses in the user's language. This sounds trivial but it makes a huge difference in UX when the AI passes through the response.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The remote MCP is harder than local
&lt;/h3&gt;

&lt;p&gt;Local stdio is straightforward. The remote Cloudflare Worker using streamable-http had more edge cases: CORS, authentication headers, connection timeouts, and the fact that MCP sessions are stateful but Cloudflare Workers are stateless.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Open source builds trust
&lt;/h3&gt;

&lt;p&gt;When your MCP server accesses financial data, users need to trust it. Making it MIT and putting the code on GitHub was a deliberate choice. Users can inspect exactly what the server does with their data. No black boxes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Difference Between API and MCP
&lt;/h2&gt;

&lt;p&gt;Frihet already had a REST API. The MCP server is fundamentally different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API&lt;/strong&gt; = for developers who write code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; = for anyone who uses an AI assistant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A freelancer who doesn't code but uses Claude daily can now manage invoicing without opening a browser. A dev team in Cursor can query company data without switching context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Usage Patterns I've Seen
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Create invoice for [client] for [amount]"&lt;/strong&gt; — Most common. The AI resolves the client by name, applies tax rules, assigns the number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Show unpaid invoices older than 30 days"&lt;/strong&gt; — Uses &lt;code&gt;search_invoices&lt;/code&gt; with filters. The AI formats results into a readable summary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"What's my total revenue this quarter?"&lt;/strong&gt; — Combines multiple API calls. The AI calculates totals from invoice data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Record a 47.50 EUR fuel expense from yesterday"&lt;/strong&gt; — Creates expense with correct date, category suggestion, and VAT deduction.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @frihet/mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://github.com/berthelius/frihet-mcp" rel="noopener noreferrer"&gt;github.com/berthelius/frihet-mcp&lt;/a&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/@frihet/mcp-server" rel="noopener noreferrer"&gt;@frihet/mcp-server&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://docs.frihet.io" rel="noopener noreferrer"&gt;docs.frihet.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT license. 31 tools. Works with Claude Code, Cursor, Windsurf, and any MCP client.&lt;/p&gt;

&lt;p&gt;If you're building an MCP server for your product, happy to share more details in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Viktor, solo founder of &lt;a href="https://frihet.io" rel="noopener noreferrer"&gt;Frihet&lt;/a&gt; — an AI-native ERP for freelancers. Free plan, no credit card: &lt;a href="https://app.frihet.io" rel="noopener noreferrer"&gt;app.frihet.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
