Bouwen met CometAPIHeb je één API voor meerdere modellen nodig?Test de workflow in Playground en maak daarna een API-sleutel aan wanneer het model en de kosten passen bij je use case.
MCP vs functieaanroepen: hoe koppel je tools aan AI-agenten
Vergelijking: MCP versus function calling
- Function calling (tool calling) via het model:
- Sterke punten: Lage latency, geen extra processen, eenvoudig om direct Python-functies of HTTP-clients aan te roepen vanuit je host-app. Ideaal voor één app, één toolset.
- Zwakke punten: Strakke koppeling aan je runtime; hergebruik tussen apps/agents is lastiger; sandboxing en permissies moet je zelf regelen; discoverability van tools is beperkt tot wat je in code bundelt.
- MCP (Model Context Protocol):
- Sterke punten: Gestandaardiseerde interface voor tools; decoupling tussen agent en tools; tools zijn discoverable (list_tools), self-describing (schema’s), en kunnen door meerdere agents/clients hergebruikt worden; betere isolatie en governance (aparte processen/containers).
- Zwakke punten: Extra laag en procescommunicatie (JSON-RPC) introduceert overhead en complexiteit; je hebt een server en client nodig; minimale leercurve.
Onderstaande Python-templates laten dezelfde order lookup zien:
1) direct (rechtstreeks naar CometAPI),
2) via function calling met het model,
3) via MCP (server die CometAPI publiceert; client die de tool aanroept),
4) en een bridge waarbij het model een tool call triggert en de host die via MCP uitvoert.
Benodigdheden
- Python 3.10+
- pip install requests anyio openai mcp
- Omgevingsvariabelen:
- COMET_BASE_URL: basis-URL van CometAPI, bijv. https://api.example.com
- COMET_API_KEY: API key indien vereist
- OPENAI_API_KEY: voor function calling voorbeelden
Bestand: comet_api.py
import os
import typing as t
import requests
class CometAPI:
def __init__(
self,
base_url: t.Optional[str] = None,
api_key: t.Optional[str] = None,
timeout: int = 10,
) -> None:
self.base_url = (base_url or os.environ.get("COMET_BASE_URL") or "").rstrip("/")
if not self.base_url:
raise ValueError("COMET_BASE_URL is niet gezet")
self.api_key = api_key or os.environ.get("COMET_API_KEY")
self.timeout = timeout
def _headers(self) -> dict:
headers = {"Accept": "application/json"}
if self.api_key:
headers["Authorization"] = f"Bearer {self.api_key}"
return headers
def get_order(self, order_id: str) -> dict:
if not order_id:
raise ValueError("order_id is verplicht")
url = f"{self.base_url}/orders/{order_id}"
resp = requests.get(url, headers=self._headers(), timeout=self.timeout)
resp.raise_for_status()
data = resp.json()
if not isinstance(data, dict):
raise ValueError("Onverwacht antwoordformaat; verwacht JSON object")
return data
def find_orders(self, email: t.Optional[str] = None, status: t.Optional[str] = None) -> dict:
params = {}
if email:
params["email"] = email
if status:
params["status"] = status
url = f"{self.base_url}/orders"
resp = requests.get(url, headers=self._headers(), params=params, timeout=self.timeout)
resp.raise_for_status()
return resp.json()
Bestand: direct_lookup.py
import sys
from pprint import pprint
from comet_api import CometAPI
def main():
if len(sys.argv) > 1:
order_id = sys.argv[1]
else:
order_id = "ORD-1001"
api = CometAPI()
data = api.get_order(order_id)
print(f"Order {order_id}:")
pprint(data)
if __name__ == "__main__":
main()
Bestand: llm_function_calling.py
import json
from pprint import pprint
from openai import OpenAI
from comet_api import CometAPI
def build_tools_schema():
return [
{
"type": "function",
"function": {
"name": "get_order",
"description": "Haalt ordergegevens op aan de hand van order_id.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Het ordernummer, bijv. ORD-1001"
}
},
"required": ["order_id"]
},
},
}
]
def execute_tool_call(name: str, arguments_json: str):
if name == "get_order":
args = json.loads(arguments_json or "{}")
order_id = args.get("order_id")
api = CometAPI()
result = api.get_order(order_id)
return {"ok": True, "data": result}
raise ValueError(f"Onbekende tool: {name}")
def main():
client = OpenAI()
model = "gpt-4o-mini"
messages = [
{"role": "system", "content": "Je bent een behulpzame assistant."},
{
"role": "user",
"content": "Zoek de orderstatus voor ORD-1001 en geef een korte samenvatting."
},
]
# Eerste call: model kan beslissen om de tool te gebruiken
resp = client.chat.completions.create(
model=model,
messages=messages,
tools=build_tools_schema(),
tool_choice="auto",
temperature=0
)
msg = resp.choices[0].message
tool_calls = msg.tool_calls or []
if not tool_calls:
print("Model gaf antwoord zonder tool; antwoord:")
print(msg.content)
return
# Voer elke tool call uit en verzamel resultaten
tool_results = []
for tc in tool_calls:
name = tc.function.name
args = tc.function.arguments
result = execute_tool_call(name, args)
tool_results.append(
{
"role": "tool",
"tool_call_id": tc.id,
"name": name,
"content": json.dumps(result),
}
)
# Tweede call: geef tool-resultaten terug aan het model voor eindantwoord
messages2 = messages + [msg] + tool_results
resp2 = client.chat.completions.create(
model=model,
messages=messages2,
temperature=0
)
final_answer = resp2.choices[0].message.content
print("Antwoord van het model:")
print(final_answer)
if __name__ == "__main__":
main()
Bestand: mcp_server.py
# Opmerking: Dit gebruikt de MCP Python SDK (https://pypi.org/project/mcp).
# Afhankelijk van de SDK-versie kunnen namen licht afwijken. Zie de officiële docs
# voor eventuele kleine aanpassingen.
import os
import json
import anyio
from comet_api import CometAPI
# MCP server primitives
from mcp.server import Server
from mcp.server.stdio import stdio_server
server = Server("comet-tools")
@server.tool()
async def get_order(order_id: str) -> str:
"""
MCP tool: get_order
Argumenten:
- order_id: string
Retourneert:
- JSON string met ordergegevens
"""
api = CometAPI()
# Run sync HTTP call in thread om de eventloop niet te blokkeren
data = await anyio.to_thread.run_sync(api.get_order, order_id)
# MCP tools retourneren content; strings zijn veilig en self-describing
return json.dumps({"ok": True, "data": data})
async def main():
# stdio server maakt het mogelijk om via stdin/stdout te praten met clients
async with stdio_server() as (reader, writer):
await server.run(reader, writer)
if __name__ == "__main__":
anyio.run(main)
Bestand: mcp_client_demo.py
# Eenvoudige MCP client die mcp_server.py start en de tool aanroept.
# Draai in een terminal:
# python mcp_server.py
# En in een andere:
# python mcp_client_demo.py ORD-1001
import sys
import json
import anyio
from mcp.client import Client
from mcp.client.stdio import stdio_client
async def run(order_id: str):
# Verbind met een reeds draaiende server via stdio_client en een command
# Optie 1: start server als subproces:
# async with stdio_client(command=[sys.executable, "mcp_server.py"]) as (reader, writer):
# Optie 2: verbind naar bestaande server (stdin/stdout; sommige SDK’s ondersteunen sockets)
async with stdio_client(command=[sys.executable, "mcp_server.py"]) as (reader, writer):
client = Client()
await client.initialize(reader, writer)
# Optioneel: ontdek beschikbare tools
tools = await client.list_tools()
tool_names = [t.name for t in tools]
if "get_order" not in tool_names:
raise RuntimeError("Tool 'get_order' niet gevonden")
# Roep de tool aan
result = await client.call_tool("get_order", {"order_id": order_id})
# Result kan content-blokken bevatten; ga uit van één string-blok
content = result.content[0].text if result.content else ""
obj = json.loads(content) if content else {}
print(json.dumps(obj, indent=2))
def main():
order_id = sys.argv[1] if len(sys.argv) > 1 else "ORD-1001"
anyio.run(run, order_id)
if __name__ == "__main__":
main()
Bestand: llm_mcp_bridge.py
# Dit laat zien hoe je het model laat beslissen 'get_order' te gebruiken, maar de daadwerkelijke
# uitvoering via MCP laat lopen in plaats van direct CometAPI te bellen.
# De tool signature in het model blijft hetzelfde; de host code routeert naar MCP.
import json
from pprint import pprint
from openai import OpenAI
import anyio
from mcp.client import Client
from mcp.client.stdio import stdio_client
def build_tools_schema():
return [
{
"type": "function",
"function": {
"name": "get_order",
"description": "Haalt ordergegevens op aan de hand van order_id.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Het ordernummer, bijv. ORD-1001"
}
},
"required": ["order_id"]
},
},
}
]
async def call_mcp_get_order(order_id: str) -> dict:
async with stdio_client(command=["python", "mcp_server.py"]) as (reader, writer):
client = Client()
await client.initialize(reader, writer)
result = await client.call_tool("get_order", {"order_id": order_id})
content = result.content[0].text if result.content else ""
return json.loads(content) if content else {}
def main():
client = OpenAI()
model = "gpt-4o-mini"
messages = [
{"role": "system", "content": "Je bent een behulpzame assistant."},
{"role": "user", "content": "Wat is de status van ORD-1001?"},
]
resp = client.chat.completions.create(
model=model,
messages=messages,
tools=build_tools_schema(),
tool_choice="auto",
temperature=0
)
msg = resp.choices[0].message
tool_calls = msg.tool_calls or []
if not tool_calls:
print("Model gaf antwoord zonder tool; antwoord:")
print(msg.content)
return
# Voer tool via MCP
tc = tool_calls[0]
args = json.loads(tc.function.arguments or "{}")
order_id = args.get("order_id")
mcp_result = anyio.run(call_mcp_get_order, order_id)
tool_result_message = {
"role": "tool",
"tool_call_id": tc.id,
"name": "get_order",
"content": json.dumps(mcp_result),
}
# Tweede call voor eindantwoord
messages2 = messages + [msg, tool_result_message]
resp2 = client.chat.completions.create(
model=model,
messages=messages2,
temperature=0
)
final_answer = resp2.choices[0].message.content
print("Antwoord van het model:")
print(final_answer)
if __name__ == "__main__":
main()
Uitvoerinstructies
- Installeer dependencies:
- pip install requests anyio openai mcp
- Stel omgevingsvariabelen:
- export COMET_BASE_URL="https://api.example.com"
- export COMET_API_KEY="..." (indien nodig)
- export OPENAI_API_KEY="..."
- Directe lookup:
- python direct_lookup.py ORD-1001
- Function calling (rechtstreeks):
- python llm_function_calling.py
- MCP: start server en client:
- Terminal 1: python mcp_server.py
- Terminal 2: python mcp_client_demo.py ORD-1001
- LLM via MCP-bridge:
- python llm_mcp_bridge.py
Opmerkingen
- De MCP SDK kan kleine API-verschillen hebben per versie; als een import of methode niet bestaat, raadpleeg de Model Context Protocol Python SDK documentatie en pas de server/client imports of methoden licht aan.
- CometAPI in deze templates is generiek; vervang COMET_BASE_URL door de echte service en pas de endpoints/velden aan.
Deon GoodwinOnderzoeksteam voor AI-modellen en API
Function calling geeft een model een manier om een tool aan te vragen. MCP geeft een applicatie een standaardmanier om tools op een server te ontdekken en aan te roepen. Gebruik directe functie-integratie voor een kleine set tools die uw applicatie bezit. Voeg MCP toe wanneer u een bestaande compatibele service wilt gebruiken of tools via een gedeelde interface wilt ontsluiten. Hieronder koppelt u dezelfde orderopvraging op beide manieren via CometAPI, binnen één complete agentlus.
Belangrijkste punten
Begin met directe dispatch wanneer een paar tools één applicatie bedienen; gebruik MCP wanneer een compatibele toolservice of een gedeelde toolinterface het onderhoud eenvoudiger maakt.
Beide paden hebben een complete lus nodig: beschrijf de tool, ontvang een call, voer die uit, geef het resultaat terug en laat het model antwoorden.
Gecontroleerd op duidelijkheid, bronvermelding en actuele API-terminologie.
Gebruik deze samenvatting voor een snel antwoord en lees daarna de gids voor context, voorbeelden en implementatiedetails.
U kunt dezelfde modelgerichte functie behouden terwijl u de uitvoering ervan wijzigt van een directe handler naar een MCP-client.
Houd toolcontracten smal en controleer resultaten tegen de taak die u de agent wilt laten voltooien.
Hoe Function calling en MCP samenpassen
Een supportagent kan een verzendvertraging uitleggen, maar heeft toegang tot het ordersysteem nodig om een klant te vertellen waar hun pakket is. Function calling geeft het model een manier om die opvraging aan te vragen. Uw applicatie voert de opvraging uit en geeft het resultaat terug. De handler kan een lokale bibliotheek, een database of een externe API gebruiken.
Om dat verzoek via MCP te vervullen, gebruikt de applicatie een client om servert tools te ontdekken met tools/list en ze aan te roepen met tools/call. De applicatie beslist nog steeds welke gevonden tools aan het model worden blootgesteld.
MCP vs Function calling: belangrijkste verschillen
Vergelijking
Function calling
MCP
Verbinding
Een door het model aangevraagde actie naar applicatiecode
Een MCP-client van de applicatie naar een toolserver
Hoofdrol
Het model een benoemde bewerking met gestructureerde argumenten laten aanvragen
Standaardiseren hoe compatibele applicaties servert tools ontdekken en aanroepen
Tooldefinities
Definities geleverd in het formaat van de model-API
Door de server geleverde definities, inclusief een inputSchema
Uitvoeringslocatie
De handler waarnaar de applicatie dispatcht, die een lokale of externe service kan aanroepen
De toolimplementatie van de MCP-server, die een backendservice kan aanroepen
Afzonderlijke server vereist?
Geen server is vereist door de function-callinginterface zelf
Een MCP-server is vereist, maar een client kan die als lokaal stdio-subprocess starten; een apart uitgerolde externe service is optioneel
Typisch gebruik
Een paar door de applicatie beheerde tools met directe dispatch
Bestaande compatibele services of een toolinterface die over applicaties heen wordt hergebruikt
Kunnen ze samenwerken?
De applicatie kan het functieverzoek van het model via MCP routeren
De MCP-client vervult dat verzoek met tools/call en geeft het resultaat terug aan de applicatie
Die laatste rij is de sleutel om met beide te bouwen. Een model kan get_order_status aanvragen, terwijl de applicatie kiest of zij haar eigen handler of een MCP-server aanroept. De functiedefinitie richting het model kan hetzelfde blijven.
Kies de integratie die uw applicatie nodig heeft
We raden aan om te beginnen met directe integratie wanneer u een paar tools bezit die door één applicatie worden gebruikt. Er valt minder te deployen, en het pad van een modelverzoek naar uw businesscode is eenvoudig te volgen.
MCP wordt nuttig wanneer een compatibele server de mogelijkheid al biedt of wanneer meerdere AI-applicaties een gemeenschappelijke toolinterface nodig hebben. Dezelfde ordertool kan zowel een supportassistent als een interne operatie-applicatie bedienen, waarbij elke host bepaalt hoe zijn gebruikers er toegang toe hebben.
Een dispatcher kan zowel interne functies als MCP-services ondersteunen en elke bewerking naar zijn implementatie routeren. Bibliotheken en REST-API’s kunnen ook worden gedeeld; kies MCP wanneer de standaardinterface voor discovery en aanroepen nuttig is voor de applicaties die de tools consumeren.
Bouw een complete toolcyclus via CometAPI
We gebruiken één read-only operatie, get_order_status, en één fictieve order, ORD-104. Het voorbeeld roept de operatie eerst direct aan en voert die vervolgens uit via een lokale MCP-server. Beide modi gebruiken de CometAPI Responses API voor modelinferentie.
Figuur 2. Eén agentlus kan directe en MCP-uitvoering ondersteunen. Originele illustratie, gebaseerd op de MCP-architectuur en de CometAPI function-callingflow.
Stap 1 Het project instellen
Gebruik Python 3.11 of later en een CometAPI-API-sleutel. Deze walkthrough is getest met Python 3.12.14 en mcp==2.3.0. Volg de CometAPI-quickstart om een sleutel te maken. Maak in een macOS- of Linux-shell een project en activeer een virtuele omgeving:
Vervang de placeholder door uw sleutel en houd deze buiten openbare broncode. Deze walkthrough pinnt de MCP-SDK die door het voorbeeld wordt gebruikt; de officiële Python-servergids richt zich op de 2.x-API. De twee agentcommando’s hieronder sturen verzoeken naar CometAPI en verbruiken API-tegoed.
Stap 2 Definieer de orderopvraging
Sla dit op als orders.py. Vaste gegevens houden de walkthrough self-contained; later kunt u de opvraging vervangen door uw eigen service.
"""Read-only, invented order data; never connects to a real order system."""
import re
def get_order_status(order_id: str) -> dict[str, str]:
"""Look up an invented order; ORD-104 is the only available record."""
if not isinstance(order_id, str) or not re.fullmatch(r"ORD-[0-9]{3}", order_id):
raise ValueError("order_id must have the form ORD-104")
if order_id != "ORD-104":
raise ValueError("Order not found in this demo")
return {"order_id": order_id, "status": "shipped", "source": "fictional_demo"}
Het aanroepen van get_order_status("ORD-104") geeft deze fixture terug:
Sla het volgende complete script op als agent.py. Het registreert de functie, stuurt de vraag naar CometAPI, voert aangevraagde calls uit en geeft elk resultaat terug met de originele call_id.
De modelgerichte definitie gebruikt het parameters-veld van de CometAPI Responses API. MCP levert een inputSchema; dit voorbeeld controleert het ontdekte contract tegen het één-string order_id-schema voordat de beoordeelde functie wordt blootgesteld.
"""A deliberately narrow direct/MCP bridge, not a general MCP adapter."""
import argparse
import asyncio
import json
import os
from pathlib import Path
import sys
from urllib.request import Request, urlopen
from mcp import Client, StdioServerParameters
from mcp.client.stdio import stdio_client
from orders import get_order_status
NAME = "get_order_status"
SCHEMA = {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"], "additionalProperties": False}
TOOL = {"type": "function", "name": NAME, "description": "Look up fictional order ORD-104.",
"parameters": SCHEMA, "strict": True}
def validate_arguments(arguments):
# Exact validation for SCHEMA above; deliberately not a JSON Schema engine.
if (not isinstance(arguments, dict) or set(arguments) != {"order_id"}
or not isinstance(arguments["order_id"], str)):
raise ValueError("Expected exactly one string argument: order_id")
def validate_catalog(tools):
if len(tools) != 1 or tools[0].name != NAME:
raise RuntimeError("Unexpected MCP tool catalog")
schema = tools[0].input_schema
if (schema.get("type") != "object" or schema.get("required") != ["order_id"]
or set(schema.get("properties", {})) != {"order_id"}
or schema["properties"]["order_id"].get("type") != "string"):
raise RuntimeError("MCP schema does not match this reviewed demo tool")
async def dispatch(name, arguments, client=None):
if name != NAME:
raise ValueError("Tool is not allowlisted")
try:
validate_arguments(arguments)
if client is None:
return {"is_error": False, "data": get_order_status(**arguments)}
except ValueError as error:
return {"is_error": True, "error": str(error)}
result = await client.call_tool(name, arguments)
if getattr(result, "result_type", "complete") != "complete":
raise RuntimeError("Input-required MCP results are outside this demo")
if any(block.type != "text" for block in result.content):
raise RuntimeError("Non-text MCP content is outside this demo")
return {"is_error": bool(result.is_error),
"content": [block.text for block in result.content],
"structured_content": result.structured_content}
async def run_agent(send, execute, question, max_rounds=4):
history = [{"role": "user", "content": question}]
seen_call_ids = set()
for _ in range(max_rounds):
response = send({"model": "gpt-6-astra", "input": list(history),
"tools": [TOOL], "reasoning": {"effort": "low"}})
if response.get("status") != "completed" or response.get("error"):
raise RuntimeError("Model response failed or did not complete")
output = response["output"]
# CometAPI's documented manual replay: keep ALL items, omit top-level ids.
history.extend({key: value for key, value in item.items() if key != "id"}
for item in output)
blocks = [block for item in output if item["type"] == "message"
for block in item.get("content", [])]
if any(block["type"] == "refusal" for block in blocks):
raise RuntimeError("Model refused the request")
calls = [item for item in output if item["type"] == "function_call"]
if not calls:
text = "\n".join(block["text"] for block in blocks
if block["type"] == "output_text")
if not text:
raise RuntimeError("No final text returned")
return text
for call in calls:
call_id = call["call_id"]
if not isinstance(call_id, str) or not call_id or call_id in seen_call_ids:
raise ValueError("Missing or duplicate function call_id")
seen_call_ids.add(call_id)
try:
arguments = json.loads(call["arguments"])
except (ValueError, TypeError):
result = {"is_error": True, "error": "Arguments must be JSON text"}
else:
result = await execute(call["name"], arguments)
print(json.dumps({"tool": call["name"], "arguments": call["arguments"],
"result": result}), file=sys.stderr)
history.append({"type": "function_call_output", "call_id": call_id,
"output": json.dumps(result)})
raise RuntimeError("Tool loop reached its round limit")
def send_live(payload):
key = os.environ["COMETAPI_KEY"] # Only live mode reads the caller's key.
request = Request("https://api.cometapi.com/v1/responses",
data=json.dumps(payload).encode(),
headers={"Authorization": f"Bearer {key}",
"Content-Type": "application/json"})
with urlopen(request, timeout=45) as response:
return json.load(response)
def server_parameters():
return StdioServerParameters(command=sys.executable,
args=[str(Path(__file__).with_name("server.py"))])
async def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--mode", choices=["direct", "mcp"], required=True)
parser.add_argument("--question", default="Use the tool to check order ORD-104.")
args = parser.parse_args()
if args.mode == "direct":
answer = await run_agent(send_live, dispatch, args.question)
else:
async with Client(stdio_client(server_parameters())) as client:
discovered = await client.list_tools()
validate_catalog(discovered.tools)
async def execute(name, arguments):
return await dispatch(name, arguments, client)
answer = await run_agent(send_live, execute, args.question)
print(answer)
if __name__ == "__main__":
asyncio.run(main())
De lus houdt de originele vraag en elk geretourneerd response-item vast. Volgens het conversieformaat van CometAPI Responses verwijdert deze vóór replay de top-level id-velden van de outputitems en voegt voor elke call een function_call_output toe. Het behouden van de rest van de geretourneerde items behoudt ook eventuele reasoning-items die nodig zijn voor de volgende beurt.
Stap 4 Voer het directe pad uit
Voer uit:
python agent.py --mode direct
De applicatie beschrijft get_order_status aan het model. Wanneer het model dit aanvraagt, controleert dispatch() de naam en de argumenten en roept vervolgens de functie in orders.py aan. Het resultaat gaat terug in de conversatie en het model kan het omzetten in een antwoord.
Gebruik de tooltrace die naar uw terminal is geprint om te controleren dat de opvraging ORD-104 gebruikte en status: shipped teruggaf. Het definitieve antwoord zou dat resultaat moeten weerspiegelen; de formulering kan variëren. U hebt nu de complete function-callinglus: van de vraag van de gebruiker tot een door de applicatie uitgevoerde operatie en een daaropvolgende modelrespons.
De volgende stap houdt het model en de conversatielus in stand. De uitvoering wordt verplaatst achter een MCP-server en de applicatie ontdekt en roept de tool aan via een client.
Stap 5 Stel de opvraging bloot als een MCP-tool
Sla dit op als server.py, naast de andere twee bestanden:
"""One read-only MCP tool, served over stdio. No stdout logging."""
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError
from orders import get_order_status as lookup_order
server = MCPServer("fictional-orders")
@server.tool(structured_output=True)
def get_order_status(order_id: str) -> dict[str, str]:
"""Look up fictional order ORD-104; this demo has no real customer data."""
try:
return lookup_order(order_id)
except ValueError as error:
raise ToolError(str(error)) from error
if __name__ == "__main__":
server.run(transport="stdio")
De mcp-tak in main() start server.py, roept list_tools() aan en controleert het contract van de ordertool. Wanneer het model de opvraging aanvraagt, gebruikt dezelfde dispatcher nu client.call_tool(). De server voert de functie uit en de applicatie geeft het resultaat terug aan het model.
Vergelijk de twee runs aan de hand van dezelfde criteria: de juiste tool, ORD-104 als argument, een succesvol resultaat met shipped, en een definitief antwoord dat met dat resultaat in overeenstemming is. Het uitvoeringspad is veranderd; de taak en de modelgerichte functie zijn hetzelfde gebleven.
Alle drie bronbestanden staan hierboven. Het voorbeeldpakket bevat ze ook en de offline checks voor handig hergebruik. Die checks testen een echte lokale MCP-server met gescripte modelresponses; live modeloutput staat los van die lokale verificatie.
Pas het voorbeeld aan uw eigen tools aan
Vervang de vaste ordergegevens door de kleinste operatie die uw applicatie daadwerkelijk nodig heeft. Geef voor een verzendvraag een order-ID en nuttige statusvelden terug. Een compact resultaat geeft het model minder irrelevante materie om te interpreteren en maakt het antwoord eenvoudiger te controleren.
Houd de beschrijving en het argumentcontract van de tool specifiek. Dit voorbeeld accepteert exact één string, en de host controleert de aangevraagde toolnaam vóór dispatch. De MCP-beveiligingsrichtlijnen vereisen dat servers invoer valideren en toegangscontroles implementeren. Voor een echte orderservice leidt u de identiteit van de klant af uit vertrouwde applicatiecontext en handhaaft u toegang tot de order van die klant binnen de service. Een door het model aangeleverde order-ID kan geen eigendom vaststellen.
Zodra de tool werkt, evalueert u voltooide taken, end-to-endtijd en daadwerkelijke kosten. Voeg MCP toe waar de service-interface helpt voor de applicaties die de tool nodig hebben, en behoud directe handlers waar ze eenvoudiger te beheren zijn.
Veelgestelde vragen
Vervangt MCP function calling?
Ze behandelen verschillende interfaces: MCP verbindt de client van de applicatie met een server. In dit voorbeeld vraagt het model een functie aan en vult de applicatie dat verzoek via een MCP-client in. Beide nemen deel aan dezelfde agentlus.
Kan een MCP-tool een bestaande REST-API aanroepen?
Ja. Vervang de opvraging in de MCP-tool door een call naar uw API. De MCP-server publiceert het toolcontract en behandelt toolcalls; uw bestaande service blijft zijn businessgedrag leveren.
Wanneer moet ik een externe MCP-server gebruiken?
Gebruik een externe service wanneer clients een apart uitgerolde server moeten bereiken in plaats van een lokaal proces te starten. MCP definieert Streamable HTTP voor die verbinding en stdio voor een door de client gestart subprocess. Configureer de autorisatie van de externe server voor de bedoelde aanroepers.
Conclusie
Voor één applicatie: vervang het fictieve record in orders.py door één read-only query uit uw service en begin met de directe modus.
Als u een bestaande MCP-service of een gedeelde toolinterface nodig hebt, gebruik dan het MCP-pad en houd dezelfde controles: de juiste operatie, het juiste record en een antwoord dat wordt ondersteund door de geretourneerde gegevens.