معرفی کوتاه: Model Context Protocol (MCP) به شیوهی استانداردی تبدیل شده که عاملهای هوش مصنوعی از ابزارهای بیرونی استفاده میکنند. اما یک تنش اساسی وجود دارد: عاملها برای انجام کار مفید به ابزارهای متعددی نیاز دارند، در حالی که هر ابزار جدید، از پنجرهٔ کانتکست مدل (context window) مصرف میکند و فضای کمتری برای خودِ وظیفه باقی میماند. Code Mode راهحلی است برای کاهش استفاده از کانتکست هنگام کار با ابزارها — بهجای تعریف هزاران ابزار مجزا، اجازه بدهید مدل کد بنویسد و علیه یک typed SDK اجرا شود و آن کد در یک Dynamic Worker Loader ایمن اجرا شود. کد نقش یک نقشهٔ فشرده را بازی میکند: مدل میتواند عملیات ابزارها را کاوش کند، چند فراخوانی را ترکیب کند و تنها دادهٔ مورد نیاز را برگرداند. (Anthropic هم الگوی مشابهی را در پست Code Execution with MCP بررسی کرده است.) 🚀
امروز یک MCP server جدید معرفی شد که کل Cloudflare API — از DNS و Zero Trust تا Workers و R2 — را با استفاده از Code Mode فراهم میکند. این سرور تنها دو ابزار دارد: search() و execute()؛ که همهٔ API را از طریق MCP در دسترس قرار میدهند و در عین حال تنها حدود 1,000 tokens مصرف میکنند. به عبارت دیگر، اندازهٔ راهحل ثابت میماند، فارغ از اینکه چند endpoint وجود داشته باشد.
برای یک API بزرگ مثل Cloudflare، Code Mode تعداد توکنهای ورودی را تا 99.9% کاهش میدهد. نسخهای معادل از MCP بدون Code Mode حدود 1.17 میلیون توکن مصرف میکرد — بیشتر از کل context window در پیشرفتهترین مدلهای پایه. اگر علاقهمند باشید، این Cloudflare MCP server قابل استفاده است و همچنین یک Code Mode SDK جدید در Cloudflare Agents SDK متنباز شده تا شما هم همین الگو را در MCP serverها و AI Agents خود پیادهسازی کنید.
Server‑side Code Mode: در این طراحی، Code Mode در سمت سرور اجرا میشود. بهجای هزاران ابزار، سرور فقط دو ابزار export میکند: search() و execute(). هر دو با Code Mode کار میکنند. سطح ابزار (tool surface) که در کانتکست مدل قرار میگیرد به شکل زیر است:
[pyaml]
[
{
“name”: “search”,
“description”: “Search the Cloudflare OpenAPI spec. All $refs are pre-resolved inline.”,
“inputSchema”: {
“type”: “object”,
“properties”: {
“code”: {
“type”: “string”,
“description”: “JavaScript async arrow function to search the OpenAPI spec”
}
},
“required”: [“code”]
}
},
{
“name”: “execute”,
“description”: “Execute JavaScript code against the Cloudflare API.”,
“inputSchema”: {
“type”: “object”,
“properties”: {
“code”: {
“type”: “string”,
“description”: “JavaScript async arrow function to execute”
}
},
“required”: [“code”]
}
}
]
[/yaml]
شیوه کار: برای کشف قابلیتها عامل اول search() را صدا میزند. عامل مشغول نوشتن JavaScript بر پایهٔ یک نمای typed از OpenAPI spec میشود. عامل میتواند endpointها را بر اساس product، path، tags یا هر متادیتای دیگری فیلتر کند و هزاران endpoint را تا چند مورد مرتبط محدود کند. خودِ OpenAPI spec هیچگاه وارد کانتکست مدل نمیشود؛ عامل فقط از طریق کد با آن تعامل دارد.
وقتی عامل آمادهٔ اقدام شد، از execute() استفاده میکند. عامل کدی مینویسد که میتواند درخواستهای Cloudflare API را بفرستد، pagination را مدیریت کند، پاسخها را بررسی کند و چند عملیات را در یک اجرای واحد زنجیر کند. هر دو ابزار کد تولیدشده را داخل یک Dynamic Worker isolate اجرا میکنند — یک sandbox سبک مبتنی بر V8 با هیچ فایلسیستم، بدون محیط متغیر( environment variables) که از طریق prompt injection نشت پیدا کند، و fetch خارجی بهصورت پیشفرض غیرفعال است. درخواستهای outbound تنها وقتی لازم باشد میتوانند با outbound fetch handlers کنترل شوند. 🔒
مثال عملی — محافظت از origin در برابر حملات DDoS: فرض کنید کاربر به عامل میگوید: “protect my origin from DDoS attacks.” اولین قدم عامل مراجعه به مستندات است (مثلاً Cloudflare Docs MCP Server یا جستجو). از مستندات میفهمد که باید WAF و DDoS protection rules را جلوی origin قرار دهد.
گام 1: پیدا کردن endpointهای مرتبط — ابزار search یک شی spec را در اختیار مدل قرار میدهد: کل OpenAPI spec با $refs از پیش حلشده. مدل یک JavaScript مینویسد تا endpointهای WAF و ruleset مربوط به یک zone را پیدا کند:
[pyaml]
async () => {
const results = [];
for (const [path, methods] of Object.entries(spec.paths)) {
if (path.includes(‘/zones/’) && (path.includes(‘firewall/waf’) || path.includes(‘rulesets’))) {
for (const [method, op] of Object.entries(methods)) {
results.push({ method: method.toUpperCase(), path, summary: op.summary });
}
}
}
return results;
}
[/yaml]
سرور این کد را در یک Workers isolate اجرا میکند و خروجی مشابه زیر برمیگردد:
[pyaml]
[
{ “method”: “GET”, “path”: “/zones/{zone_id}/firewall/waf/packages”, “summary”: “List WAF packages” },
{ “method”: “PATCH”, “path”: “/zones/{zone_id}/firewall/waf/packages/{package_id}”, “summary”: “Update a WAF package” },
{ “method”: “GET”, “path”: “/zones/{zone_id}/firewall/waf/packages/{package_id}/rules”, “summary”: “List WAF rules” },
{ “method”: “PATCH”, “path”: “/zones/{zone_id}/firewall/waf/packages/{package_id}/rules/{rule_id}”, “summary”: “Update a WAF rule” },
{ “method”: “GET”, “path”: “/zones/{zone_id}/rulesets”, “summary”: “List zone rulesets” },
{ “method”: “POST”, “path”: “/zones/{zone_id}/rulesets”, “summary”: “Create a zone ruleset” },
{ “method”: “GET”, “path”: “/zones/{zone_id}/rulesets/phases/{ruleset_phase}/entrypoint”, “summary”: “Get a zone entry point ruleset” },
{ “method”: “PUT”, “path”: “/zones/{zone_id}/rulesets/phases/{ruleset_phase}/entrypoint”, “summary”: “Update a zone entry point ruleset” },
{ “method”: “POST”, “path”: “/zones/{zone_id}/rulesets/{ruleset_id}/rules”, “summary”: “Create a zone ruleset rule” },
{ “method”: “PATCH”, “path”: “/zones/{zone_id}/rulesets/{ruleset_id}/rules/{rule_id}”, “summary”: “Update a zone ruleset rule” }
]
[/yaml]
توضیح: کل Cloudflare API بیش از 2,500 endpoint دارد، اما مدل همینطور با اجرای کد مشخص، آنها را تا موارد مرتبط فیلتر کرد — بدون اینکه کل spec وارد کانتکست شود. مدل میتواند قبل از فراخوانی یک endpoint، درون schema آن endpoint هم نگاه کند. برای مثال، برای بررسی phases در zone rulesets چنین کدی نوشته میشود:
[pyaml]
async () => {
const op = spec.paths[‘/zones/{zone_id}/rulesets’]?.get;
const items = op?.responses?.[‘200’]?.content?.[‘application/json’]?.schema;
// Walk the schema to find the phase enum
const props = items?.allOf?.[1]?.properties?.result?.items?.allOf?.[1]?.properties;
return { phases: props?.phase?.enum };
}
[/yaml]
و خروجی بهصورت زیر خواهد بود:
[pyaml]
{
“phases”: [
“ddos_l4”, “ddos_l7”, “http_request_firewall_custom”,
“http_request_firewall_managed”, “http_response_firewall_managed”,
“http_ratelimit”, “http_request_redirect”, “http_request_transform”,
“magic_transit”, “magic_transit_managed”
]
}
[/yaml]
حالا عامل میداند که برای محافظت DDoS باید از phase = ddos_l7 و برای WAF از http_request_firewall_managed استفاده کند.
گام 2: عمل کردن روی API — عامل به execute سوئیچ میکند. در sandbox، یک client به نام cloudflare.request() در اختیار کد است که میتواند فراخوانیهای احراز هویتشده به Cloudflare API انجام دهد. اول عامل بررسی میکند که چه rulesetهایی روی zone وجود دارند:
[pyaml]
async () => {
const response = await cloudflare.request({ method: “GET”, path: `/zones/${zoneId}/rulesets` });
return response.result.map(rs => ({ name: rs.name, phase: rs.phase, kind: rs.kind }));
}
[/yaml]
خروجی نمونه:
[pyaml]
[
{ “name”: “DDoS L7”, “phase”: “ddos_l7”, “kind”: “managed” },
{ “name”: “Cloudflare Managed”,”phase”: “http_request_firewall_managed”, “kind”: “managed” },
{ “name”: “Custom rules”, “phase”: “http_request_firewall_custom”, “kind”: “zone” }
]
[/yaml]
عامل میبیند که rulesetهای managed برای DDoS و WAF موجودند. سپس میتواند در یک اجرای واحد چند فراخوانی را زنجیر کند تا جزئیات آنها را بررسی و حساسیتها را بهروزرسانی کند:
[pyaml]
async () => {
// Get the current DDoS L7 entrypoint ruleset
const ddos = await cloudflare.request({ method: “GET”, path: `/zones/${zoneId}/rulesets/phases/ddos_l7/entrypoint` });
// Get the WAF managed ruleset
const waf = await cloudflare.request({ method: “GET”, path: `/zones/${zoneId}/rulesets/phases/http_request_firewall_managed/entrypoint` });
// (ممکن است اینجا بررسی، تغییر و PATCH انجام شود)
}
[/yaml]
نکتهٔ مهم: تمام این عملیات — از جستجوی spec و بررسی schema تا لیست rulesetها و واکشی تنظیمات DDoS و WAF — تنها با چهار فراخوانی ابزار انجام شد. این همان مزیت فشردهسازی برنامهریزی است که Code Mode فراهم میآورد.
معماری Cloudflare MCP server: قبلاً برای هر محصول یک MCP server جدا داشتیم (مثلاً DNS یا Workers Observability). اما وقتی ابزارها زیاد شوند، نگهداری مجموعهای بزرگ از سرورهای دستینگهدار دشوار است. این MCP server جدید سادهسازی میکند: دو ابزار، حدود 1,000 tokens و پوشش همهٔ endpointها. وقتی محصول جدیدی اضافه شود، همان مسیرهای search() و execute() آنها را کشف و فراخوانی میکنند — بدون نیاز به ابزارهای جدید یا MCP serverهای جدا. حتی از GraphQL Analytics API هم پشتیبانی دارد.
مسائل امنیتی و دسترسی: سرور بر اساس آخرین مشخصات MCP ساخته شده و با OAuth 2.1 سازگار است؛ از Workers OAuth Provider برای downscope کردن توکن استفاده میشود تا تنها مجوزهایی که کاربر موقع اتصال تأیید کرده باشد صادر شود. به بیان ساده: عامل فقط به قابلیتهایی دسترسی پیدا میکند که کاربر بهطور صریح مجاز کرده — یک الگوی least privilege کاربردی برای محیطهای حساس SRE/DevOps.
برای توسعهدهندگان این یعنی میتوانید از یک agent loop ساده استفاده کنید و در عین حال دسترسی کامل و پویا به Cloudflare API بدهید، با کشف تدریجی قابلیتها (progressive capability discovery) و بدون پیچیدگی نگهداری ابزارهای زیاد.
مقایسهٔ روشها برای کاهش مصرف کانتکست: چند رویکرد مطرح شدهاند:
– Client-side Code Mode: اولین آزمایش ما بود. مدل TypeScript مینویسد و آن را در Dynamic Worker Loader روی کلاینت اجرا میکند. اشکال این روش این است که عامل باید همراه با دسترسی امن به sandbox توزیع شود. این الگو در Goose و Anthropic’s Claude SDK بهعنوان Programmatic Tool Calling پیاده شده است.
– CLIها: رابطهای خط فرمان self-documenting هستند و قابلیتها را هنگام کاوش آشکار میکنند. ابزارهایی مثل OpenClaw و Moltworker MCP servers را به CLIs تبدیل میکنند تا agentها بتوانند قابلیتها را تدریجی ببینند. محدودیت واضح است: عامل نیاز به یک shell دارد که همیشه در دسترس نیست و attack surface وسیعتری نسبت به یک isolate sandbox ایجاد میکند.
– Dynamic tool search: رویکردی که Anthropic در برخی کارها استفاده کرده — به مدل اجازه میدهد از طریق کشف پویا، ابزارها/endpointها را بیابد و سپس انتخاب کند چه کاری انجام دهد.
جمعبندی برای SRE/DevOps: اگر میخواهید به عاملهای هوش مصنوعی امکان مدیریت منابع، قوانین امنیتی یا عملیات زمانبندیشده در سطح Cloudflare را بدهید، Server‑side Code Mode یک راهکار عملی، کمهزینه از نظر tokens و نسبتاً امن است. مزیت کلیدی برای مهندسان عملیاتی این است که با حداقل تعریف ابزار و فضای کانتکست ثابت، میتوانید تواناییهای عامل را افزایش دهید در حالی که حریم امنیت و least-privilege را حفظ میکنید. 😊