Explains Model Context Protocol and Agent2Agent for agents to discover standardized tool schemas, invoke APIs, and coordinate multi step tasks like flight booking, debugging, and data workflows.
If you’ve seen chatter about MCPs, AI agents, and Agent2Agent (A2A) and felt left out — this is the single lesson you need to catch up. No prior knowledge of AI models, coding, or APIs is required.This article is split into two parts:
Part 1 — Why and what: core concepts, diagrams, and real-world motivations.
Part 2 — How: configuration snippets, example flows, and a preview of a hands-on FlightSim lab.
Part 1 — Why and whatModern chat products (like ChatGPT) combine two different responsibilities:
A chat interface (the UI you interact with).
A large language model (LLM) that generates the responses.
When you ask a question, the UI forwards your request to an LLM. The LLM returns text (and sometimes images), and the UI displays the result. LLMs include models such as Claude, Gemini, Llama, OpenAI models, and more — in this lesson we will use the generic term “LLM”.LLMs are powerful at producing language and plans, but they cannot natively perform external actions (for example, calling airline APIs or clicking buttons in a web UI). To automate real-world tasks — e.g., search and book a flight — we combine LLMs with agents and tools.What is an AI agent?An AI agent bridges text output and real-world actions. At a high level an agent:
Uses tools (code that calls an external API or system).
Keeps context and memory across steps.
Calls one or more LLMs to plan and decide.
Runs an observe → think → act loop until the task completes.
Example task: Ask FlyGPT (a hypothetical app) to book a flight. The agent:
Queries multiple airline systems,
Compares results to user preferences,
Chooses and books a flight,
Returns booking references — without manual steps from the user.
Agents in developer toolsMany modern IDE assistants already work in “agent mode.” Instead of returning a single static answer, an agent can accept a larger task and perform a sequence of operations:
Search the codebase,
Inspect Git history,
Run commands in a terminal,
Iterate until the task is resolved.
This multi-step execution can include several LLM calls and multiple tool invocations.
Build agents or use pre-built agentsYou can choose different approaches to adopt agents:
Use hosted, pre-built agents (platform examples: agent.ai).
Use no-code automation platforms such as n8n to compose workflows.
Build custom agents programmatically with frameworks like LangChain or LangGraph.
Tools: the agent’s action primitivesA tool is the code that enables an agent to interact with a third-party API or system. For the flight example, each airline would have a tool that searches or books flights. The agent uses the tool to retrieve structured data and consults the LLM to determine the next action.How applications interact — a short API refresherHumans use websites and mobile apps (UI). Applications talking to other applications use APIs that return structured data (JSON) rather than scraping HTML.Example: a scraped HTML search result (simplified)
Different APIs, different schemasEach provider may expose different endpoints and field names, which historically required custom adapters.Examples of varying APIs (curl + JSON response)
Adapters vs. a standardized discovery protocolTraditionally you’d write adapter code for each provider. In agent-based systems we prefer a standardized, machine-readable description that lets agents discover how to call APIs without hand-coding many adapters. This is the purpose of the Model Context Protocol.Model Context Protocol (MCP)MCP (Model Context Protocol) defines a standardized, machine-readable way to describe:
An application’s capabilities (tools),
Tool input and output schemas,
Metadata and safe invocation rules.
Agents run MCP clients; third-party services expose MCP servers. The agent queries an MCP server to discover capabilities and the correct input/output schemas, then invokes the tools safely and predictably.Example MCP capability description
{ "searchFlights": { "description": "Search flights from origin to destination on given date", "input_schema": { "origin": "string", "destination": "string", "date": "YYYY-MM-DD" }, "output_schema": { "flights": "list of flight objects with number" } }, "bookFlight": { "description": "Book a flight for a passenger", "input_schema": { "flightNumber": "string", "passenger": { "firstName": "string", "lastName": "string", "email": "string" }, "seatPreference": "string" } }}
MCP servers and clients
MCP servers: expose capabilities and accept structured invocations.
MCP clients: query servers, discover capabilities, and invoke tools.
Agents typically store MCP client configuration in a small config file (for example mcp.conf or a JSON settings file) that defines available MCP servers and how to launch or connect to them.Example agent-local MCP server configuration (JSON)
Agent2Agent (A2A)As systems scale, you often split responsibilities between specialized agents:
Flight agent — focused on flight search and booking.
Hotel agent — focused on hotel search and reservations.
Agent2Agent (A2A) is a protocol that enables discovery and collaboration among agents:
Agent A asks Agent B what capabilities it exposes.
Agent B replies with a structured capability list.
Agent A delegates a subtask to Agent B and waits for results.
A2A supports discovery, task assignment, status checks, and structured context / result passing between agents.
Real-world use cases
Troubleshooting: An agent inspects Git history and code and identifies the commit that removed a UI element; it can propose a fix or revert plan.
Backend development: An agent runs queries against test databases (via MCP server) to validate API behavior while you build.
Data engineering: Give an agent access to Stripe, BigQuery, and Metabase via MCPs. The agent can correlate data across systems to find missing invoice details.
Illustrative agent tool output (sample)
Called MCP tool execute-query ✓Mumshad 🚀, after updating the query to join invoices using both charges.invoice_id = invoices.id OR invoices.charge_id = charges.id, here's what we get for your charge:Transaction ID | Date | Amount | Currency | Status | Product Name | Product Type | Intervalch_3RPNosLnvBo4cHTg1V2oPR4x | 2025-05-16 12:57:06 | 22140 | USD | succeeded | KodeKloud STANDARD | standard | yearConclusion:• The product details are now correctly retrieved! 🎉• The charge is for KodeKloud STANDARD (type: standard), with a yearly interval.Key Fix:• Always join invoices using both charges.invoice_id = invoices.id and invoices.charge_id = charges.id to catch all cases.
Part 2 — How (preview of the hands-on lab)This lesson includes an interactive FlightSim MCP lab that demonstrates an MCP server and a client integrated into an in-browser VS Code environment. The lab guides you through configuring the client, setting environment variables (API keys provided in the lab), enabling the FlightSim MCP server, and performing searches and bookings through an agent.Important environment variables used in the lab (stored in ~/.bash_profile)
Open the client UI (robot icon in the left panel).
Select “Use your own API key” and choose the OpenAI-compatible provider.
Paste OPENAI_API_BASE and OPENAI_API_KEY from ~/.bash_profile.
Choose a model ID (for example openai/gpt-4.1) and click “Let’s Go”.
Test by sending a short message — the model should respond.
Adding an MCP server for FlightSimIn the client settings (Manage MCP Servers → Configure MCP Servers), provide a JSON config (for example cline_mcp_settings.json) that declares MCP servers. Example FlightSim entry:
After saving this configuration, the client will show FlightSim MCP as available. The agent can query the server for capabilities (e.g., search_flights, book_flight) and will request your approval before any external call is made.Example booking payload (what the MCP server expects when booking a flight)
Preview: small Python agent-client flow (illustrative)This example shows two user clients and demonstrates private thread isolation using langgraph_sdk (async). It is illustrative and intended to show high level semantics:
# example_langgraph_demo.pyimport asynciofrom langgraph_sdk import get_clientasync def main(): # Create clients for both users alice = get_client( url="http://localhost:2024", headers={"Authorization": "Bearer user1-token"} ) bob = get_client( url="http://localhost:2024", headers={"Authorization": "Bearer user2-token"} ) # Alice creates an assistant alice_assistant = await alice.assistants.create() print(f"✅ Alice created assistant: {alice_assistant['assistant_id']}") # Alice creates a thread and chats alice_thread = await alice.threads.create() print(f"✅ Alice created thread: {alice_thread['thread_id']}") await alice.runs.create( thread_id=alice_thread["thread_id"], assistant_id="agent", input={"messages": [{"role": "user", "content": "Hi, this is Alice's private chat"}]} ) # Bob tries to access Alice's thread try: await bob.threads.get(alice_thread["thread_id"]) print("❌ Bob shouldn't see Alice's thread!") except Exception as e: print("✅ Bob correctly denied access:", e) # Bob creates his own thread bob_thread = await bob.threads.create() await bob.runs.create( thread_id=bob_thread["thread_id"], assistant_id="agent", input={"messages": [{"role": "user", "content": "Hi, this is Bob's private chat"}]} ) print(f"✅ Bob created his own thread: {bob_thread['thread_id']}") # List threads - each user only sees their own alice_threads = await alice.threads.search() bob_threads = await bob.threads.search() print(f"✅ Alice sees {len(alice_threads)} thread(s)") print(f"✅ Bob sees {len(bob_threads)} thread(s)")if __name__ == "__main__": asyncio.run(main())
Hands-on lab summary
The FlightSim MCP lab runs in an in-browser VS Code environment.
The lab provides example API keys and a FlightSim MCP server script.
You will configure the client, enable the MCP server, ask the agent to search flights, approve agent tool calls, and try a booking via the FlightSim MCP.
The agent demonstrates the full observe → think → act loop: discover capability → call tool → ask for approval → act → return results.
Best practice: always review MCP capability descriptions before approving an agent’s tool call. The MCP metadata shows required inputs, outputs, and any safety or authorization constraints.
Wrapping upMCP servers provide a standard mechanism for agents to discover and invoke third-party capabilities safely. Agent2Agent enables agents to cooperate and delegate tasks to specialized agents. Together, MCP + A2A allow you to build systems where LLM-guided agents take meaningful actions across distributed services — from booking flights to debugging production systems.If you want hands-on experience, run the FlightSim MCP lab included in this lesson. The next lesson will dive deeper into implementing MCP servers, designing tool schemas, and demonstrating Agent2Agent interactions in code.Links and references
Model Context Protocol (MCP) — open specifications and examples
Anthropic — MCP introduction and materials
LangChain — agent frameworks and integrations
LangGraph — graph-based agent orchestration
n8n — no-code automation, workflow builder
Security reminder: never share real API keys in public docs or repositories. Use environment variables and secret stores for credentials — review access permissions before enabling any MCP server.