⚠️ อัปเดตสำคัญ: ตั้งแต่ MCP Specification วันที่ 18 มิถุนายน 2025 การใช้งาน SSE (Server-Sent Events) แบบเดี่ยวได้ถูก ยกเลิก และแทนที่ด้วย "Streamable HTTP" transport สเปค MCP ปัจจุบันกำหนดวิธีการส่งข้อมูลหลักสองแบบ:
- stdio - การส่งข้อมูลผ่าน input/output มาตรฐาน (แนะนำสำหรับเซิร์ฟเวอร์ในเครื่อง)
- Streamable HTTP - สำหรับเซิร์ฟเวอร์ระยะไกลที่อาจใช้ SSE ภายใน
บทเรียนนี้ได้รับการปรับปรุงเพื่อเน้นที่ stdio transport ซึ่งเป็นวิธีที่แนะนำสำหรับการใช้งานเซิร์ฟเวอร์ MCP ส่วนใหญ่
stdio transport ช่วยให้เซิร์ฟเวอร์ MCP สื่อสารกับไคลเอนต์ผ่าน input และ output มาตรฐาน นี่เป็นวิธีการส่งข้อมูลที่ใช้บ่อยที่สุดและแนะนำในสเปค MCP ปัจจุบัน โดยให้วิธีที่ง่ายและมีประสิทธิภาพในการสร้างเซิร์ฟเวอร์ MCP ที่สามารถผสานรวมกับแอปพลิเคชันไคลเอนต์ต่างๆ ได้อย่างง่ายดาย
บทเรียนนี้ครอบคลุมวิธีการสร้างและใช้งานเซิร์ฟเวอร์ MCP โดยใช้ stdio transport
เมื่อจบบทเรียนนี้ คุณจะสามารถ:
- สร้างเซิร์ฟเวอร์ MCP โดยใช้ stdio transport
- ดีบักเซิร์ฟเวอร์ MCP ด้วย Inspector
- ใช้งานเซิร์ฟเวอร์ MCP ผ่าน Visual Studio Code
- เข้าใจกลไกการส่งข้อมูล MCP ปัจจุบันและเหตุผลที่ stdio ถูกแนะนำ
stdio transport เป็นหนึ่งในสองประเภทการส่งข้อมูลที่รองรับในสเปค MCP ปัจจุบัน (18 มิถุนายน 2025) วิธีการทำงานมีดังนี้:
- การสื่อสารที่ง่าย: เซิร์ฟเวอร์อ่านข้อความ JSON-RPC จาก input มาตรฐาน (
stdin) และส่งข้อความไปยัง output มาตรฐาน (stdout) - กระบวนการพื้นฐาน: ไคลเอนต์เปิดเซิร์ฟเวอร์ MCP เป็น subprocess
- รูปแบบข้อความ: ข้อความเป็นคำขอ JSON-RPC การแจ้งเตือน หรือการตอบกลับ โดยแยกด้วยบรรทัดใหม่
- การบันทึก: เซิร์ฟเวอร์ อาจ เขียนข้อความ UTF-8 ไปยัง error มาตรฐาน (
stderr) เพื่อบันทึกข้อมูล
- ข้อความ ต้อง แยกด้วยบรรทัดใหม่และ ต้องไม่ มีบรรทัดใหม่ฝังอยู่
- เซิร์ฟเวอร์ ต้องไม่ เขียนสิ่งใดไปยัง
stdoutที่ไม่ใช่ข้อความ MCP ที่ถูกต้อง - ไคลเอนต์ ต้องไม่ เขียนสิ่งใดไปยัง
stdinของเซิร์ฟเวอร์ที่ไม่ใช่ข้อความ MCP ที่ถูกต้อง
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{
name: "example-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);ในโค้ดข้างต้น:
- เรา import
ServerและStdioServerTransportจาก MCP SDK - เราสร้าง instance ของเซิร์ฟเวอร์ด้วยการตั้งค่าพื้นฐานและความสามารถ
import asyncio
import logging
from mcp.server import Server
from mcp.server.stdio import stdio_server
# Create server instance
server = Server("example-server")
@server.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
async def main():
async with stdio_server(server) as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())ในโค้ดข้างต้น:
- เราสร้าง instance ของเซิร์ฟเวอร์โดยใช้ MCP SDK
- กำหนดเครื่องมือด้วย decorators
- ใช้ context manager
stdio_serverเพื่อจัดการ transport
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddMcpServer()
.WithStdioTransport()
.WithTools<Tools>();
builder.Services.AddLogging(logging => logging.AddConsole());
var app = builder.Build();
await app.RunAsync();ความแตกต่างสำคัญจาก SSE คือ stdio servers:
- ไม่ต้องตั้งค่าเว็บเซิร์ฟเวอร์หรือ endpoints HTTP
- ถูกเปิดใช้งานเป็น subprocess โดยไคลเอนต์
- สื่อสารผ่าน streams stdin/stdout
- ง่ายต่อการพัฒนาและดีบัก
ในการสร้างเซิร์ฟเวอร์ของเรา เราต้องคำนึงถึงสองสิ่ง:
- เราต้องใช้เว็บเซิร์ฟเวอร์เพื่อเปิดเผย endpoints สำหรับการเชื่อมต่อและข้อความ
ในห้องปฏิบัติการนี้ เราจะสร้างเซิร์ฟเวอร์ MCP แบบง่ายโดยใช้ stdio transport ที่แนะนำ เซิร์ฟเวอร์นี้จะเปิดเผยเครื่องมือที่ไคลเอนต์สามารถเรียกใช้ได้โดยใช้ Model Context Protocol มาตรฐาน
- Python 3.8 หรือใหม่กว่า
- MCP Python SDK:
pip install mcp - ความเข้าใจพื้นฐานเกี่ยวกับการเขียนโปรแกรมแบบ async
เริ่มต้นสร้างเซิร์ฟเวอร์ MCP stdio แรกของเรา:
import asyncio
import logging
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create the server
server = Server("example-stdio-server")
@server.tool()
def calculate_sum(a: int, b: int) -> int:
"""Calculate the sum of two numbers"""
return a + b
@server.tool()
def get_greeting(name: str) -> str:
"""Generate a personalized greeting"""
return f"Hello, {name}! Welcome to MCP stdio server."
async def main():
# Use stdio transport
async with stdio_server(server) as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())Stdio Transport (มาตรฐานปัจจุบัน):
- โมเดล subprocess ที่ง่าย - ไคลเอนต์เปิดเซิร์ฟเวอร์เป็น child process
- สื่อสารผ่าน stdin/stdout โดยใช้ข้อความ JSON-RPC
- ไม่ต้องตั้งค่าเว็บเซิร์ฟเวอร์
- ประสิทธิภาพและความปลอดภัยที่ดีกว่า
- ง่ายต่อการดีบักและพัฒนา
SSE Transport (ยกเลิกตั้งแต่ MCP 18 มิถุนายน 2025):
- ต้องใช้เว็บเซิร์ฟเวอร์พร้อม endpoints SSE
- การตั้งค่าที่ซับซ้อนมากขึ้นด้วยโครงสร้างพื้นฐานเว็บเซิร์ฟเวอร์
- ข้อพิจารณาด้านความปลอดภัยเพิ่มเติมสำหรับ endpoints HTTP
- ถูกแทนที่ด้วย Streamable HTTP สำหรับสถานการณ์ที่ใช้เว็บ
ในการสร้างเซิร์ฟเวอร์ stdio เราต้อง:
- Import ไลบรารีที่จำเป็น - เราต้องใช้ส่วนประกอบเซิร์ฟเวอร์ MCP และ stdio transport
- สร้าง instance ของเซิร์ฟเวอร์ - กำหนดเซิร์ฟเวอร์พร้อมความสามารถ
- กำหนดเครื่องมือ - เพิ่มฟังก์ชันที่เราต้องการเปิดเผย
- ตั้งค่า transport - กำหนดการสื่อสาร stdio
- รันเซิร์ฟเวอร์ - เริ่มเซิร์ฟเวอร์และจัดการข้อความ
มาสร้างทีละขั้นตอน:
import asyncio
import logging
from mcp.server import Server
from mcp.server.stdio import stdio_server
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create the server
server = Server("example-stdio-server")
@server.tool()
def get_greeting(name: str) -> str:
"""Generate a personalized greeting"""
return f"Hello, {name}! Welcome to MCP stdio server."
async def main():
async with stdio_server(server) as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())@server.tool()
def calculate_sum(a: int, b: int) -> int:
"""Calculate the sum of two numbers"""
return a + b
@server.tool()
def calculate_product(a: int, b: int) -> int:
"""Calculate the product of two numbers"""
return a * b
@server.tool()
def get_server_info() -> dict:
"""Get information about this MCP server"""
return {
"server_name": "example-stdio-server",
"version": "1.0.0",
"transport": "stdio",
"capabilities": ["tools"]
}บันทึกโค้ดเป็น server.py และรันจาก command line:
python server.pyเซิร์ฟเวอร์จะเริ่มต้นและรอ input จาก stdin โดยสื่อสารผ่านข้อความ JSON-RPC ผ่าน stdio transport
คุณสามารถทดสอบเซิร์ฟเวอร์ของคุณโดยใช้ MCP Inspector:
- ติดตั้ง Inspector:
npx @modelcontextprotocol/inspector - รัน Inspector และชี้ไปที่เซิร์ฟเวอร์ของคุณ
- ทดสอบเครื่องมือที่คุณสร้างขึ้น
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddMcpServer();
## Debugging your stdio server
### Using the MCP Inspector
The MCP Inspector is a valuable tool for debugging and testing MCP servers. Here's how to use it with your stdio server:
1. **Install the Inspector**:
```bash
npx @modelcontextprotocol/inspector-
Run the Inspector:
npx @modelcontextprotocol/inspector python server.py
-
Test your server: The Inspector provides a web interface where you can:
- View server capabilities
- Test tools with different parameters
- Monitor JSON-RPC messages
- Debug connection issues
You can also debug your MCP server directly in VS Code:
-
Create a launch configuration in
.vscode/launch.json:{ "version": "0.2.0", "configurations": [ { "name": "Debug MCP Server", "type": "python", "request": "launch", "program": "server.py", "console": "integratedTerminal" } ] } -
Set breakpoints in your server code
-
Run the debugger and test with the Inspector
- Use
stderrfor logging - never write tostdoutas it's reserved for MCP messages - Ensure all JSON-RPC messages are newline-delimited
- Test with simple tools first before adding complex functionality
- Use the Inspector to verify message formats
Once you've built your MCP stdio server, you can integrate it with VS Code to use it with Claude or other MCP-compatible clients.
-
Create an MCP configuration file at
%APPDATA%\Claude\claude_desktop_config.json(Windows) or~/Library/Application Support/Claude/claude_desktop_config.json(Mac):{ "mcpServers": { "example-stdio-server": { "command": "python", "args": ["path/to/your/server.py"] } } } -
Restart Claude: Close and reopen Claude to load the new server configuration.
-
Test the connection: Start a conversation with Claude and try using your server's tools:
- "Can you greet me using the greeting tool?"
- "Calculate the sum of 15 and 27"
- "What's the server info?"
Here's a complete TypeScript example for reference:
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{
name: "example-stdio-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// Add tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get_greeting",
description: "Get a personalized greeting",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Name of the person to greet",
},
},
required: ["name"],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get_greeting") {
return {
content: [
{
type: "text",
text: `Hello, ${request.params.arguments?.name}! Welcome to MCP stdio server.`,
},
],
};
} else {
throw new Error(`Unknown tool: ${request.params.name}`);
}
});
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
runServer().catch(console.error);using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddMcpServer()
.WithStdioTransport()
.WithTools<Tools>();
var app = builder.Build();
await app.RunAsync();
public class Tools
{
[Description("Get a personalized greeting")]
public string GetGreeting(string name)
{
return $"Hello, {name}! Welcome to MCP stdio server.";
}
[Description("Calculate the sum of two numbers")]
public int CalculateSum(int a, int b)
{
return a + b;
}
}In this updated lesson, you learned how to:
- Build MCP servers using the current stdio transport (recommended approach)
- Understand why SSE transport was deprecated in favor of stdio and Streamable HTTP
- Create tools that can be called by MCP clients
- Debug your server using the MCP Inspector
- Integrate your stdio server with VS Code and Claude
The stdio transport provides a simpler, more secure, and more performant way to build MCP servers compared to the deprecated SSE approach. It's the recommended transport for most MCP server implementations as of the 2025-06-18 specification.
### .NET
1. สร้างเครื่องมือก่อน โดยสร้างไฟล์ *Tools.cs* ด้วยเนื้อหาดังนี้:
```csharp
using System.ComponentModel;
using System.Text.Json;
using ModelContextProtocol.Server;
## Exercise: Testing your stdio server
Now that you've built your stdio server, let's test it to make sure it works correctly.
### Prerequisites
1. Ensure you have the MCP Inspector installed:
```bash
npm install -g @modelcontextprotocol/inspector
- Your server code should be saved (e.g., as
server.py)
-
Start the Inspector with your server:
npx @modelcontextprotocol/inspector python server.py
-
เปิดอินเทอร์เฟซเว็บ: Inspector จะเปิดหน้าต่างเบราว์เซอร์ที่แสดงความสามารถของเซิร์ฟเวอร์ของคุณ
-
ทดสอบเครื่องมือ:
- ลองใช้เครื่องมือ
get_greetingกับชื่อที่แตกต่างกัน - ทดสอบเครื่องมือ
calculate_sumกับตัวเลขต่างๆ - เรียกใช้เครื่องมือ
get_server_infoเพื่อดูข้อมูลเมตาของเซิร์ฟเวอร์
- ลองใช้เครื่องมือ
-
ตรวจสอบการสื่อสาร: Inspector แสดงข้อความ JSON-RPC ที่แลกเปลี่ยนระหว่างไคลเอนต์และเซิร์ฟเวอร์
เมื่อเซิร์ฟเวอร์ของคุณเริ่มต้นอย่างถูกต้อง คุณควรเห็น:
- ความสามารถของเซิร์ฟเวอร์ที่แสดงใน Inspector
- เครื่องมือที่พร้อมใช้งานสำหรับการทดสอบ
- การแลกเปลี่ยนข้อความ JSON-RPC ที่สำเร็จ
- การตอบกลับของเครื่องมือที่แสดงในอินเทอร์เฟซ
เซิร์ฟเวอร์ไม่เริ่มต้น:
- ตรวจสอบว่าติดตั้ง dependencies ทั้งหมดแล้ว:
pip install mcp - ตรวจสอบไวยากรณ์ Python และการเยื้อง
- ดูข้อความแสดงข้อผิดพลาดในคอนโซล
เครื่องมือไม่ปรากฏ:
- ตรวจสอบว่า
@server.tool()decorators มีอยู่ - ตรวจสอบว่าฟังก์ชันเครื่องมือถูกกำหนดก่อน
main() - ตรวจสอบว่าเซิร์ฟเวอร์ถูกตั้งค่าอย่างถูกต้อง
ปัญหาการเชื่อมต่อ:
- ตรวจสอบว่าเซิร์ฟเวอร์ใช้ stdio transport อย่างถูกต้อง
- ตรวจสอบว่าไม่มีกระบวนการอื่นรบกวน
- ตรวจสอบไวยากรณ์คำสั่ง Inspector
ลองสร้างเซิร์ฟเวอร์ของคุณด้วยความสามารถเพิ่มเติม ดู หน้านี้ เพื่อเพิ่มเครื่องมือที่เรียก API ตัวอย่าง คุณสามารถออกแบบเซิร์ฟเวอร์ได้ตามต้องการ สนุกกับการสร้างนะ :)
คำตอบ นี่คือตัวอย่างคำตอบพร้อมโค้ดที่ใช้งานได้
สิ่งที่ควรจดจำจากบทนี้คือ:
- stdio transport เป็นกลไกที่แนะนำสำหรับเซิร์ฟเวอร์ MCP ในเครื่อง
- stdio transport ช่วยให้การสื่อสารระหว่างเซิร์ฟเวอร์ MCP และไคลเอนต์เป็นไปอย่างราบรื่นโดยใช้ input และ output มาตรฐาน
- คุณสามารถใช้ Inspector และ Visual Studio Code เพื่อใช้งานเซิร์ฟเวอร์ stdio ได้โดยตรง ทำให้การดีบักและการผสานรวมเป็นเรื่องง่าย
ตอนนี้คุณได้เรียนรู้วิธีสร้างเซิร์ฟเวอร์ MCP ด้วย stdio transport แล้ว คุณสามารถสำรวจหัวข้อขั้นสูงเพิ่มเติมได้:
- ขั้นตอนถัดไป: HTTP Streaming with MCP (Streamable HTTP) - เรียนรู้เกี่ยวกับกลไกการส่งข้อมูลที่รองรับอีกแบบสำหรับเซิร์ฟเวอร์ระยะไกล
- ขั้นสูง: MCP Security Best Practices - ใช้การรักษาความปลอดภัยในเซิร์ฟเวอร์ MCP ของคุณ
- การใช้งานจริง: Deployment Strategies - นำเซิร์ฟเวอร์ของคุณไปใช้งานจริง
- MCP Specification 2025-06-18 - สเปคอย่างเป็นทางการ
- MCP SDK Documentation - เอกสารอ้างอิง SDK สำหรับทุกภาษา
- Community Examples - ตัวอย่างเซิร์ฟเวอร์เพิ่มเติมจากชุมชน
ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษามืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้