Karaniwang primitives lang ang inilalantad ng mga handang MCP Server, kaya kailangang buuin muli ng Agent ang business actions at magpasya sa bawat failure. Sa manipis na Flask adapter layer, maaaring pagsamahin ang tool declarations, routing, execution, validation, at error semantics.
Kapag ikinokonekta ang browser environment sa isang AI Agent, may isang bagay na hindi maiiwasan: primitives lang ang ibinibigay ng mga standard tool, habang kailangan mo pa ring buuin ang mismong business actions.
Isang konkretong halimbawa. Para matapos ang isang collection run, ang aktuwal na daloy ay “magbukas ng environment para sa isang rehiyon, ikabit ang outbound connection, bumisita muna nang isang beses para sa warm-up, at tiyaking gumagana ang outbound connection,” saka pa lamang ipapasa ang trabaho sa Agent. Karaniwang single-step tools lang ang ibinibigay ng isang ready-made MCP Server, gaya ng pagbukas ng environment, pag-navigate, pag-click, at pagkuha ng screenshot. Walang kusang bumubuo ng magkakasunod na hakbang na iyon para sa iyo. Kailangang ayusin ng Agent mula sa simula ang lahat sa bawat pagkakataon, mabagal iyon, at kailangan din nitong magpasya kung ano ang gagawin kapag pumalya ang alinmang intermediate step.
Iyan ang silbi ng adapter layer: panatilihin sa sarili mong panig ang composition logic, validation, at state, at isang business action lang ang ilantad sa labas.
Pinakamaliit na gumaganang istruktura
Tatlong bahagi lang ang kailangan ng isang gumaganang adapter layer: tool declaration, request routing, at execution na may return value. Sa Flask, kasya ang lahat sa iisang process.

Magsimula sa tool declaration; ito ang nagtatakda kung ano ang makikita ng Agent.
# adapter/tools.py
TOOLS = [
{
"name": "prepare_environment",
"description": "Maghanda ng available na environment para sa isang rehiyon at ibalik ang environment ID kapag tapos na",
"inputSchema": {
"type": "object",
"properties": {
"region": {"type": "string", "description": "Outbound region, gaya ng US-CA"},
"purpose": {"type": "string", "description": "Purpose label para sa reuse at quota statistics"},
"timeout": {"type": "integer", "minimum": 10, "maximum": 120, "default": 60},
},
"required": ["region"],
"additionalProperties": False,
},
},
{
"name": "open_page",
"description": "Magbukas ng page sa tinukoy na environment at maghintay hanggang maging interactive ito",
"inputSchema": {
"type": "object",
"properties": {
"env_id": {"type": "string"},
"url": {"type": "string"},
},
"required": ["env_id", "url"],
"additionalProperties": False,
},
},
]
Ang router ang namamahagi ng mga JSON-RPC method. Hihingin muna ng client ang tools/list, saka tatawag ng tools/call ayon sa pangalan.
# adapter/app.py
from flask import Flask, request, jsonify
from adapter.tools import TOOLS
from adapter.runner import run_tool
app = Flask(__name__)
@app.post("/mcp")
def mcp():
req = request.get_json(force=True)
method, rid = req.get("method"), req.get("id")
if method == "tools/list":
return jsonify({"jsonrpc": "2.0", "id": rid, "result": {"tools": TOOLS}})
if method == "tools/call":
name = req["params"]["name"]
args = req["params"].get("arguments", {})
return jsonify({"jsonrpc": "2.0", "id": rid, "result": run_tool(name, args)})
return jsonify({"jsonrpc": "2.0", "id": rid,
"error": {"code": -32601, "message": "method not found"}})
Ang execution layer lang ang lugar na humahawak sa environment API at page protocol. Dito isinasagawa ang mga multi-step sequence, at dito rin ginagawang pare-pareho ang format ng mga failure.
# adapter/runner.py
def run_tool(name, args):
try:
payload = HANDLERS[name](**args)
return ok(payload)
except ToolError as e:
return fail(e.code, e.retryable, e.message)
Mainam na tukuyin nang maaga ang return format. Huwag ibigay sa Agent ang hilaw na low-level exceptions; susubukan nitong i-parse ang mga string na iyon at maaaring makagawa ng kakaibang desisyon. Magtakda ng result structure na may code, gaya ng {"ok": false, "code": "env_unavailable", "retryable": true, "attempts": 3}. Sa ganitong paraan, dalawang bagay lang ang kailangang pasyahan ng Agent: puwede bang ulitin, at kailangan bang ipasa sa tao?
Paano idisenyo ang mga parameter
Ang granularity ng tools ay dapat nakabatay sa business actions, hindi sa APIs. Kung bawat low-level endpoint ay gagawing hiwalay na tool, halos wala ring abstraction; kailangan pa ring ayusin ng Agent ang pagkakasunod-sunod ng mga hakbang.
May malinaw na hangganan sa mga parameter: kung ano ang dapat desisyunan ng model at kung ano ang dapat desisyunan ng adapter layer. Kabilang sa una ang rehiyon, layunin, at target URL kaya ang model ang maglalagay ng mga iyon. Kabilang sa ikalawa ang debug port, internal queue names, at kung aling environment pool ang gagamitin; huwag ilagay ang mga ito sa schema dahil kalaunan ay malamang na mali ang maibigay ng model.
Madaling maging problema ang selectors. Kapag nagbago ang page structure, maaaring sabay-sabay masira ang mga tawag na may hard-coded selector. Mas mabuting semantic targets ang ipasa ng model, gaya ng medyo matatag na identifier na “login button,” at sa adapter layer panatilihin ang selector mapping. Kapag nagbago ang page, isang lugar lang ang kailangang baguhin.
Dapat may upper limit ang numeric parameters. Kung walang maximum sa schema para sa timeout, retry count, o page count, maaaring magpasa ang model ng napakalaking value at gawing mahigit sampung minuto ang isang tawag. Ang bawat tool na may loop semantics ay kailangang may malinaw na endpoint. Gumamit ng field gaya ng max_pages para limitahan ang trabaho sa halip na “ituloy hanggang wala nang data.”
Isaalang-alang din ang idempotency. Magpasa ang caller ng task_id; kapag naulit ang request, puwedeng ibalik agad ang dating result para hindi makagawa ng pangalawang environment ang retry ng Agent.
Panatilihing maliit ang return values. Huwag magbalik ng screenshot bilang base64; magbalik ng file reference. Para sa list results, magsama ng count at truncation flag sa halip na ilagay ang buong table sa context.
Tatlong lugar na dapat unahing tingnan sa debugging
Kapag stdio ang gamit, okupado ng JSON-RPC ang stdout, kaya hindi dapat kailanman doon isulat ang logs. Isang simpleng print lang ay maaaring makasira agad sa protocol parsing at magdulot ng mahabang debugging. Ipadala ang logs sa stderr o sa file.

Ang tools/list ang unang checkpoint. Kung hindi nabasa ang declarations, hindi mangyayari ang lahat ng susunod na calls. Suriin muna ang tool names, schema structure, at kung may parameter na hinaharangan ng additionalProperties.
Ang ikalawang checkpoint ay step-by-step trace. Itala sa bawat call ang task_id, buod ng parameters, elapsed time, at result code. Kapag may problema, makikita kung huminto ba sa environment creation, navigation, o validation. Itabi ang orihinal na parameters ng failed cases para eksaktong ma-replay — mas mabilis ayusin ang bug kapag madaling ma-reproduce.
Ang ikatlong checkpoint ay isang fixed set ng fixtures: isang stable na test page at ilang element locators na hindi nagbabago. Magpatakbo ng smoke test pagkatapos ng bawat pagbabago sa adapter layer; mas nakakatipid ito ng oras kaysa sa anumang verbal verification.
Mga hangganan ng pahintulot
Sa adapter layer pinakanakakonsentra ang permissions sa buong system: hawak nito ang credentials, environments, at page operations. Kaya rito mismo kailangang itakda ang mga hangganan.
Ilagay ang credentials sa server-side configuration, hindi sa tool parameters o model context. Paghiwalayin ang tools ayon sa risk: read-only tools gaya ng screenshot at text extraction ay naka-enable by default; write tools gaya ng click, submit, at delete ay naka-disable by default at pansamantalang binubuksan lamang para sa isang task. Sa ganitong paraan, limitado pa rin ang pinsala kahit magkamali ang model.
Ihiwalay ang environments ayon sa gamit. Magkaibang account at magkaibang task ay dapat gumamit ng magkaibang environment; huwag paghaluin sa iisang environment. Sa multi-account management, maaaring ipahawak sa espesyal na environment layer ang environment creation, outbound network binding, at state maintenance. Ang mga tool gaya ng PurpleMark ang naghihiwalay sa layer na ito, habang ang adapter layer ay nakatuon lamang sa business composition at validation.
Panatilihin ang audit logs. Dapat ma-export ayon sa oras kung aling task ang gumamit ng aling environment at kung aling write tools ang tinawag. Kapag totoong may nangyaring problema, ang record na ito ang tanging paraan para maibalik ang buong proseso.
Panghuli, ang matibay na hangganan: hindi dapat magbigay ang adapter layer ng anumang paraan para lampasan ang mga tuntunin ng platform. Huwag gawing tool ang mga gawaing gaya ng bulk registration, pag-bypass sa verification, o pamemeke ng identity, kahit pa tawaging internal tool. Kapag nailantad na sa model ang isang tool, maaaring awtomatikong mangyari ang calls; walang maaasahang puntong mapipigil ang mga iyon bago mangyari, at hindi na mababawi ang epekto pagkatapos.
Para sa mga bersyon ng protocol at kahulugan ng mga field, sundin ang opisyal na dokumentasyon ng MCP.


