Model Context Protocol (MCP): Building an AI-to-API Bridge
1. What Is MCP?
Model Context Protocol (MCP) allows an AI assistant such as Kiro, Codex, Claude, or another MCP-compatible agent to interact with external systems in a structured way.
A useful mental model is:
AI Agent --> MCP Client --> MCP Server -->
External API / Database / Application
Enter fullscreen mode Exit fullscreen mode
For this example, assume we have an internal Todo Management API called TodoHub.
TodoHub provides REST APIs such as:
GET /todos/123
POST /todos
PUT /todos/123
POST /todos/123/comments
Enter fullscreen mode Exit fullscreen mode
We want an AI agent to understand requests such as:
Show todo 123
or:
Create a high-priority todo for fixing the login issue.
Our MCP server acts as the bridge between the AI agent and the TodoHub API.
2. What Are We Building?
Our architecture will look like this:
User ----> "Show todo 123"
AI Agent
(Kiro / Codex / Claude) ----> MCP tool call
TodoHub MCP Server ----> HTTP REST call ---> TodoHub API
Enter fullscreen mode Exit fullscreen mode
The MCP server exposes tools such as:
get_todo
create_todo
update_todo
add_comment
Enter fullscreen mode Exit fullscreen mode
These are MCP tools.
The AI does not need to know exactly how the underlying REST API works.
It only needs to understand the tool and its input:
Tool: get_todo
Input:
todo_id
Enter fullscreen mode Exit fullscreen mode
The MCP server handles the actual API communication.
For example:
AI ----> get_todo(todo_id=123)
|
|-----> MCP Server ---> GET /api/todos/123
----> TodoHub
Enter fullscreen mode Exit fullscreen mode
3. MCP Server vs REST API
This distinction is important.
You might wonder:
Why don’t we simply give the AI our REST API?
The reason is that an MCP server provides the AI with a cleaner, AI-friendly abstraction over the underlying API.
Your REST API might require something like:
POST /api/v2/workitems
Enter fullscreen mode Exit fullscreen mode
with a request body:
{
"subject": "...",
"type_id": 7,
"priority_id": 3,
"workspace_id": 19,
"creator": 758
}
Enter fullscreen mode Exit fullscreen mode
However, exposing all these internal implementation details to the AI is unnecessary.
Instead, the MCP tool could expose a much simpler interface:
create_todo(
title,
description,
priority
)
Enter fullscreen mode Exit fullscreen mode
The MCP server translates the AI-friendly parameters into the parameters required by the internal application.
For example:
priority = "high"
│
▼
MCP Server
│
▼
priority_id = 3
Enter fullscreen mode Exit fullscreen mode
So the architecture becomes:
AI-friendly parameters
│
▼
MCP Server
│
▼
Internal application parameters
│
▼
REST API
Enter fullscreen mode Exit fullscreen mode
This keeps implementation details away from the AI and gives the AI a simpler interface to work with.
4. MCP Tools
An MCP server can expose different tools for different operations.
For our TodoHub example:
MCP Tool Purposeget_todo
Retrieve a todo
create_todo
Create a new todo
update_todo
Update an existing todo
add_comment
Add a comment to a todo
For example:
get_todo
Input:
todo_id: integer
Enter fullscreen mode Exit fullscreen mode
create_todo
Input:
title: string
description: string
priority: string
Enter fullscreen mode Exit fullscreen mode
The AI can then select the appropriate tool based on the user’s request.
5. Configuring the MCP Server
The AI agent needs to know how to start and communicate with the MCP server.
For example, we can create an mcp.json configuration file:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"todohub": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"mcp-todohub",
"mcp-todohub"
],
"env": {
"TODOHUB_URL": "https://todos.example.com",
"TODOHUB_API_KEY": "xxxxx"
}
}
}
}
Enter fullscreen mode Exit fullscreen mode
The important parts are:
mcpServers
│
└── todohub
│
|___ SKILL.md
├── type
├── command
├── args
└── env
Enter fullscreen mode Exit fullscreen mode
The configuration tells the AI client:
- An MCP server named
todohubis available. - The server communicates using
stdio. -
uvxis used to start the server. - The required environment variables are provided to the server.
6. Example End-to-End Flow
Let’s follow one complete request.
User
Show me todo 123.
Step 1 — AI understands the request
The AI determines that the user wants information about a todo.
Intent:
Retrieve todo information
Todo ID:
123
Enter fullscreen mode Exit fullscreen mode
Step 2 — AI sees the available MCP tools
The MCP server has advertised tools such as:
get_todo(todo_id: int)
create_todo(...)
update_todo(...)
add_comment(...)
Enter fullscreen mode Exit fullscreen mode
Step 3 — AI selects the appropriate tool
The AI chooses:
get_todo
Enter fullscreen mode Exit fullscreen mode
with:
todo_id = 123
Enter fullscreen mode Exit fullscreen mode
Step 4 — MCP Tool Call
Conceptually, the request looks like:
{
"name": "get_todo",
"arguments": {
"todo_id": 123
}
}
Enter fullscreen mode Exit fullscreen mode
Step 5 — MCP Server Executes the Tool
The MCP server receives the request and executes something equivalent to:
get_todo(123)
Enter fullscreen mode Exit fullscreen mode
Step 6 — Python Calls the REST API
The MCP server then communicates with TodoHub:
GET https://todos.example.com/api/todos/123
Enter fullscreen mode Exit fullscreen mode
Step 7 — TodoHub Responds
TodoHub returns:
{
"id": 123,
"title": "Payment timeout",
"status": "In Progress"
}
Enter fullscreen mode Exit fullscreen mode
Step 8 — MCP Server Returns the Result
The MCP server sends the result back to the AI:
TodoHub
↓
MCP Server
↓
AI
Enter fullscreen mode Exit fullscreen mode
Step 9 — AI Answers Naturally
The AI can now respond to the user:
Task #123 is “Payment timeout” and is currently In Progress.
7. The Complete MCP Cycle
Putting everything together:
User
│
│ "Show me todo 123"
▼
AI Agent
│
│ Understands intent
▼
Selects MCP Tool
│
│ get_todo(todo_id=123)
▼
MCP Server
│
│ Translates tool input
▼
REST API
│
│ GET /api/todos/123
▼
TodoHub
│
│ Returns JSON
▼
MCP Server
│
│ Returns structured result
▼
AI Agent
│
│ Generates natural-language response
▼
User
Enter fullscreen mode Exit fullscreen mode
The key idea is:
MCP provides a standardized bridge between an AI agent and external systems.
The AI works with meaningful tools such as get_todo and create_todo, while the MCP server takes care of authentication, API calls, parameter translation, and other implementation details.
That is the complete MCP cycle.
Adding SKILL.md
Additionally, we can have a SKILL.md file under the MCP project directory structure mentioned above.
This becomes particularly useful when the MCP tool needs business context or parameter-building guidance that cannot be expressed cleanly through the tool schema alone.
MCP Tool vs SKILL.md vs MCP Server
An important distinction is:
Component Purpose MCP Tool Definition Tells the AI what the tool does and what parameters it accepts.SKILL.md
Provides additional instructions, context, rules, examples, and parameter-building guidance for the agent.
MCP Server Code
Validates and translates the parameters before making the actual REST API call.
A SKILL.md generally contains:
→ Business context
→ How to construct parameters
→ Business rules
→ Examples
Enter fullscreen mode Exit fullscreen mode
For example, the MCP tool might simply define:
create_task(
title,
description,
priority
)
Enter fullscreen mode Exit fullscreen mode
While SKILL.md can explain how the AI should derive those parameters from the user’s request, including business rules and examples.
Keeping SKILL.md Maintainable
If SKILL.md becomes too large, we can split the content into multiple Markdown files and organize them under a references directory.
For example:
taskhub-mcp/
├── SKILL.md
├── server.py
├── tools/
│ ├── get_task.py
│ ├── create_task.py
│ ├── update_task.py
│ └── add_comment.py
└── references/
├── task-creation.md
├── priority-rules.md
└── business-rules.md
Enter fullscreen mode Exit fullscreen mode
This keeps the main SKILL.md concise while allowing more detailed business context to be maintained separately.
Happy reading!