概要
AnythingMCP のコードモードのステップバイステップ チュートリアル。コードランナーを起動し、コードモードを有効にして、ERP(weclapp)の直近の受注と CRM(HubSpot)のアカウントおよび進行中の案件を 1 回のツール呼び出しで読み取るコードツールを保存します。読み取り専用で、呼び出し元の権限で実行され、監査されます。
TL;DR: 顧客との通話の前に、営業担当者がアシスタントに概要を尋ねます。ERP の直近の受注と、CRM のアカウント担当者および進行中の案件です。コードモードがない場合、ツール呼び出しは 4〜5 回になり、モデルはそれぞれの結果を全文読み込みます。保存済みコードツールなら 1 回で済みます。customer_overview(customer) が短い JavaScript プログラムを実行し、呼び出しを行い、重要な情報だけを残して、コンパクトな 1 つのサマリーを返します。このチュートリアルでは、セルフホストの AnythingMCP(v0.52.1 以降)で、ERP に weclapp、CRM に HubSpot を使ってこのツールを作成します。同じパターンは、任意の 2 つのコネクタで使えます。
必要なもの
- セルフホストの AnythingMCP v0.52.1 以降。 コードモードは AnythingMCP Cloud で近日公開予定です。
- 読み取りツールを持つ 2 つのコネクタ。 ここでは weclapp と HubSpot で、インストール済みで動作していること。
- ワークスペースの管理者権限。
この考え方が初めてですか?MCP コードモードとは?で、1 つのプログラムが多数のツール呼び出しよりも優れている理由を説明しています。
ステップ 1 — コードランナーを起動する
コードが AnythingMCP 自体の内部で実行されることはありません。コードは別の code-runner コンテナで実行され、これがないとすべてのコード実行が拒否されます。.env に次を追加します。
COMPOSE_PROFILES=code-runner
CODE_RUNNER_URL=ws://code-runner:8777
すでにプロファイルを使っている場合は、COMPOSE_PROFILES=files,code-runner のようにまとめて列挙します。その後、次を実行します。
docker compose up -d
ランナーはシークレットを保持せず、ポートを公開せず、インターネットへの経路もありません。通信するのはバックエンドだけで、内部 Docker ネットワーク上で行われます。各実行をどのように分離しているかは、AI エージェントのための安全なコード実行をご覧ください。
ステップ 2 — MCP サーバーのコードモードを有効にする
コードモードは MCP サーバーごとにデフォルトでオフになっており、コードモードが off のサーバーでは保存済みコードツールは拒否されます。営業チームが使うサーバーのコードモードを tools(保存済みコードツールのみ)に設定します。inline では、さらにエージェントに code_execute と code_propose_tool が提供されますが、このチュートリアルでは不要です。
ダッシュボードで MCP Servers を開き、対象のサーバーを開きます。上部の Server settings カードで Code mode を Saved code tools only に設定し、Save をクリックします。その後、AI クライアントを再接続します。
API を使う場合は、PUT /api/mcp-servers/<id> に {"codeMode": "tools"} を送っても同じです。この設定は v0.52.1 で追加されました。v0.52.0 の場合は先にアップデートしてください。
ステップ 3 — 2 つのコネクタの ID を控える
コードツールは、プログラムが呼び出せるコネクタを宣言します。ダッシュボードで各コネクタを開くと、ID はアドレスの末尾、/connectors/<id> の部分です。weclapp コネクタと HubSpot コネクタの ID をコピーしてください。
ステップ 4 — コードツールを作成する
weclapp コネクタを開き、MCP Tools に移動して Add Tool をクリックします。Tool Type を Code Tool に設定し、次を入力します。
- Tool Name:
customer_overview - Description: 「通話前の 1 社の顧客概要:ERP の直近 10 件の受注、CRM のアカウント、進行中の案件。会社名またはその一部を渡してください。」説明文は、AI がツールをいつ呼び出すかを判断するために読むものなので、何を返すかを書いてください。
- Input Parameters: パラメータは 1 つ、
customer、型は string、必須。

ステップ 5 — プログラムを書く
Program は、非同期 JavaScript 関数の本体です。ツールの入力は args に入っています。amcp.run(name, args) は別のツールを呼び出し、その結果をパース済みの JSON として返します(ツールが失敗した場合は例外をスローします)。return したものが、そのまま AI に渡されます。
// Input: args.customer, a company name or part of it.
const name = String(args.customer ?? '').trim();
if (!name) return { error: 'Pass a customer name.' };
// ERP (weclapp): the customer, then its latest sales orders.
const parties = await amcp.run('weclapp_list_customers', {
filter: `company-ilike=%${name}%`,
pageSize: 5,
});
const customer = (parties.result ?? [])[0];
if (!customer) return { error: `No customer matching "${name}" in the ERP.` };
const orders = await amcp.run('weclapp_list_sales_orders', {
filter: `customerId-eq=${customer.id}`,
sort: '-orderDate',
pageSize: 10,
});
// CRM (HubSpot): the company record and its open deals.
const companies = await amcp.run('hubspot_search_objects', {
object_type: 'companies',
query: customer.company,
properties: ['name', 'domain', 'hubspot_owner_id', 'lifecyclestage'],
limit: 1,
});
const company = companies.results?.[0];
let deals = [];
if (company) {
const found = await amcp.run('hubspot_search_objects', {
object_type: 'deals',
filter_groups: [{ filters: [
{ propertyName: 'associations.company', operator: 'EQ', value: company.id },
{ propertyName: 'hs_is_closed', operator: 'EQ', value: 'false' },
] }],
properties: ['dealname', 'amount', 'dealstage', 'closedate'],
limit: 20,
});
deals = found.results ?? [];
}
// Only this goes back to the model.
return {
customer: { number: customer.customerNumber, name: customer.company },
lastOrders: (orders.result ?? []).map((o) => ({
number: o.orderNumber, date: o.orderDate, status: o.status, net: o.netAmount,
})),
crm: company
? { owner: company.properties.hubspot_owner_id, stage: company.properties.lifecyclestage }
: null,
openDeals: deals.map((d) => ({
name: d.properties.dealname, amount: d.properties.amount,
stage: d.properties.dealstage, close: d.properties.closedate,
})),
};
フィールド名は、weclapp と HubSpot の API が返すものです。フィールドに依存する前に、基となるツールを Test パネルで一度実行して結果を確認してください。プログラム内では、await amcp.describe('weclapp_list_sales_orders') でツールの入力スキーマを取得できます。
結合についての補足。 このプログラムは CRM の会社を名前で照合します。事前ブリーフィング用途であれば十分です。ERP の顧客番号を HubSpot のプロパティに保存している場合は、代わりにそれでフィルタすれば、完全に一致させられます。
ステップ 6 — プログラムが使えるものを宣言する
Uses (connectors) には、プログラムが呼び出せるコネクタ、および必要に応じて正確なツールを列挙します。ステップ 3 の 2 つの ID を貼り付けます。
[
{ "connectorId": "<weclapp connector id>", "tools": ["weclapp_list_customers", "weclapp_list_sales_orders"] },
{ "connectorId": "<hubspot connector id>", "tools": ["hubspot_search_objects"] }
]
ツールを指定するのは任意です("tools" がなければコネクタ全体が許可されます)が、短いリストにしておくとツールをレビューしやすくなります。受け付けられるのは同じワークスペースのコネクタだけです。このリスト外のツールは、ユーザーが直接呼び出せる場合でもエラーで失敗します。
ステップ 7 — 呼び出し元として実行、読み取り専用
- Run as: Invoker(呼び出し元自身の権限)。 内部の呼び出しはすべて、ツールを使う人のロールに照らして確認されます。HubSpot へのアクセス権がない担当者は、HubSpot を直接呼び出した場合と同じように、HubSpot の部分でエラーになります。(Definer は、ストアドプロシージャのように作成者のキュレーションで実行されます。管理者と Enterprise 向けです。)
- Allow write tools: オフ。 この場合、プログラムは読み取り専用のツールしか呼び出せません。
weclapp_list_*とhubspot_search_objectsは読み取りです。書き込み可能なコードツールには Enterprise が必要です。
Create Tool をクリックします。
ステップ 8 — Claude または ChatGPT から試す
まず、ダッシュボードでツールの Test ボタンを使ってプログラムを確認します。コードは code runner で、実際の呼び出しと同じルールで実行されます。その後、MCP サーバーに接続した AI クライアントから試します。このツールは、weclapp コネクタがあり、コードモードがオンになっているすべてのサーバーで利用できます。AI クライアントを再接続するかツールを更新して、次のように尋ねてください。
「10 分後に Lindenhof Bau に電話します。最近何を注文したか、アカウント担当は誰か、進行中の案件はあるか教えてください。」
アシスタントは customer_overview を 1 回呼び出し、受注一覧や CRM レコードの全文を読む代わりに、コンパクトな結果からブリーフィングを作成します。何か問題があれば、ツールの結果にその内容が表示されます。Uses 外の呼び出し('hubspot_search_objects' is not a tool this code tool can use)、API が返したエラー、またはタイムアウトなどです。プログラムを修正して保存し、もう一度尋ねてください。
呼び出しごとに起こること
- 1 回の実行、1 件の記録。 ツールの各呼び出しはコード実行として記録され、プログラムが行うすべてのツール呼び出しも、他の呼び出しと同様にユーザー情報とともに監査ログに残ります。
- 制限。 1 回の実行は最大 10 秒、ツール呼び出しは最大 500 回(同時 16 件まで)、返せるデータは最大 1 MB です。制限を超えたプログラムは明確なエラーで停止し、他には影響しません。
- ネスト不可。 コードツールから別のコードツールを呼び出すことはできません。
- 自社のサーバーのみ。 コードツールは、ワークスペース自身の MCP サーバーで提供され、共有の
/mcpエンドポイントでは提供されません。
プラン
v0.52 で発表された、エディションごとの保存済みコードツール数は次のとおりです。Community 3、Starter 5、Team 20、Enterprise は無制限。書き込み可能なコードツールと「definer として実行」は Enterprise です。プランを比較する。
FAQ
JavaScript の知識は必要ですか?
基本的な JavaScript で十分です。await、オブジェクト、map と filter が分かれば問題ありません。エージェントにプログラムの下書きを作らせ、レビューのためにツールとして提案してもらうこともできます。
プログラムから外部 API を直接呼び出せますか? いいえ。ネットワークアクセスはありません。呼び出せるのは Uses に列挙された MCP ツールだけです。別の API を利用するには、まずコネクタとして追加してください。
コードツールはどのコネクタに置くべきですか? 使用するコネクタのどれでも構いません。ツールは、そのコネクタが割り当てられている場所すべてに表示されます。ツールを提供したい対象に合ったコネクタを選んでください。
関連記事
- MCP コードモードとは?
- AI エージェントのための安全なコード実行:分離されたランナーのしくみ
- コードモードのレシピ:月次売上、請求書の照合、100 件の価格検索
- エージェントがコードツールを提案し、管理者が承認する
- AI から ERP を操作する:weclapp
- Docker Compose で AnythingMCP をデプロイする
- weclapp と HubSpot を Claude に接続する
このガイドは役に立ちましたか?