Getting started5-minute read7 languages

MCP Code Mode Recipes: Monthly Revenue, Invoice Reconciliation and 100 Price Lookups in One Call

Three practical code mode programs for AnythingMCP: monthly revenue across the online shop (Shopify) and accounting (Lexware Office), orders reconciled against invoices, and 100 customer price lookups in one tool call instead of 100. With the code, the limits that matter, and when to save a program as a tool.

HCBy HelpCode teamUpdated 5 min read Open-source on GitHub

No credit card · 7-day trial · Self-host alternative available

  • 7-day free trial
    No credit card required
  • GDPR & SOC 2 ready
    EU data residency, audit logs
  • Open-source on GitHub
    Open source · AGPL-3.0
  • Works with ChatGPT, Claude, Gemini
    Any MCP-compatible client

Summary

Three practical code mode programs for AnythingMCP: monthly revenue across the online shop (Shopify) and accounting (Lexware Office), orders reconciled against invoices, and 100 customer price lookups in one tool call instead of 100. With the code, the limits that matter, and when to save a program as a tool.

TL;DR: Code mode pays off where an agent would otherwise make the same call many times or read two long lists to compare them. These three recipes show the pattern: sum across two systems, match two lists, repeat one lookup for many items. Each is a short JavaScript program that calls MCP tools through amcp.run and returns only the result. Run them inline (the agent writes the program with code_execute) or save them as code tools your team calls by name. Code mode is available in self-hosted AnythingMCP from v0.52.0 and coming soon to AnythingMCP Cloud.

New to code mode? Start with What is MCP code mode? and Build your first code tool.

Before you copy a program

  • Tool names are real, shapes vary. The recipes use tools of the Shopify and Lexware Office connectors. Field names follow each API's response; run a tool once in its Test panel, or call amcp.describe(name) inside a program, before relying on a field.
  • Ten seconds per run. A run stops after 10 seconds. Fetch pages and run independent calls in parallel (at most 16 at a time) rather than one after another.
  • Read-only. Inline code never calls tools that change data; saved code tools may only when an administrator allows it, on Enterprise. All three recipes only read.
  • Invented figures. The results shown are invented examples.

Recipe 1 — Monthly revenue across shop and accounting

The question: "What was our revenue in October: online shop plus B2B invoices?"

Without code mode, the agent pages through hundreds of shop orders and invoices, reading every record into its context, and adds numbers by reading. With code mode it gets two totals.

// Input: args.month as "YYYY-MM", e.g. "2026-10".
const [y, m] = String(args.month).split('-').map(Number);
const from = `${y}-${String(m).padStart(2, '0')}-01`;
const to = m === 12 ? `${y + 1}-01-01` : `${y}-${String(m + 1).padStart(2, '0')}-01`;

// Shop: paid orders created in the month (Shopify search syntax), 250 per page.
let shop = 0, shopOrders = 0, after = undefined;
do {
  const res = await amcp.run('shopify_search_orders', {
    query: `created_at:>=${from} created_at:<${to} financial_status:paid test:false`,
    first: 250,
    after,
  });
  const page = res.orders ?? res.data?.orders; // depends on how the tool wraps the GraphQL result
  for (const o of page.nodes) {
    shop += Number(o.currentTotalPriceSet.shopMoney.amount);
    shopOrders++;
  }
  after = page.pageInfo.hasNextPage ? page.pageInfo.endCursor : undefined;
} while (after);

// Accounting: sales invoices dated in the month, without drafts and voided ones.
let b2b = 0, invoices = 0, p = 0, last = false;
const lastDay = new Date(Date.UTC(y, m, 0)).toISOString().slice(0, 10);
while (!last) {
  const res = await amcp.run('lexware_office_list_vouchers', {
    voucherType: 'salesinvoice',
    voucherStatus: 'open,paid,paidoff',
    voucherDateFrom: from,
    voucherDateTo: lastDay,
    size: 250,
    page: p++,
  });
  for (const v of res.content ?? []) { b2b += Number(v.totalAmount); invoices++; }
  last = res.last ?? true;
}

return {
  month: args.month,
  shop: { orders: shopOrders, gross: Math.round(shop * 100) / 100 },
  invoices: { count: invoices, gross: Math.round(b2b * 100) / 100 },
  total: Math.round((shop + b2b) * 100) / 100,
};

What comes back is four numbers, not 600 records:

{ "month": "2026-10", "shop": { "orders": 412, "gross": 38214.9 }, "invoices": { "count": 57, "gross": 91380.12 }, "total": 129595.02 }

Check the definition before you trust the total. If shop orders are also invoiced in accounting, adding both counts them twice; filter the invoices to B2B customers then. Both figures here are gross amounts in the shop's and the books' currency; refunds and credit notes are not subtracted. Write these decisions into the tool's description, so the AI says what the number means.

Recipe 2 — Orders without an invoice, invoices without an order

The question: "Which paid shop orders from last month have no invoice in accounting, and which amounts do not match?"

This is the task models are worst at by reading: two lists of a few hundred lines each, compared by eye. In code it is a dictionary lookup.

// Where your accounting keeps the shop order number. Adapt to your setup:
// many shop integrations write it into the invoice's reference or title.
const orderRefOf = (invoice) => invoice.orderReference;

const orders = args.orders;     // [{ name: "#1042", total: 89.9 }, ...] from a first step
const invoices = args.invoices; // [{ orderReference: "#1042", totalAmount: 89.9, voucherNumber: "RE0815" }, ...]

const byOrder = new Map(invoices.map((i) => [orderRefOf(i), i]));
const missing = [], mismatched = [];
for (const o of orders) {
  const inv = byOrder.get(o.name);
  if (!inv) missing.push(o.name);
  else if (Math.abs(Number(inv.totalAmount) - Number(o.total)) > 0.01)
    mismatched.push({ order: o.name, invoice: inv.voucherNumber, order_total: o.total, invoice_total: inv.totalAmount });
}
const orderNames = new Set(orders.map((o) => o.name));
const orphanInvoices = invoices.filter((i) => !orderNames.has(orderRefOf(i))).map((i) => i.voucherNumber);

return { checked: orders.length, missing, mismatched, orphanInvoices };

This version takes both lists as inputs to keep the matching logic readable. In a saved code tool, fetch them inside the program with the paging loops from recipe 1 (orders from shopify_search_orders, invoices from lexware_office_list_vouchers, plus lexware_office_get_invoice where you need the reference field), so the AI calls one tool with a month and gets three short lists back:

{ "checked": 412, "missing": ["#1077", "#1139"], "mismatched": [{ "order": "#1101", "invoice": "RE0902", "order_total": 129.0, "invoice_total": 119.0 }], "orphanInvoices": [] }

Recipe 3 — 100 price lookups in one call instead of 100

The question: "Here are 100 article numbers from the customer's enquiry. What are this customer's prices?"

Many ERPs calculate a customer-specific price per article and customer, one request at a time. Suppose your own REST connector for the ERP has a tool erp_get_customer_price with the inputs article and customer (an example name; how to turn a REST API into MCP tools). Without code mode the agent makes 100 calls and reads 100 results. With code mode:

// Inputs: args.customer, args.articles (array of article numbers).
const articles = [...new Set(args.articles.map(String))];
const rows = [];
const BATCH = 10; // at most 16 calls may be in flight at once

for (let i = 0; i < articles.length; i += BATCH) {
  const batch = articles.slice(i, i + BATCH);
  const results = await Promise.all(batch.map(async (article) => {
    try {
      const r = await amcp.run('erp_get_customer_price', { article, customer: args.customer });
      return { article, price: r.netPrice, unit: r.priceUnit, currency: r.currency };
    } catch (e) {
      return { article, error: String(e.message ?? e) };
    }
  }));
  rows.push(...results);
}

return {
  customer: args.customer,
  found: rows.filter((r) => !r.error).length,
  notFound: rows.filter((r) => r.error).map((r) => r.article),
  prices: rows.filter((r) => !r.error),
};

Ten calls run at a time, so 100 lookups at a few hundred milliseconds each finish well inside the 10-second limit. One failing article does not stop the rest; it lands in notFound. The model receives one table it can turn into a quote draft or an e-mail, instead of 100 separate tool results.

First check whether you need code at all. If the API can filter by a list of articles in one request (weclapp, for example, filters article numbers with an in operator), a single ordinary tool call is simpler. Code mode is for the APIs that cannot.

Inline or saved?

Inline (code_execute)Saved code tool
Who writes the programThe agent, for this questionAn administrator, once (or the agent proposes it)
Good forOne-off analysis, exploringQuestions the team asks every week
PermissionsThe caller's own, read-onlyInvoker or definer, read-only unless allowed to write (Enterprise)
Edition (as announced with v0.52)Team and EnterpriseCommunity 3, Starter 5, Team 20, Enterprise unlimited

A pattern the agent solves inline twice is a candidate for a saved tool. With inline code enabled, the agent can propose it and an administrator approves it with one click.

FAQ

Can these programs write, e.g. create the missing invoices? Not inline. A saved code tool can call write tools only when an administrator turns on Allow write tools, which needs Enterprise. For anything that changes data, keep the program read-only and let a person confirm the action.

What if a run needs more than 10 seconds? Split it: one run per month instead of a year, or fewer items per call. Runs that exceed a limit stop with an error; nothing is half-written, because they only read.

Is my data sent anywhere by the program? No. The program runs in an isolated runner with no network. It reaches your systems only through the MCP tools, under your role. See Secure code execution for AI agents.

Was this guide helpful?

Ship MCP to your stack in 60 seconds.

Spin up AnythingMCP on managed Cloud or self-host it on your infrastructure. Free for 7 days, no credit card.

Related guides

GS
Getting started

Code Mode: Cut AI Agent Token Usage by Running Tools in One Step

Code mode lets an AI agent run a short program that orchestrates many MCP tools in a single call, instead of one round trip per tool. Filtering and joining happen in a locked-down sandbox, so only the final answer returns — cutting token usage on data-heavy workflows by up to 90–99%.

GS
Getting started

Build Your First MCP Code Tool: ERP Orders and CRM Account in One Call

A step-by-step tutorial for AnythingMCP code mode: start the code runner, turn code mode on, and save a code tool that reads the last orders from the ERP (weclapp) and the account and open deals from the CRM (HubSpot) in one tool call. Read-only, with the caller's permissions, audited.

GS
Getting started

What Is MCP Code Mode? Fewer Tokens and Round Trips for AI Agents

Code mode lets an AI agent run one short program that calls several MCP tools, instead of calling them one at a time through the model. Why that saves tokens and round trips, when it helps and when it does not, and how AnythingMCP runs it: saved code tools, inline code and agent proposals, in an isolated runner.

GS
Getting started

Connect AnythingMCP to Claude: One URL for All Your Business APIs

Add AnythingMCP as a Claude connector in five minutes. Sign in, pick the MCP servers Claude may reach, and query weclapp, DATEV, Etsy, Deutsche Bahn or your own API in plain language.

GS
Getting started

The MCP Knowledge Graph: a connector that learns how your systems connect

AnythingMCP isn't just an MCP proxy — it builds a knowledge graph of your tools so AI agents know how to chain a customer in your CRM to their orders in your ERP. Here's how the smart connector works.

GS
Getting started

What is the Model Context Protocol (MCP)?

A comprehensive guide to understanding the Model Context Protocol — how it works, why it matters, and how to get started.