入门阅读约 1 分钟7 种语言

MCP 代码模式实战:一次调用完成月度营收统计、发票对账和 100 次价格查询

AnythingMCP 的三个实用代码模式程序:汇总网店(Shopify)与财务系统(Lexware Office)的月度营收、将订单与发票对账,以及一次工具调用完成 100 次客户价格查询,而不是调用 100 次。包含代码、需要注意的关键限制,以及何时把程序保存为工具。

HC作者:HelpCode 团队更新于 1 分钟阅读 在 GitHub 开源

无需信用卡 · 7 天试用 · 提供自托管方案

  • 7 天免费试用
    无需信用卡
  • 符合 GDPR,SOC 2 就绪
    数据驻留欧盟,审计日志
  • 在 GitHub 开源
    开源 · AGPL-3.0
  • 支持 ChatGPT、Claude、Gemini
    任何兼容 MCP 的客户端

摘要

AnythingMCP 的三个实用代码模式程序:汇总网店(Shopify)与财务系统(Lexware Office)的月度营收、将订单与发票对账,以及一次工具调用完成 100 次客户价格查询,而不是调用 100 次。包含代码、需要注意的关键限制,以及何时把程序保存为工具。

TL;DR: 代码模式适用于这样的场景:智能体原本需要重复发起同一个调用很多次,或者需要读两份很长的列表来做比对。这三个示例展示了对应的模式:跨两个系统求和、匹配两份列表、对多个条目重复同一次查询。每个示例都是一小段 JavaScript 程序,通过 amcp.run 调用 MCP 工具,只返回最终结果。你可以直接内联运行(由智能体通过 code_execute 编写程序),也可以将其保存为代码工具,供团队按名称调用。代码模式在自托管的 AnythingMCP v0.52.0 起可用,AnythingMCP Cloud 即将支持。

刚接触代码模式?请先阅读什么是 MCP 代码模式?和创建你的第一个代码工具。

复制程序之前

  • 工具名称是真实的,返回结构因情况而异。 这些示例使用的是 Shopify 和 Lexware Office 连接器中的工具。字段名称以各 API 的返回为准;在依赖某个字段之前,先在工具的 Test 面板中运行一次,或在程序内调用 amcp.describe(name)。
  • 每次运行 10 秒。 运行超过 10 秒会被停止。请并行获取分页数据并并行执行相互独立的调用(同时最多 16 个),而不是逐个顺序执行。
  • 只读。 内联代码绝不会调用会修改数据的工具;已保存的代码工具只有在管理员允许时才可以(企业版)。这三个示例都只读取数据。
  • 数据均为虚构。 所示结果都是虚构的示例。

示例 1 — 汇总网店与财务系统的月度营收

问题:“我们 10 月的营收是多少:网店加上 B2B 发票?”

不使用代码模式时,智能体需要翻阅数百条网店订单和发票,把每条记录都读进上下文,再靠“阅读”来累加数字。使用代码模式,它只会拿到两个总数。

// 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,
};

返回的是四个数字,而不是 600 条记录:

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

在信任总数之前,先核对统计口径。 如果网店订单同样在财务系统中开具了发票,两者相加就会重复计算;此时应把发票筛选为仅限 B2B 客户。这里的两个数字都是含税总额,币种为网店和账簿使用的币种;退款和贷项通知单没有被扣除。请把这些决定写进工具的描述里,这样 AI 才能说明这个数字的含义。

示例 2 — 没有发票的订单,没有订单的发票

问题:“上个月哪些已付款的网店订单在财务系统中没有发票,哪些金额对不上?”

这是模型靠“阅读”最不擅长的任务:两份各有几百行的列表,要靠肉眼比对。用代码来做,就是一次字典查找。

// 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 };

为了让匹配逻辑便于阅读,这个版本把两份列表作为输入参数。在已保存的代码工具中,请在程序内部用示例 1 中的分页循环来获取它们(订单来自 shopify_search_orders,发票来自 lexware_office_list_vouchers,需要引用字段时再加上 lexware_office_get_invoice),这样 AI 只需传入一个月份调用一个工具,就能拿到三份简短的列表:

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

示例 3 — 一次调用完成 100 次价格查询,而不是 100 次

问题:“这是客户询价单里的 100 个物料号。这位客户的价格分别是多少?”

许多 ERP 会针对每个物料和每位客户计算专属价格,而且一次只能处理一个请求。假设你为 ERP 自建的 REST 连接器中有一个工具 erp_get_customer_price,输入为 article 和 customer(这只是示例名称;参见如何把 REST API 转换为 MCP 工具)。不使用代码模式时,智能体要发起 100 次调用并读取 100 个结果。使用代码模式:

// 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),
};

每次同时运行十个调用,所以每次耗时几百毫秒的 100 次查询,可以轻松在 10 秒限制内完成。某个物料查询失败不会中断其余查询,它会被归入 notFound。模型收到的是一张表格,可以直接转成报价草稿或电子邮件,而不是 100 条独立的工具结果。

先确认你是否真的需要代码。 如果 API 可以在一次请求中按物料列表过滤(例如 weclapp 就可以用 in 运算符过滤物料号),那么一次普通的工具调用会更简单。代码模式适用于做不到这一点的 API。

内联还是保存?

内联(code_execute)已保存的代码工具
谁来编写程序智能体,针对当前问题管理员,一次编写(或由智能体提议)
适用场景一次性分析、探索团队每周都会问的问题
权限调用者自己的权限,只读调用者或定义者的权限,除非获准写入(企业版),否则只读
版本(随 v0.52 公布)团队版和企业版社区版 3 个,入门版 5 个,团队版 20 个,企业版不限

智能体在内联模式下解决了两次的模式,就适合保存为工具。启用内联代码后,智能体可以提议保存,管理员一键即可批准。

FAQ

这些程序可以写入数据吗,比如创建缺失的发票? 内联不行。已保存的代码工具只有在管理员开启 Allow write tools 后才能调用写入类工具,这需要企业版。对于任何会修改数据的操作,请保持程序只读,并由人来确认该操作。

如果一次运行需要超过 10 秒怎么办? 拆分任务:按月运行而不是按年,或者每次调用处理更少的条目。超出限制的运行会报错停止;由于程序只读取数据,不会留下写了一半的结果。

程序会把我的数据发送到别处吗? 不会。程序运行在没有网络的隔离运行器中,只能在你的角色权限下通过 MCP 工具访问你的系统。参见AI 智能体的安全代码执行。

相关内容

这份指南对你有帮助吗?

60 秒内把 MCP 接入你的技术栈。

在托管云上启动 AnythingMCP,或在你自己的基础设施上自托管。免费试用 7 天,无需信用卡。

相关指南

GS
入门

代码模式:通过一步运行工具削减 AI 智能体的 token 用量

代码模式让 AI 智能体运行一段简短程序,在一次调用中编排多个 MCP 工具,而不必对每个工具都往返一次。筛选和关联都在锁定的沙箱中完成,因此只返回最终结果——在数据密集型工作流中可将 token 用量最多降低 90–99%。

GS
入门

构建你的第一个 MCP 代码工具:一次调用获取 ERP 订单和 CRM 客户账户

AnythingMCP 代码模式分步教程:启动 code runner,开启代码模式,并保存一个代码工具,在一次工具调用中读取 ERP(weclapp)中的最近订单,以及 CRM(HubSpot)中的客户账户和未结商机。只读,使用调用者的权限,并记录审计日志。

GS
入门

什么是 MCP 代码模式?为 AI 智能体减少 token 消耗与往返次数

代码模式让 AI 智能体运行一段调用多个 MCP 工具的简短程序,而不是通过模型逐个调用这些工具。本文介绍为什么这样可以节省 token 和往返次数、何时有用、何时没用,以及 AnythingMCP 如何在隔离的运行器中提供三种形式:已保存的代码工具、内联代码和智能体提案。

GS
入门

MCP 知识图谱:一个会学习你的系统如何关联的连接器

AnythingMCP 不只是 MCP 代理——它会为你的工具构建一张知识图谱,让 AI 智能体知道如何把 CRM 里的客户串联到 ERP 里的订单。下面看看这个智能连接器如何工作。

GS
入门

模型上下文协议 (MCP) 是什么?

全面了解模型上下文协议的指南 — 它是如何工作的,为什么重要,以及如何开始使用。

GS
入门

开始使用 AnythingMCP

在几分钟内安装和配置 AnythingMCP。克隆代码库,运行交互式设置脚本,并开始将你的 API 连接到 AI 代理。