API quick refresher
APIs are an integral part of our systems. All the modern systems of today are using APIs.
They follow the HTTP protocol using the following verbs, each of which brings its own advantage and necessity. To summarize each one of them, below is a quick refresher, using the analogy of a restaurant for each verb:
HTTP Verb | Need/Purpose | Restaurant Analogy | Idempotent? |
---|
GET | Retrieve data (read-only, safe) | Looking at the restaurant menu | Yes |
POST | Create new data | Placing a new order | No |
PUT | Replace the resource entirely | Replacing your entire meal with another | Yes |
PATCH | Update partially | Asking for a side dessert | No |
DELETE | Removing resource | Returning an empty plate | Yes |
OPTIONS | Find allowed actions | Asking what things are allowed in a restaurant | Yes |
Now, all the above verbs are standardized by all the widely adopted programming languages.
Now, let's create a basic FastAPI using Python.
python -m venv venv #create virtual environment
venv/Scripts/activate #activate virtual environment
pip install fastapi[standard]
Now, create mainapp.py
from fastapi import FastAPI
app = FastAPI()
menu = ["Pizza", "Burger", "Pasta"]
current_order: str = None
@app.get("/menu")
def get_menu():
return {"menu": menu}
@app.post("/order")
def place_order(item: str):
global current_order
current_order = item
return {"message": f"Order placed for {item}"}
@app.put("/order")
def replace_order(new_item: str):
global current_order
current_order = new_item
return {"message": f"Order replaced with {new_item}"}
@app.delete("/order")
def delete_order():
global current_order
current_order = None
return {"message": "Order deleted (empty plate)"}
@app.patch("/order")
def patch_order(side_dish: str):
global current_order
if not current_order:
return {"error": "No order to update"}
current_order = f"{current_order} with {side_dish}"
return {"message": f"Order updated: {current_order}"}
@app.options("/order")
def options_order():
return {
"allowed_methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"message": "You can look at menu, place, replace, delete, or update an order."
}
Start the app
fastapi dev mainapp.py
FastAPI Starting development server 🚀
Searching for package file structure from directories with __init__.py files
Importing from E:\KnowledgeSharing\API Basics
module 🐍 mainapp.py
code Importing the FastAPI app object from the module with the following code:
from mainapp import app
app Using import string: mainapp:app
server Server started at http://127.0.0.1:8000
server Documentation at http://127.0.0.1:8000/docs
tip Running in development mode, for production use: fastapi run
Logs:
INFO Will watch for changes in these directories: ['E:\\KnowledgeSharing\\API Basics']
INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO Started reloader process [12696] using WatchFiles
INFO Started server process [2952]
INFO Waiting for application startup.
INFO Application startup complete.
INFO 127.0.0.1:54932 - "GET /docs HTTP/1.1" 200
INFO 127.0.0.1:54932 - "GET /openapi.json HTTP/1.1" 200
Now our App is up and running,
![fastapidemo]()
As you can see from the Swagger documentation above, all the endpoints are neatly organized.
It also contains /openapi.json if you look closely below the title - FastAPI
This Open API json is a specification (spec) file provided by all the popular frameworks in different programming languages.
What is the Open API spec?
Open API Specification (formerly was also known as the Swagger Specification), is language-agnostic standard for defining and documenting RESTful APIs. It provides a structured way to describe the endpoints, request/response formats, authentication methods, and other capabilities of an API. By using the Open API Spec, both humans and machines can easily understand how a service works without needing direct access to its source code, detailed documentation, or analyzing network traffic.
This makes it highly useful for developers, testers, and automated tools to generate client SDKs, server stubs, and interactive documentation, ultimately streamlining the entire API development and integration process.
Now, from our above API, we can see this spec file.
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/menu": {
"get": {
"summary": "Get Menu",
"operationId": "get_menu_menu_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
}
},
"/order": {
"post": {
"summary": "Place Order",
"operationId": "place_order_order_post",
"parameters": [
{
"name": "item",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Item"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"put": {
"summary": "Replace Order",
"operationId": "replace_order_order_put",
"parameters": [
{
"name": "new_item",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "New Item"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"delete": {
"summary": "Delete Order",
"operationId": "delete_order_order_delete",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
},
"patch": {
"summary": "Patch Order",
"operationId": "patch_order_order_patch",
"parameters": [
{
"name": "side_dish",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Side Dish"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"options": {
"summary": "Options Order",
"operationId": "options_order_order_options",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
}
}
}
Now, let's convert it to be utilized by AI-first systems. For this, we will convert this to an MCP server. This MCP server is consumed by AI Agents such as GitHub Co-pilot, Claude desktop, etc, to perform actions.
In short, our APIs will be directly consumed by Agentic systems.
Let's install the FastMCP Python package.
pip install fastmcp
Now let's create the mcpapp.py
import httpx
from fastmcp import FastMCP
# Create an HTTP client for your API
client = httpx.AsyncClient(base_url="http://localhost:8000")
# Load your OpenAPI spec
openapi_spec = httpx.get("http://localhost:8000/openapi.json").json()
# Create the MCP server
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="My Restaurant Assistant"
)
if __name__ == "__main__":
mcp.run(transport="http", port=8001)
Start the app
python mcpapp.py
[09/12/25 20:41:51] INFO Using legacy OpenAPI parser. To use the new parser, set server.py:2013
FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER=true. The
new parser was introduced for testing in 2.11 and will
become the default soon.
INFO Created FastMCP OpenAPI server with 6 routes openapi.py:827
╭────────────────────────────────────────────────────────────────────────────╮
│ │
│ _ __ ___ _____ __ __ _____________ ____ ____ │
│ _ __ ___ .'____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \ │
│ _ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / / │
│ _ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ / │
│ _ __ ___ /_/ \____/____/\__/_/ /_/\____/_/ /_____(*)____/ │
│ │
│ │
│ FastMCP 2.0 │
│ │
│ │
│ 🖥️ Server name: My Restaurant Assistant │
│ 📦 Transport: Streamable-HTTP │
│ 🔗 Server URL: http://127.0.0.1:8001/mcp │
│ │
│ 🏎️ FastMCP version: 2.12.3 │
│ 🤝 MCP SDK version: 1.14.0 │
│ │
│ 📚 Docs: https://gofastmcp.com │
│ 🚀 Deploy: https://fastmcp.cloud │
│ │
╰────────────────────────────────────────────────────────────────────────────╯
INFO Starting MCP server 'My Restaurant Assistant' with server.py:1572
transport 'http' on http://127.0.0.1:8001/mcp
E:\KnowledgeSharing\API Basics\venv\Lib\site-packages\websockets\legacy\__init__.py:6: DeprecationWarning: websockets.legacy is deprecated; see https://websockets.readthedocs.io/en/stable/howto/upgrade.html for upgrade instructions
warnings.warn( # deprecated in 14.0 - 2024-11-09
E:\KnowledgeSharing\API Basics\venv\Lib\site-packages\uvicorn\protocols\websockets\websockets_impl.py:17: DeprecationWarning: websockets.server.WebSocketServerProtocol is deprecated
from websockets.server import WebSocketServerProtocol
INFO: Started server process [7996]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
INFO: 127.0.0.1:53885 - "GET / HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:53885 - "GET /favicon.ico HTTP/1.1" 404 Not Found
That's it !! Now, our app is up and running for consumption. Let's interact with it with the help of an Agent.
We can set up the VS Code agent by configuring the settings below in the workspace. File will be .vscode/mcp.json.
{
"servers": {
"local-restaurant-mcp": {
"url": "http://localhost:8001/mcp",
"type": "http"
}
},
"inputs": []
}
Now, let's interact with the agent. We will perform the two interactions:
Below is the screenshot of how seamlessly our AI Agent interacts with our APIs via the MCP server.
![order_demo-img]()
That's it! Thanks for reading till the end. We learned how to build APIs, convert to an MCP server, and integrate with Agents.
API quick refresher
APIs are an integral part of our systems. All the modern systems of today are using APIs.
They follow the HTTP protocol using the following verbs, each of which brings its own advantage and necessity. To summarize each one of them, below is a quick refresher, using the analogy of a restaurant for each verb:
HTTP Verb | Need/Purpose | Restaurant Analogy | Idempotent? |
---|
GET | Retrieve data (read-only, safe) | Looking at the restaurant menu | Yes |
POST | Create new data | Placing a new order | No |
PUT | Replace the resource entirely | Replacing your entire meal with another | Yes |
PATCH | Update partially | Asking for a side dessert | No |
DELETE | Removing resource | Returning an empty plate | Yes |
OPTIONS | Find allowed actions | Asking what things are allowed in a restaurant | Yes |
Now, all the above verbs are standardized by all the widely adopted programming languages.
Now, let's create a basic FastAPI using Python.
python -m venv venv #create virtual environment
venv/Scripts/activate #activate virtual environment
pip install fastapi[standard]
Now, create mainapp.py
from fastapi import FastAPI
app = FastAPI()
menu = ["Pizza", "Burger", "Pasta"]
current_order: str = None
@app.get("/menu")
def get_menu():
return {"menu": menu}
@app.post("/order")
def place_order(item: str):
global current_order
current_order = item
return {"message": f"Order placed for {item}"}
@app.put("/order")
def replace_order(new_item: str):
global current_order
current_order = new_item
return {"message": f"Order replaced with {new_item}"}
@app.delete("/order")
def delete_order():
global current_order
current_order = None
return {"message": "Order deleted (empty plate)"}
@app.patch("/order")
def patch_order(side_dish: str):
global current_order
if not current_order:
return {"error": "No order to update"}
current_order = f"{current_order} with {side_dish}"
return {"message": f"Order updated: {current_order}"}
@app.options("/order")
def options_order():
return {
"allowed_methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"message": "You can look at menu, place, replace, delete, or update an order."
}
Start the app
fastapi dev mainapp.py
FastAPI Starting development server 🚀
Searching for package file structure from directories with __init__.py files
Importing from E:\KnowledgeSharing\API Basics
module 🐍 mainapp.py
code Importing the FastAPI app object from the module with the following code:
from mainapp import app
app Using import string: mainapp:app
server Server started at http://127.0.0.1:8000
server Documentation at http://127.0.0.1:8000/docs
tip Running in development mode, for production use: fastapi run
Logs:
INFO Will watch for changes in these directories: ['E:\\KnowledgeSharing\\API Basics']
INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO Started reloader process [12696] using WatchFiles
INFO Started server process [2952]
INFO Waiting for application startup.
INFO Application startup complete.
INFO 127.0.0.1:54932 - "GET /docs HTTP/1.1" 200
INFO 127.0.0.1:54932 - "GET /openapi.json HTTP/1.1" 200
Now our App is up and running,
![fastapidemo]()
As you can see from the Swagger documentation above, all the endpoints are neatly organized.
It also contains /openapi.json if you look closely below the title - FastAPI
This Open API json is a specification (spec) file provided by all the popular frameworks in different programming languages.
What is the Open API spec?
Open API Specification (formerly was also known as the Swagger Specification), is language-agnostic standard for defining and documenting RESTful APIs. It provides a structured way to describe the endpoints, request/response formats, authentication methods, and other capabilities of an API. By using the Open API Spec, both humans and machines can easily understand how a service works without needing direct access to its source code, detailed documentation, or analyzing network traffic.
This makes it highly useful for developers, testers, and automated tools to generate client SDKs, server stubs, and interactive documentation, ultimately streamlining the entire API development and integration process.
Now, from our above API, we can see this spec file.
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/menu": {
"get": {
"summary": "Get Menu",
"operationId": "get_menu_menu_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
}
},
"/order": {
"post": {
"summary": "Place Order",
"operationId": "place_order_order_post",
"parameters": [
{
"name": "item",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Item"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"put": {
"summary": "Replace Order",
"operationId": "replace_order_order_put",
"parameters": [
{
"name": "new_item",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "New Item"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"delete": {
"summary": "Delete Order",
"operationId": "delete_order_order_delete",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
},
"patch": {
"summary": "Patch Order",
"operationId": "patch_order_order_patch",
"parameters": [
{
"name": "side_dish",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Side Dish"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
},
"options": {
"summary": "Options Order",
"operationId": "options_order_order_options",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
}
}
}
Now, let's convert it to be utilized by AI-first systems. For this, we will convert this to an MCP server. This MCP server is consumed by AI Agents such as GitHub Co-pilot, Claude desktop, etc, to perform actions.
In short, our APIs will be directly consumed by Agentic systems.
Let's install the FastMCP Python package.
pip install fastmcp
Now let's create the mcpapp.py
import httpx
from fastmcp import FastMCP
# Create an HTTP client for your API
client = httpx.AsyncClient(base_url="http://localhost:8000")
# Load your OpenAPI spec
openapi_spec = httpx.get("http://localhost:8000/openapi.json").json()
# Create the MCP server
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="My Restaurant Assistant"
)
if __name__ == "__main__":
mcp.run(transport="http", port=8001)
Start the app
python mcpapp.py
[09/12/25 20:41:51] INFO Using legacy OpenAPI parser. To use the new parser, set server.py:2013
FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER=true. The
new parser was introduced for testing in 2.11 and will
become the default soon.
INFO Created FastMCP OpenAPI server with 6 routes openapi.py:827
╭────────────────────────────────────────────────────────────────────────────╮
│ │
│ _ __ ___ _____ __ __ _____________ ____ ____ │
│ _ __ ___ .'____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \ │
│ _ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / / │
│ _ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ / │
│ _ __ ___ /_/ \____/____/\__/_/ /_/\____/_/ /_____(*)____/ │
│ │
│ │
│ FastMCP 2.0 │
│ │
│ │
│ 🖥️ Server name: My Restaurant Assistant │
│ 📦 Transport: Streamable-HTTP │
│ 🔗 Server URL: http://127.0.0.1:8001/mcp │
│ │
│ 🏎️ FastMCP version: 2.12.3 │
│ 🤝 MCP SDK version: 1.14.0 │
│ │
│ 📚 Docs: https://gofastmcp.com │
│ 🚀 Deploy: https://fastmcp.cloud │
│ │
╰────────────────────────────────────────────────────────────────────────────╯
INFO Starting MCP server 'My Restaurant Assistant' with server.py:1572
transport 'http' on http://127.0.0.1:8001/mcp
E:\KnowledgeSharing\API Basics\venv\Lib\site-packages\websockets\legacy\__init__.py:6: DeprecationWarning: websockets.legacy is deprecated; see https://websockets.readthedocs.io/en/stable/howto/upgrade.html for upgrade instructions
warnings.warn( # deprecated in 14.0 - 2024-11-09
E:\KnowledgeSharing\API Basics\venv\Lib\site-packages\uvicorn\protocols\websockets\websockets_impl.py:17: DeprecationWarning: websockets.server.WebSocketServerProtocol is deprecated
from websockets.server import WebSocketServerProtocol
INFO: Started server process [7996]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
INFO: 127.0.0.1:53885 - "GET / HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:53885 - "GET /favicon.ico HTTP/1.1" 404 Not Found
That's it !! Now, our app is up and running for consumption. Let's interact with it with the help of an Agent.
We can set up the VS Code agent by configuring the settings below in the workspace. File will be .vscode/mcp.json.
{
"servers": {
"local-restaurant-mcp": {
"url": "http://localhost:8001/mcp",
"type": "http"
}
},
"inputs": []
}
Now, let's interact with the agent. We will perform the two interactions:
Below is the screenshot of how seamlessly our AI Agent interacts with our APIs via the MCP server.
![order_demo-img]()
That's it! Thanks for reading till the end. We learned how to build APIs, convert to an MCP server, and integrate with Agents.