O'z MCP serveringizni yozish

MCP — bu protokol, ya'ni siz o'zingizning serveringizni yozib, agentga istalgan imkoniyatni bera olasiz: ichki API'ga ulanish, ma'lumotlar bazasi, korxona tizimlari. Bu qo'llanmada — noldan ishlaydigan MCP server qurish, Python (FastMCP) va TypeScript'da.
MCP server nima qiladi?
Server agentga uch turdagi narsa beradi:
- Tools (vositalar) — agent bajaradigan amallar (funksiya chaqirish: "ob-havoni ol", "DB'ga yoz")
- Resources (resurslar) — agent o'qiydigan ma'lumotlar (fayl, jadval, hujjat)
- Prompts (promtlar) — tayyor shablon promtlar
Python — FastMCP bilan
Eng oson yo'l. fastmcp kutubxonasi dekoratorlar bilan ishlaydi.
O'rnatish
pip install fastmcp
Eng oddiy server
from fastmcp import FastMCP
mcp = FastMCP("Mening serverim")
@mcp.tool()
def ob_havo(shahar: str) -> str:
"""Berilgan shahar uchun ob-havoni qaytaradi."""
# bu yerda real API chaqiruvi
return f"{shahar}: 22°C, quyoshli"
if __name__ == "__main__":
mcp.run()
Tamom. @mcp.tool() dekoratori funksiyani agent uchun vositaga aylantiradi. Docstring — agentga tushuntirish (juda muhim — agent shu asosida qachon chaqirishni biladi).
Resource qo'shish
@mcp.resource("config://settings")
def get_settings() -> str:
"""Ilova sozlamalarini qaytaradi."""
return open("settings.json").read()
Parametrli tool — DB misol
import sqlite3
@mcp.tool()
def foydalanuvchi_qidir(email: str) -> dict:
"""Email bo'yicha foydalanuvchini bazadan topadi."""
conn = sqlite3.connect("app.db")
cur = conn.execute(
"SELECT id, name, email FROM users WHERE email = ?",
(email,) # parametrlangan — SQL injection'dan himoya
)
row = cur.fetchone()
conn.close()
if not row:
return {"error": "topilmadi"}
return {"id": row[0], "name": row[1], "email": row[2]}
TypeScript — MCP SDK bilan
Node muhitida ishlasangiz.
O'rnatish
npm install @modelcontextprotocol/sdk zod
Server
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "mening-server", version: "1.0.0" });
server.tool(
"ob_havo",
"Berilgan shahar uchun ob-havoni qaytaradi",
{ shahar: z.string() },
async ({ shahar }) => {
return {
content: [{ type: "text", text: `${shahar}: 22°C, quyoshli` }]
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
zod — parametrlar sxemasi va validatsiya. Agent qaysi argumentlar kerakligini shundan biladi.
Transport turlari
- stdio — server agent bilan bir mashinada, jarayon orqali. Eng oddiy, lokal vositalar uchun.
- HTTP / SSE — server alohida (bulutda). Remote MCP, ko'p foydalanuvchi. Auth kerak.
Claude Code'ga ulash
stdio server uchun:
claude mcp add mening-server python /path/to/server.py
HTTP server uchun:
claude mcp add mening-server --transport http https://my-server.com/mcp
Yoki .mcp.json:
{
"mcpServers": {
"mening-server": {
"command": "python",
"args": ["/path/to/server.py"]
}
}
}
Testlash
MCP Inspector — rasmiy debug vositasi:
npx @modelcontextprotocol/inspector python server.py
Brauzer ochiladi, har bir tool/resource'ni qo'lda sinab ko'rasiz — agent ulashdan oldin.
Yaxshi tool dizayni
Agent tool'ni qanchalik to'g'ri ishlatishi — sizning dizayningizga bog'liq:
- Aniq nom:
foydalanuvchi_qidir,qidiruvemas - Boy docstring: nima qiladi, qachon ishlatiladi, nima qaytaradi
- Aniq parametrlar: type hints + tavsif
- Xato — strukturalashgan:
{"error": "..."}exception emas - Kichik, fokuslangan: bitta tool — bitta ish. "Hamma narsa" tool — yomon
- Idempotent bo'lsa — yaxshi: bir xil input → bir xil natija
Xavfsizlik — qisqacha
MCP server agentga kuch beradi — ehtiyot bo'ling:
- SQL parametrlash (injection'dan)
- Fayl yo'llarini sanitize qilish (path traversal)
- Maxfiy ma'lumotlarni qaytarmaslik (parol, token)
- Yozish/o'chirish amallariga ruxsat nazorati
Batafsil: MCP xavfsizligi.
Real misol: ichki CRM tool
from fastmcp import FastMCP
import httpx
mcp = FastMCP("CRM konnektor")
@mcp.tool()
async def buyurtma_holati(buyurtma_id: str) -> dict:
"""Buyurtma raqami bo'yicha uning holatini qaytaradi."""
async with httpx.AsyncClient() as client:
r = await client.get(
f"https://crm.internal/api/orders/{buyurtma_id}",
headers={"Authorization": f"Bearer {TOKEN}"}
)
if r.status_code == 404:
return {"error": "buyurtma topilmadi"}
return r.json()
if __name__ == "__main__":
mcp.run()
Endi agent: "buyurtma #1234 qayerda?" → tool chaqiradi → CRM'dan javob → foydalanuvchiga.
Anti-paternlar
- Docstring'siz tool: agent qachon chaqirishni bilmaydi → noto'g'ri ishlatadi
- Ulkan "do everything" tool: 10 ta parametr, 5 xil rejim — agent chalkashadi. Bo'ling
- Xom exception: agent stack trace'ni ko'radi, tushunmaydi. Strukturalashgan xato qaytaring
- Sinovsiz deploy: Inspector'da sinamasdan agentga ulash — debug qiyin
- Sekin tool, timeout'siz: agent kutib qoladi. Async + timeout qo'ying
Keyingi qadamlar
- MCP nima — protokol asoslari
- MCP serverlarini tanlash — tayyor serverlar
- MCP xavfsizligi — auth, scopes, prompt injection