cd /news/developer-tools/how-to-create-an-mcp-server-tutorial Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-107584] src=dev.to β†— pub= topic=developer-tools verified=true sentiment=Β· neutral

How to Create an MCP Server: Tutorial

A developer has published a tutorial explaining how to create a Model Context Protocol (MCP) server, which allows AI assistants like Kiro, Codex, and Claude to interact with external systems. The tutorial uses a fictional TodoHub API to demonstrate how MCP servers provide an AI-friendly abstraction over REST APIs, translating simple tool inputs into complex API calls. It includes configuration examples using an mcp.json file and explains the architecture of AI agent, MCP client, and MCP server.

read5 min views3 publishedAug 23, 2026

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

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

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.

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

The MCP server exposes tools such as:

get_todo
create_todo
update_todo
add_comment

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

The MCP server handles the actual API communication.

For example:

AI  ----> get_todo(todo_id=123)
 |
 |-----> MCP Server ---> GET /api/todos/123
 ----> TodoHub

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

with a request body:

{
  "subject": "...",
  "type_id": 7,
  "priority_id": 3,
  "workspace_id": 19,
  "creator": 758
}

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
)

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

So the architecture becomes:

AI-friendly parameters
        β”‚
        β–Ό
    MCP Server
        β”‚
        β–Ό
Internal application parameters
        β”‚
        β–Ό
     REST API

This keeps implementation details away from the AI and gives the AI a simpler interface to work with.

An MCP server can expose different tools for different operations.

For our TodoHub example:

MCP Tool Purpose
get_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

create_todo

Input:
  title: string
  description: string
  priority: string

The AI can then select the appropriate tool based on the user's request.

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"
      }
    }
  }
}

The important parts are:

mcpServers
    β”‚
    └── todohub
          β”‚
          |___ SKILL.md
          β”œβ”€β”€ type
          β”œβ”€β”€ command
          β”œβ”€β”€ args
          └── env

The configuration tells the AI client:

todohub

is available.stdio

.uvx

is used to start the server.Let's follow one complete request.

Show me todo 123.

The AI determines that the user wants information about a todo.

Intent:
Retrieve todo information

Todo ID:
123

The MCP server has advertised tools such as:

get_todo(todo_id: int)
create_todo(...)
update_todo(...)
add_comment(...)

The AI chooses:

get_todo

with:

todo_id = 123

Conceptually, the request looks like:

{
  "name": "get_todo",
  "arguments": {
    "todo_id": 123
  }
}

The MCP server receives the request and executes something equivalent to:

get_todo(123)

The MCP server then communicates with TodoHub:

GET https://todos.example.com/api/todos/123

TodoHub returns:

{
  "id": 123,
  "title": "Payment timeout",
  "status": "In Progress"
}

The MCP server sends the result back to the AI:

TodoHub
   ↓
MCP Server
   ↓
AI

The AI can now respond to the user:

Task #123 is

"Payment timeout"and is currentlyIn Progress.

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

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.

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.

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

For example, the MCP tool might simply define:

create_task(
    title,
    description,
    priority
)

While SKILL.md

can explain how the AI should derive those parameters from the user's request, including business rules and examples.

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

This keeps the main SKILL.md

concise while allowing more detailed business context to be maintained separately.

Happy reading!

── more in #developer-tools 4 stories Β· sorted by recency
── more on @kiro 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/how-to-create-an-mcp…] indexed:0 read:5min 2026-08-23 Β· β€”