Skip to content

Agent ๅ่ฎฎ๏ผšMCP ไธŽ A2A ๐Ÿ”— โ€‹

"ๆ ‡ๅ‡†ๅŒ–ๅ่ฎฎๆ˜ฏ AI ็”Ÿๆ€็ณป็ปŸไบ’่”ไบ’้€š็š„ๅŸบ็ก€่ฎพๆ–ฝใ€‚"

้š็€ AI Agent ็”Ÿๆ€็š„ๅฟซ้€Ÿๅ‘ๅฑ•๏ผŒไธคไธช้‡่ฆ็š„ๅผ€ๆ”พๅ่ฎฎๆญฃๅœจๆˆไธบ่กŒไธšๆ ‡ๅ‡†๏ผšModel Context Protocol (MCP) ็”จไบŽ AI ๆจกๅž‹ไธŽๅทฅๅ…ท/ๆ•ฐๆฎๆบ็š„้›†ๆˆ๏ผŒAgent2Agent (A2A) ็”จไบŽ AI Agent ไน‹้—ด็š„้€šไฟกๅไฝœใ€‚็†่งฃ่ฟ™ไธคไธชๅ่ฎฎๅฏนไบŽๆž„ๅปบ็Žฐไปฃ AI ๅบ”็”จ่‡ณๅ…ณ้‡่ฆใ€‚

1. ๅ่ฎฎๅ…จๆ™ฏๅ›พ โ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        AI Agent ๅ่ฎฎ็”Ÿๆ€                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚    โ”‚                    Agent2Agent (A2A)                         โ”‚      โ”‚
โ”‚    โ”‚              Agent โ†โ†’ Agent ้€šไฟกไธŽๅไฝœ                        โ”‚      โ”‚
โ”‚    โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚      โ”‚
โ”‚    โ”‚    โ”‚ Agent A โ”‚ โ†โ†’โ”‚ Agent B โ”‚ โ†โ†’โ”‚ Agent C โ”‚                   โ”‚      โ”‚
โ”‚    โ”‚    โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                   โ”‚      โ”‚
โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚              โ”‚             โ”‚             โ”‚                               โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚    โ”‚         โ”‚   Model Context Protocol (MCP)                     โ”‚      โ”‚
โ”‚    โ”‚         โ”‚     Model โ†โ†’ Tools/Data ้›†ๆˆ                       โ”‚      โ”‚
โ”‚    โ”‚         โ–ผ             โ–ผ             โ–ผ                        โ”‚      โ”‚
โ”‚    โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚      โ”‚
โ”‚    โ”‚    โ”‚ MCP     โ”‚   โ”‚ MCP     โ”‚   โ”‚ MCP     โ”‚                   โ”‚      โ”‚
โ”‚    โ”‚    โ”‚ Server  โ”‚   โ”‚ Server  โ”‚   โ”‚ Server  โ”‚                   โ”‚      โ”‚
โ”‚    โ”‚    โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                   โ”‚      โ”‚
โ”‚    โ”‚         โ”‚             โ”‚             โ”‚                        โ”‚      โ”‚
โ”‚    โ”‚         โ–ผ             โ–ผ             โ–ผ                        โ”‚      โ”‚
โ”‚    โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚      โ”‚
โ”‚    โ”‚    โ”‚Database โ”‚   โ”‚  API    โ”‚   โ”‚ Files   โ”‚                   โ”‚      โ”‚
โ”‚    โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚      โ”‚
โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1.1 ๅ่ฎฎๅฎšไฝๅฏนๆฏ” โ€‹

็ปดๅบฆMCP (Model Context Protocol)A2A (Agent2Agent)
ๅ‘่ตทๆ–นAnthropic (2024.11)Google Cloud (2025.04)
ๆ ธๅฟƒ็›ฎๆ ‡AI ๆจกๅž‹ไธŽๅทฅๅ…ท/ๆ•ฐๆฎๆบ็š„ๆ ‡ๅ‡†ๅŒ–้›†ๆˆAI Agent ไน‹้—ด็š„ไบ’ๆ“ไฝœๆ€งไธŽๅไฝœ
้€šไฟกๅฏน่ฑกModel โ†” Server (Tools/Resources)Agent โ†” Agent
ไธป่ฆๅœบๆ™ฏ่ฏปๅ–ๆ–‡ไปถใ€่ฐƒ็”จ APIใ€ๆ‰ง่กŒๆ“ไฝœไปปๅŠกๅง”ๆดพใ€ไฟกๆฏไบคๆขใ€ๅไฝœๅทฅไฝœๆต
ๅ่ฎฎๅŸบ็ก€JSON-RPC 2.0HTTP, SSE, JSON-RPC
้‡‡็”จๆ–นOpenAI, Google DeepMind, Cursor50+ ๅˆไฝœไผ™ไผด๏ผˆSalesforce, SAP ็ญ‰๏ผ‰

1.2 ไบ’่กฅๅ…ณ็ณป โ€‹

ๅœบๆ™ฏ็คบไพ‹๏ผšไผไธšๆ™บ่ƒฝๅทฅไฝœๆต

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ็”จๆˆท่ฏทๆฑ‚๏ผš"ๅˆ†ๆžๆœ€่ฟ‘็š„้”€ๅ”ฎๆ•ฐๆฎ๏ผŒ็”ŸๆˆๆŠฅๅ‘Šๅนถๅ‘้€็ป™ๅ›ข้˜Ÿ"               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ”‚
                                โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    ๅ่ฐƒ Agent (Orchestrator)                     โ”‚
โ”‚  ไฝฟ็”จ A2A ๅ่ฎฎๅง”ๆดพไปปๅŠก็ป™ไธ“ไธš Agent                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚ A2A                  โ”‚ A2A                  โ”‚ A2A
            โ–ผ                      โ–ผ                      โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  ๆ•ฐๆฎๅˆ†ๆž    โ”‚        โ”‚  ๆŠฅๅ‘Š็”Ÿๆˆ    โ”‚        โ”‚  ้‚ฎไปถๅ‘้€    โ”‚
   โ”‚   Agent     โ”‚        โ”‚   Agent     โ”‚        โ”‚   Agent     โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚ MCP                   โ”‚ MCP                  โ”‚ MCP
          โ–ผ                       โ–ผ                      โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Database   โ”‚        โ”‚   Doc API   โ”‚        โ”‚  Email API  โ”‚
   โ”‚  MCP Server โ”‚        โ”‚  MCP Server โ”‚        โ”‚  MCP Server โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2. Model Context Protocol (MCP) โ€‹

2.1 ๆ ธๅฟƒๆฆ‚ๅฟต โ€‹

MCP ๅฎšไน‰ไบ† AI ๆจกๅž‹ไธŽๅค–้ƒจ็ณป็ปŸไบคไบ’็š„ๆ ‡ๅ‡†ๅŒ–ๆ–นๅผ๏ผŒๆ ธๅฟƒๆžถๆž„ๅŒ…ๅซไธ‰ไธช่ง’่‰ฒ๏ผš

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          MCP ๆžถๆž„                                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚   MCP Host   โ”‚          โ”‚  MCP Client  โ”‚          โ”‚  MCP Server  โ”‚  โ”‚
โ”‚  โ”‚  (ๅฆ‚ Cursor) โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚   (ๅ่ฎฎๅฑ‚)    โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚  (ๅทฅๅ…ทๆไพ›ๆ–น) โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚        โ”‚                          โ”‚                          โ”‚         โ”‚
โ”‚        โ”‚                          โ”‚                          โ”‚         โ”‚
โ”‚        โ–ผ                          โ–ผ                          โ–ผ         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ ็”จๆˆท็•Œ้ข      โ”‚          โ”‚ ๆถˆๆฏ่ทฏ็”ฑ      โ”‚          โ”‚ ๅ…ทไฝ“ๅฎž็Žฐ      โ”‚  โ”‚
โ”‚  โ”‚ ๆƒ้™็ฎก็†      โ”‚          โ”‚ ๅ่ฎฎ่ฝฌๆข      โ”‚          โ”‚ ๅทฅๅ…ท/่ต„ๆบ     โ”‚  โ”‚
โ”‚  โ”‚ ไผš่ฏ็ฎก็†      โ”‚          โ”‚ ่ฟžๆŽฅ็ฎก็†      โ”‚          โ”‚ ๆ็คบๆจกๆฟ      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ไธ‰ไธช่ง’่‰ฒ๏ผš

่ง’่‰ฒ่Œ่ดฃ็คบไพ‹
Hostๅฎน็บณ AI ๅบ”็”จ็š„ๅฎฟไธป็ŽฏๅขƒCursor IDE, Claude Desktop
ClientไธŽ Server ๅปบ็ซ‹่ฟžๆŽฅ็š„ๅ่ฎฎๅฑ‚MCP SDK ๅฎขๆˆท็ซฏๅฎž็Žฐ
Serverๆไพ›ๅทฅๅ…ทใ€่ต„ๆบๅ’Œๆ็คบ็š„ๆœๅŠก็ซฏๆ–‡ไปถ็ณป็ปŸ Server, GitHub Server

2.2 ไธ‰ๅคงๆ ธๅฟƒ่ƒฝๅŠ› โ€‹

MCP Server ๅฏไปฅๆไพ›ไธ‰็ง็ฑปๅž‹็š„่ƒฝๅŠ›๏ผš

typescript
// 1. Resources - ่ต„ๆบ๏ผˆ็ฑปไผผ REST ่ต„ๆบ๏ผ‰
// ๆไพ›ๆ•ฐๆฎ่ฏปๅ–่ƒฝๅŠ›๏ผŒ็”ฑ Server ๆšด้œฒ๏ผŒ็”ฑ Client ่ฏปๅ–

interface Resource {
  uri: string;           // ่ต„ๆบๅ”ฏไธ€ๆ ‡่ฏ†๏ผŒๅฆ‚ "file:///path/to/file.txt"
  name: string;          // ไบบ็ฑปๅฏ่ฏปๅ็งฐ
  description?: string;  // ่ต„ๆบๆ่ฟฐ
  mimeType?: string;     // MIME ็ฑปๅž‹
}

// 2. Tools - ๅทฅๅ…ท๏ผˆๆจกๅž‹ๅฏ่ฐƒ็”จ็š„ๅ‡ฝๆ•ฐ๏ผ‰
// ๅ…่ฎธ AI ๆ‰ง่กŒๆ“ไฝœ๏ผŒ้œ€่ฆๆจกๅž‹ไธปๅŠจ่ฐƒ็”จ

interface Tool {
  name: string;
  description: string;
  inputSchema: JSONSchema;  // JSON Schema ๅฎšไน‰ๅ‚ๆ•ฐ
}

// 3. Prompts - ๆ็คบๆจกๆฟ๏ผˆๅฏๅค็”จ็š„ๆ็คบ๏ผ‰
// ้ข„ๅฎšไน‰็š„ๆ็คบๆจกๆฟ๏ผŒๆ”ฏๆŒๅ‚ๆ•ฐๅŒ–

interface Prompt {
  name: string;
  description?: string;
  arguments?: PromptArgument[];
}

2.3 ้€šไฟกๅ่ฎฎ โ€‹

MCP ๅŸบไบŽ JSON-RPC 2.0๏ผŒๆ”ฏๆŒๅคš็งไผ ่พ“ๅฑ‚๏ผš

typescript
// ่ฏทๆฑ‚ๆ ผๅผ
interface JSONRPCRequest {
  jsonrpc: "2.0";
  id: string | number;
  method: string;
  params?: object;
}

// ๅ“ๅบ”ๆ ผๅผ
interface JSONRPCResponse {
  jsonrpc: "2.0";
  id: string | number;
  result?: any;
  error?: {
    code: number;
    message: string;
    data?: any;
  };
}

// ้€š็Ÿฅๆ ผๅผ๏ผˆๆ— ้œ€ๅ“ๅบ”๏ผ‰
interface JSONRPCNotification {
  jsonrpc: "2.0";
  method: string;
  params?: object;
}

ๆ”ฏๆŒ็š„ไผ ่พ“ๅฑ‚๏ผš

ไผ ่พ“ๆ–นๅผ้€‚็”จๅœบๆ™ฏ็‰น็‚น
stdioๆœฌๅœฐ่ฟ›็จ‹้€šไฟก็ฎ€ๅ•ๅฏ้ ๏ผŒ้€‚ๅˆๆœฌๅœฐ Server
HTTP + SSE่ฟœ็จ‹ๆœๅŠกๆ”ฏๆŒ Web ้ƒจ็ฝฒ๏ผŒ้€‚ๅˆไบ‘ๆœๅŠก
WebSocketๅฎžๆ—ถๅŒๅ‘้€šไฟกไฝŽๅปถ่ฟŸ๏ผŒ้€‚ๅˆ้ซ˜้ข‘ไบคไบ’

2.4 ๅฎž็Žฐ MCP Server โ€‹

ๅŸบ็ก€ Server ๅฎž็Žฐ (TypeScript) โ€‹

typescript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

// ๅˆ›ๅปบ Server ๅฎžไพ‹
const server = new Server(
  {
    name: "my-mcp-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},      // ๅฃฐๆ˜Žๆ”ฏๆŒๅทฅๅ…ท
      resources: {},  // ๅฃฐๆ˜Žๆ”ฏๆŒ่ต„ๆบ
    },
  }
);

// ๅฎšไน‰ๅทฅๅ…ทๅˆ—่กจ
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "search_codebase",
      description: "ๅœจไปฃ็ ๅบ“ไธญ่ฏญไน‰ๆœ็ดข",
      inputSchema: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description: "ๆœ็ดขๆŸฅ่ฏข"
          },
          maxResults: {
            type: "number",
            description: "ๆœ€ๅคง็ป“ๆžœๆ•ฐ",
            default: 10
          }
        },
        required: ["query"]
      }
    },
    {
      name: "read_file",
      description: "่ฏปๅ–ๆ–‡ไปถๅ†…ๅฎน",
      inputSchema: {
        type: "object",
        properties: {
          path: { type: "string", description: "ๆ–‡ไปถ่ทฏๅพ„" }
        },
        required: ["path"]
      }
    }
  ]
}));

// ๅฎž็Žฐๅทฅๅ…ท่ฐƒ็”จ
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  switch (name) {
    case "search_codebase": {
      const results = await performSearch(args.query, args.maxResults);
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(results, null, 2)
          }
        ]
      };
    }
    
    case "read_file": {
      const content = await fs.readFile(args.path, "utf-8");
      return {
        content: [
          {
            type: "text",
            text: content
          }
        ]
      };
    }
    
    default:
      throw new Error(`Unknown tool: ${name}`);
  }
});

// ๅฎšไน‰่ต„ๆบๅˆ—่กจ
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
  resources: [
    {
      uri: "config://app-settings",
      name: "ๅบ”็”จ้…็ฝฎ",
      description: "ๅบ”็”จ็จ‹ๅบ็š„้…็ฝฎไฟกๆฏ",
      mimeType: "application/json"
    }
  ]
}));

// ๅฎž็Žฐ่ต„ๆบ่ฏปๅ–
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const { uri } = request.params;
  
  if (uri === "config://app-settings") {
    return {
      contents: [
        {
          uri,
          mimeType: "application/json",
          text: JSON.stringify(appConfig, null, 2)
        }
      ]
    };
  }
  
  throw new Error(`Unknown resource: ${uri}`);
});

// ๅฏๅŠจ Server
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Server running on stdio");
}

main().catch(console.error);

Python ๅฎž็Žฐ โ€‹

python
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, Resource

# ๅˆ›ๅปบ Server
server = Server("my-python-server")

# ๅฎšไน‰ๅทฅๅ…ท
@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="execute_python",
            description="ๆ‰ง่กŒ Python ไปฃ็ ๅนถ่ฟ”ๅ›ž็ป“ๆžœ",
            inputSchema={
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "่ฆๆ‰ง่กŒ็š„ Python ไปฃ็ "
                    }
                },
                "required": ["code"]
            }
        )
    ]

# ๅฎž็Žฐๅทฅๅ…ท่ฐƒ็”จ
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "execute_python":
        try:
            # ๅฎ‰ๅ…จ่€ƒ่™‘๏ผšๅฎž้™…ๅบ”็”จไธญ้œ€่ฆๆฒ™็ฎฑๆ‰ง่กŒ
            result = eval(arguments["code"])
            return [TextContent(type="text", text=str(result))]
        except Exception as e:
            return [TextContent(type="text", text=f"Error: {e}")]
    
    raise ValueError(f"Unknown tool: {name}")

# ๅฏๅŠจ Server
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

2.5 ๅฎž็Žฐ MCP Client โ€‹

typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { spawn } from "child_process";

async function createClient() {
  // ๅฏๅŠจ Server ่ฟ›็จ‹
  const serverProcess = spawn("node", ["./my-server.js"]);
  
  // ๅˆ›ๅปบไผ ่พ“ๅฑ‚
  const transport = new StdioClientTransport({
    command: "node",
    args: ["./my-server.js"]
  });
  
  // ๅˆ›ๅปบ Client
  const client = new Client(
    { name: "my-client", version: "1.0.0" },
    { capabilities: {} }
  );
  
  // ่ฟžๆŽฅๅˆฐ Server
  await client.connect(transport);
  
  return client;
}

async function main() {
  const client = await createClient();
  
  // ๅˆ—ๅ‡บๅฏ็”จๅทฅๅ…ท
  const { tools } = await client.listTools();
  console.log("Available tools:", tools.map(t => t.name));
  
  // ่ฐƒ็”จๅทฅๅ…ท
  const result = await client.callTool({
    name: "search_codebase",
    arguments: { query: "authentication", maxResults: 5 }
  });
  
  console.log("Search results:", result.content);
  
  // ๅˆ—ๅ‡บ่ต„ๆบ
  const { resources } = await client.listResources();
  console.log("Available resources:", resources.map(r => r.name));
  
  // ่ฏปๅ–่ต„ๆบ
  const resource = await client.readResource({
    uri: "config://app-settings"
  });
  
  console.log("Config:", resource.contents);
}

2.6 ้…็ฝฎไธŽ้›†ๆˆ โ€‹

Cursor/Claude Desktop ้…็ฝฎ โ€‹

json
// ~/.cursor/mcp.json ๆˆ– claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
      "env": {}
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "your-github-token"
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@localhost/db"
      }
    },
    "custom-server": {
      "command": "node",
      "args": ["/path/to/my-custom-server.js"],
      "cwd": "/path/to/working/dir"
    }
  }
}

2.7 ๅฎ‰ๅ…จๆœ€ไฝณๅฎž่ทต โ€‹

typescript
// 1. ๆƒ้™ๆŽงๅˆถ
const ALLOWED_PATHS = [
  process.env.HOME,
  '/tmp',
  process.cwd()
];

function validatePath(path: string): boolean {
  const resolved = path.resolve(path);
  return ALLOWED_PATHS.some(allowed => 
    resolved.startsWith(allowed)
  );
}

// 2. ่พ“ๅ…ฅ้ชŒ่ฏ
import { z } from 'zod';

const SearchArgsSchema = z.object({
  query: z.string().min(1).max(1000),
  maxResults: z.number().int().positive().max(100).default(10)
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const args = SearchArgsSchema.parse(request.params.arguments);
  // ไฝฟ็”จ้ชŒ่ฏๅŽ็š„ args
});

// 3. ้€Ÿ็އ้™ๅˆถ
import { RateLimiter } from 'rate-limiter';

const limiter = new RateLimiter({
  tokensPerInterval: 100,
  interval: "minute"
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (!limiter.tryRemoveTokens(1)) {
    throw new Error("Rate limit exceeded");
  }
  // ๅค„็†่ฏทๆฑ‚
});

// 4. ๅฎก่ฎกๆ—ฅๅฟ—
function logToolCall(name: string, args: any, result: any) {
  const entry = {
    timestamp: new Date().toISOString(),
    tool: name,
    arguments: args,
    resultSize: JSON.stringify(result).length,
    // ไธ่ฎฐๅฝ•ๆ•ๆ„Ÿๅ†…ๅฎน
  };
  
  auditLogger.info(entry);
}

3. Agent2Agent Protocol (A2A) โ€‹

3.1 ๆ ธๅฟƒๆฆ‚ๅฟต โ€‹

A2A ๅ่ฎฎไธ“ๆณจไบŽ AI Agent ไน‹้—ด็š„้€šไฟกไธŽๅไฝœ๏ผŒๆ ธๅฟƒ็›ฎๆ ‡ๆ˜ฏๅฎž็Žฐ่ทจๅนณๅฐใ€่ทจๆก†ๆžถ็š„ Agent ไบ’ๆ“ไฝœใ€‚

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          A2A ้€šไฟกๆจกๅž‹                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚ Client Agent โ”‚                              โ”‚ Remote Agent โ”‚        โ”‚
โ”‚  โ”‚  (่ฏทๆฑ‚ๆ–น)     โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€ A2A Protocol โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚  (ๆœๅŠกๆ–น)     โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚         โ”‚                                              โ”‚               โ”‚
โ”‚         โ”‚    1. ๅ‘็Žฐ (Agent Card)                       โ”‚               โ”‚
โ”‚         โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚               โ”‚
โ”‚         โ”‚                                              โ”‚               โ”‚
โ”‚         โ”‚    2. ๅ‘่ตทไปปๅŠก (Task)                         โ”‚               โ”‚
โ”‚         โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚               โ”‚
โ”‚         โ”‚                                              โ”‚               โ”‚
โ”‚         โ”‚    3. ็Šถๆ€ๆ›ดๆ–ฐ (SSE Stream)                   โ”‚               โ”‚
โ”‚         โ”‚ โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚               โ”‚
โ”‚         โ”‚                                              โ”‚               โ”‚
โ”‚         โ”‚    4. ไบคๆขๆถˆๆฏ (Message)                      โ”‚               โ”‚
โ”‚         โ”‚ โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚               โ”‚
โ”‚         โ”‚                                              โ”‚               โ”‚
โ”‚         โ”‚    5. ่ฟ”ๅ›ž็ป“ๆžœ (Artifact)                     โ”‚               โ”‚
โ”‚         โ”‚ โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚               โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3.2 ่ฎพ่ฎกๅŽŸๅˆ™ โ€‹

A2A ็š„ไบ”ๅคง่ฎพ่ฎกๅŽŸๅˆ™๏ผš

ๅŽŸๅˆ™ๆ่ฟฐ
ๆ‹ฅๆŠฑ Agent ่ƒฝๅŠ›ๅ…่ฎธ Agent ไปฅ่‡ช็„ถใ€้ž็ป“ๆž„ๅŒ–็š„ๆ–นๅผๅไฝœ๏ผŒๆ— ้œ€ๅ…ฑไบซๅ†…ๅญ˜ๆˆ–ๅทฅๅ…ท
ๅŸบไบŽ็Žฐๆœ‰ๆ ‡ๅ‡†ไฝฟ็”จ HTTPใ€SSEใ€JSON-RPC๏ผŒไพฟไบŽไธŽไผไธš IT ้›†ๆˆ
้ป˜่ฎคๅฎ‰ๅ…จๆ”ฏๆŒไผไธš็บง่บซไปฝ้ชŒ่ฏๅ’ŒๆŽˆๆƒ๏ผˆOAuth 2.0ใ€W3C DID๏ผ‰
ๆ”ฏๆŒ้•ฟไปปๅŠก็ตๆดปๅค„็†ไปŽ็ง’็บงๅˆฐๆ•ฐๅคฉ็š„ไปปๅŠก๏ผŒๆไพ›ๅฎžๆ—ถ็Šถๆ€ๆ›ดๆ–ฐ
ๆจกๆ€ๆ— ๅ…ณๆ”ฏๆŒๆ–‡ๆœฌใ€้Ÿณ้ข‘ใ€่ง†้ข‘ใ€่กจๅ•ใ€iframe ็ญ‰ๅคš็งไบคไบ’ๅฝขๅผ

3.3 ๆ ธๅฟƒๅฎžไฝ“ โ€‹

Agent Card - Agent ่บซไปฝๅก โ€‹

Agent Card ๆ˜ฏ Agent ็š„"ๅ็‰‡"๏ผŒๆ่ฟฐๅ…ถ่ƒฝๅŠ›ๅ’Œ่ฎฟ้—ฎๆ–นๅผ๏ผš

typescript
interface AgentCard {
  // ๅŸบๆœฌไฟกๆฏ
  name: string;                    // Agent ๅ็งฐ
  description: string;             // ่ƒฝๅŠ›ๆ่ฟฐ
  url: string;                     // A2A ็ซฏ็‚น URL
  version: string;                 // ๅ่ฎฎ็‰ˆๆœฌ
  
  // ่ƒฝๅŠ›ๅฃฐๆ˜Ž
  capabilities: {
    streaming?: boolean;           // ๆ˜ฏๅฆๆ”ฏๆŒๆตๅผๅ“ๅบ”
    pushNotifications?: boolean;   // ๆ˜ฏๅฆๆ”ฏๆŒๆŽจ้€้€š็Ÿฅ
    stateTransitionHistory?: boolean; // ๆ˜ฏๅฆๆไพ›็Šถๆ€ๅކๅฒ
  };
  
  // ๆŠ€่ƒฝๅˆ—่กจ
  skills: Skill[];
  
  // ่ฎค่ฏๆ–นๅผ
  authentication: {
    schemes: string[];             // ๅฆ‚ ["oauth2", "api_key"]
    credentials?: string;          // ๅ‡ญ่ฏ่Žทๅ–ๆ–นๅผ
  };
  
  // ้ป˜่ฎค่พ“ๅ…ฅๆจกๆ€
  defaultInputModes: string[];     // ๅฆ‚ ["text", "file"]
  defaultOutputModes: string[];    // ๅฆ‚ ["text", "file", "data"]
  
  // ๆไพ›ๅ•†ไฟกๆฏ
  provider?: {
    organization: string;
    url?: string;
  };
  
  // ๅฏ้€‰ๅ…ƒๆ•ฐๆฎ
  documentationUrl?: string;
  supportUrl?: string;
}

interface Skill {
  id: string;
  name: string;
  description: string;
  tags?: string[];
  examples?: string[];             // ็คบไพ‹่พ“ๅ…ฅ
  inputModes?: string[];
  outputModes?: string[];
}

็คบไพ‹ Agent Card๏ผš

json
{
  "name": "Data Analysis Agent",
  "description": "ไธ“ไธš็š„ๆ•ฐๆฎๅˆ†ๆžๅŠฉๆ‰‹๏ผŒๆ”ฏๆŒๆ•ฐๆฎๆธ…ๆด—ใ€็ปŸ่ฎกๅˆ†ๆžๅ’Œๅฏ่ง†ๅŒ–",
  "url": "https://api.example.com/a2a",
  "version": "1.0.0",
  
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true
  },
  
  "skills": [
    {
      "id": "data-cleaning",
      "name": "ๆ•ฐๆฎๆธ…ๆด—",
      "description": "่‡ชๅŠจๆฃ€ๆต‹ๅนถๅค„็†็ผบๅคฑๅ€ผใ€ๅผ‚ๅธธๅ€ผๅ’Œ้‡ๅคๆ•ฐๆฎ",
      "tags": ["data", "preprocessing"],
      "examples": ["ๆธ…ๆด—่ฟ™ไธช CSV ๆ–‡ไปถ", "ๅค„็†ๆ•ฐๆฎไธญ็š„็ผบๅคฑๅ€ผ"]
    },
    {
      "id": "statistical-analysis", 
      "name": "็ปŸ่ฎกๅˆ†ๆž",
      "description": "ๆ‰ง่กŒๆ่ฟฐๆ€ง็ปŸ่ฎกใ€ๅ‡่ฎพๆฃ€้ชŒๅ’Œ็›ธๅ…ณๆ€งๅˆ†ๆž",
      "tags": ["statistics", "analysis"],
      "examples": ["ๅˆ†ๆž้”€ๅ”ฎๆ•ฐๆฎ็š„่ถ‹ๅŠฟ", "ๆฃ€้ชŒไธค็ป„ๆ•ฐๆฎๆ˜ฏๅฆๆœ‰ๆ˜พ่‘—ๅทฎๅผ‚"]
    }
  ],
  
  "authentication": {
    "schemes": ["oauth2"],
    "credentials": "https://auth.example.com/oauth"
  },
  
  "defaultInputModes": ["text", "file"],
  "defaultOutputModes": ["text", "file", "data"],
  
  "provider": {
    "organization": "Example Corp",
    "url": "https://example.com"
  }
}

Task - ไปปๅŠก โ€‹

Task ๆ˜ฏ A2A ๅไฝœ็š„ๆ ธๅฟƒๅ•ๅ…ƒ๏ผš

typescript
interface Task {
  id: string;                      // ๅ”ฏไธ€ไปปๅŠก ID
  sessionId?: string;              // ไผš่ฏ ID๏ผˆๅคš่ฝฎๅฏน่ฏ๏ผ‰
  
  status: TaskStatus;              // ไปปๅŠก็Šถๆ€
  
  // ๆถˆๆฏๅކๅฒ
  history?: Message[];
  
  // ไปปๅŠกไบง็‰ฉ
  artifacts?: Artifact[];
  
  // ๅ…ƒๆ•ฐๆฎ
  metadata?: Record<string, any>;
}

type TaskStatus = {
  state: TaskState;
  message?: string;                // ็Šถๆ€ๆ่ฟฐ
  timestamp: string;
};

type TaskState = 
  | "submitted"      // ๅทฒๆไบค
  | "working"        // ๅค„็†ไธญ
  | "input-required" // ้œ€่ฆ่พ“ๅ…ฅ
  | "completed"      // ๅทฒๅฎŒๆˆ
  | "failed"         // ๅคฑ่ดฅ
  | "canceled";      // ๅทฒๅ–ๆถˆ

Message - ๆถˆๆฏ โ€‹

typescript
interface Message {
  role: "user" | "agent";
  parts: Part[];
  metadata?: Record<string, any>;
}

type Part = 
  | TextPart
  | FilePart
  | DataPart
  | FormPart;

interface TextPart {
  type: "text";
  text: string;
}

interface FilePart {
  type: "file";
  file: {
    name: string;
    mimeType: string;
    // ไบŒ้€‰ไธ€
    bytes?: string;     // Base64 ็ผ–็ 
    uri?: string;       // ๆ–‡ไปถ URI
  };
}

interface DataPart {
  type: "data";
  data: Record<string, any>;
}

Artifact - ไปปๅŠกไบง็‰ฉ โ€‹

typescript
interface Artifact {
  name?: string;
  description?: string;
  parts: Part[];
  index: number;               // ไบง็‰ฉๅบๅท
  append?: boolean;            // ๆ˜ฏๅฆ่ฟฝๅŠ ๏ผˆๆตๅผ๏ผ‰
  lastChunk?: boolean;         // ๆ˜ฏๅฆๆœ€ๅŽไธ€ๅ—
  metadata?: Record<string, any>;
}

3.4 ้€šไฟกๆต็จ‹ โ€‹

ๅŸบๆœฌ่ฏทๆฑ‚-ๅ“ๅบ”ๆจกๅผ โ€‹

typescript
// 1. ๅ‘้€ไปปๅŠก
POST /a2a/tasks/send
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": "req-1",
  "method": "tasks/send",
  "params": {
    "id": "task-123",
    "message": {
      "role": "user",
      "parts": [
        { "type": "text", "text": "ๅˆ†ๆž่ฟ™ไธช้”€ๅ”ฎๆ•ฐๆฎๅนถ็”ŸๆˆๆŠฅๅ‘Š" },
        { "type": "file", "file": { "name": "sales.csv", "uri": "..." } }
      ]
    }
  }
}

// ๅ“ๅบ”
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "result": {
    "id": "task-123",
    "status": {
      "state": "working",
      "message": "ๆญฃๅœจๅˆ†ๆžๆ•ฐๆฎ...",
      "timestamp": "2025-01-15T10:30:00Z"
    }
  }
}

ๆตๅผๆ›ดๆ–ฐ (SSE) โ€‹

typescript
// ่ฎข้˜…ไปปๅŠกๆ›ดๆ–ฐ
GET /a2a/tasks/task-123/sendSubscribe
Accept: text/event-stream

// Server ๆŽจ้€ไบ‹ไปถ
event: status
data: {"state": "working", "message": "ๆ•ฐๆฎๅŠ ่ฝฝๅฎŒๆˆ..."}

event: artifact
data: {"index": 0, "parts": [{"type": "text", "text": "## ๅˆ†ๆžๆŠฅๅ‘Š\n\n"}], "append": false}

event: artifact
data: {"index": 0, "parts": [{"type": "text", "text": "### 1. ๆฆ‚่งˆ\n..."}], "append": true}

event: status
data: {"state": "completed", "message": "ๅˆ†ๆžๅฎŒๆˆ"}

3.5 ๅฎž็Žฐ A2A Agent โ€‹

Server ๅฎž็Žฐ (TypeScript) โ€‹

typescript
import express from 'express';
import { v4 as uuidv4 } from 'uuid';

const app = express();
app.use(express.json());

// ๅญ˜ๅ‚จไปปๅŠก็Šถๆ€
const tasks = new Map<string, Task>();
const subscribers = new Map<string, Set<express.Response>>();

// Agent Card ็ซฏ็‚น
app.get('/.well-known/agent.json', (req, res) => {
  res.json({
    name: "Data Analysis Agent",
    description: "ๆ•ฐๆฎๅˆ†ๆžไธ“ๅฎถ",
    url: "https://api.example.com/a2a",
    version: "1.0.0",
    capabilities: {
      streaming: true,
      pushNotifications: false
    },
    skills: [
      {
        id: "analyze-data",
        name: "ๆ•ฐๆฎๅˆ†ๆž",
        description: "ๅˆ†ๆžๆ•ฐๆฎๅนถ็”ŸๆˆๆŠฅๅ‘Š"
      }
    ],
    authentication: {
      schemes: ["bearer"]
    },
    defaultInputModes: ["text", "file"],
    defaultOutputModes: ["text", "file"]
  });
});

// ๅ‘้€ไปปๅŠก
app.post('/a2a', async (req, res) => {
  const { method, params, id } = req.body;
  
  switch (method) {
    case 'tasks/send': {
      const task = await handleTaskSend(params);
      res.json({
        jsonrpc: "2.0",
        id,
        result: task
      });
      break;
    }
    
    case 'tasks/get': {
      const task = tasks.get(params.id);
      res.json({
        jsonrpc: "2.0",
        id,
        result: task || null
      });
      break;
    }
    
    case 'tasks/cancel': {
      const task = await handleTaskCancel(params.id);
      res.json({
        jsonrpc: "2.0",
        id,
        result: task
      });
      break;
    }
  }
});

// SSE ่ฎข้˜…็ซฏ็‚น
app.get('/a2a/tasks/:taskId/subscribe', (req, res) => {
  const { taskId } = req.params;
  
  // ่ฎพ็ฝฎ SSE headers
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  // ๆทปๅŠ ่ฎข้˜…่€…
  if (!subscribers.has(taskId)) {
    subscribers.set(taskId, new Set());
  }
  subscribers.get(taskId)!.add(res);
  
  // ๆธ…็†
  req.on('close', () => {
    subscribers.get(taskId)?.delete(res);
  });
});

// ๅค„็†ไปปๅŠก
async function handleTaskSend(params: any): Promise<Task> {
  const taskId = params.id || uuidv4();
  
  const task: Task = {
    id: taskId,
    status: {
      state: "submitted",
      timestamp: new Date().toISOString()
    },
    history: [params.message]
  };
  
  tasks.set(taskId, task);
  
  // ๅผ‚ๆญฅๅค„็†ไปปๅŠก
  processTaskAsync(taskId, params.message);
  
  return task;
}

async function processTaskAsync(taskId: string, message: Message) {
  const task = tasks.get(taskId)!;
  
  // ๆ›ดๆ–ฐ็Šถๆ€ไธบๅค„็†ไธญ
  updateTaskStatus(taskId, "working", "ๆญฃๅœจๅˆ†ๆžๆ•ฐๆฎ...");
  
  try {
    // ๆจกๆ‹Ÿๅค„็†
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    // ๅ‘้€้ƒจๅˆ†็ป“ๆžœ
    emitArtifact(taskId, {
      index: 0,
      parts: [{ type: "text", text: "# ๅˆ†ๆžๆŠฅๅ‘Š\n\nๆ•ฐๆฎๅˆ†ๆžๅฎŒๆˆใ€‚" }],
      lastChunk: true
    });
    
    // ๅฎŒๆˆ
    updateTaskStatus(taskId, "completed", "ๅˆ†ๆžๅฎŒๆˆ");
    
  } catch (error) {
    updateTaskStatus(taskId, "failed", error.message);
  }
}

function updateTaskStatus(taskId: string, state: TaskState, message: string) {
  const task = tasks.get(taskId);
  if (!task) return;
  
  task.status = {
    state,
    message,
    timestamp: new Date().toISOString()
  };
  
  // ้€š็Ÿฅ่ฎข้˜…่€…
  const subs = subscribers.get(taskId);
  if (subs) {
    const event = `event: status\ndata: ${JSON.stringify(task.status)}\n\n`;
    subs.forEach(res => res.write(event));
  }
}

function emitArtifact(taskId: string, artifact: Artifact) {
  const task = tasks.get(taskId);
  if (!task) return;
  
  task.artifacts = task.artifacts || [];
  task.artifacts.push(artifact);
  
  const subs = subscribers.get(taskId);
  if (subs) {
    const event = `event: artifact\ndata: ${JSON.stringify(artifact)}\n\n`;
    subs.forEach(res => res.write(event));
  }
}

app.listen(3000, () => {
  console.log('A2A Agent running on port 3000');
});

Client ๅฎž็Žฐ โ€‹

typescript
class A2AClient {
  private baseUrl: string;
  private authToken: string;
  
  constructor(baseUrl: string, authToken: string) {
    this.baseUrl = baseUrl;
    this.authToken = authToken;
  }
  
  // ่Žทๅ– Agent Card
  async getAgentCard(): Promise<AgentCard> {
    const response = await fetch(`${this.baseUrl}/.well-known/agent.json`);
    return response.json();
  }
  
  // ๅ‘้€ไปปๅŠก
  async sendTask(message: Message, taskId?: string): Promise<Task> {
    const response = await fetch(`${this.baseUrl}/a2a`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: crypto.randomUUID(),
        method: "tasks/send",
        params: {
          id: taskId || crypto.randomUUID(),
          message
        }
      })
    });
    
    const data = await response.json();
    return data.result;
  }
  
  // ่ฎข้˜…ไปปๅŠกๆ›ดๆ–ฐ
  subscribeToTask(
    taskId: string,
    callbacks: {
      onStatus?: (status: TaskStatus) => void;
      onArtifact?: (artifact: Artifact) => void;
      onError?: (error: Error) => void;
    }
  ): () => void {
    const eventSource = new EventSource(
      `${this.baseUrl}/a2a/tasks/${taskId}/subscribe`,
      {
        // ่‡ชๅฎšไน‰ headers ้œ€่ฆไฝฟ็”จ fetch ๆ›ฟไปฃ
      }
    );
    
    eventSource.addEventListener('status', (e) => {
      const status = JSON.parse(e.data);
      callbacks.onStatus?.(status);
    });
    
    eventSource.addEventListener('artifact', (e) => {
      const artifact = JSON.parse(e.data);
      callbacks.onArtifact?.(artifact);
    });
    
    eventSource.onerror = (e) => {
      callbacks.onError?.(new Error('SSE connection error'));
    };
    
    // ่ฟ”ๅ›žๅ–ๆถˆๅ‡ฝๆ•ฐ
    return () => eventSource.close();
  }
  
  // ่Žทๅ–ไปปๅŠก็Šถๆ€
  async getTask(taskId: string): Promise<Task | null> {
    const response = await fetch(`${this.baseUrl}/a2a`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: crypto.randomUUID(),
        method: "tasks/get",
        params: { id: taskId }
      })
    });
    
    const data = await response.json();
    return data.result;
  }
  
  // ๅ–ๆถˆไปปๅŠก
  async cancelTask(taskId: string): Promise<Task> {
    const response = await fetch(`${this.baseUrl}/a2a`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: crypto.randomUUID(),
        method: "tasks/cancel",
        params: { id: taskId }
      })
    });
    
    const data = await response.json();
    return data.result;
  }
}

// ไฝฟ็”จ็คบไพ‹
async function main() {
  const client = new A2AClient('https://api.example.com', 'your-token');
  
  // ่Žทๅ– Agent ่ƒฝๅŠ›
  const agentCard = await client.getAgentCard();
  console.log('Agent skills:', agentCard.skills);
  
  // ๅ‘้€ไปปๅŠก
  const task = await client.sendTask({
    role: 'user',
    parts: [
      { type: 'text', text: 'ๅˆ†ๆž่ฟ™ไธชๆ•ฐๆฎ้›†' }
    ]
  });
  
  console.log('Task created:', task.id);
  
  // ่ฎข้˜…ๆ›ดๆ–ฐ
  const unsubscribe = client.subscribeToTask(task.id, {
    onStatus: (status) => {
      console.log('Status:', status.state, status.message);
    },
    onArtifact: (artifact) => {
      console.log('Artifact:', artifact.parts);
    }
  });
  
  // ็จๅŽๅ–ๆถˆ่ฎข้˜…
  // unsubscribe();
}

3.6 ๅคš Agent ๅไฝœๆจกๅผ โ€‹

ไปปๅŠกๅง”ๆดพๆจกๅผ โ€‹

typescript
// ๅ่ฐƒ Agent ๅฐ†ไปปๅŠกๅง”ๆดพ็ป™ไธ“ไธš Agent
class OrchestratorAgent {
  private agents: Map<string, A2AClient> = new Map();
  
  constructor(agentConfigs: AgentConfig[]) {
    for (const config of agentConfigs) {
      this.agents.set(config.skillType, new A2AClient(config.url, config.token));
    }
  }
  
  async processRequest(request: string): Promise<any> {
    // 1. ๅˆ†ๆž่ฏทๆฑ‚๏ผŒ็กฎๅฎš้œ€่ฆๅ“ชไบ› Agent
    const plan = await this.createPlan(request);
    
    // 2. ๆŒ‰่ฎกๅˆ’ๆ‰ง่กŒ
    const results = [];
    
    for (const step of plan.steps) {
      const agent = this.agents.get(step.agentType);
      if (!agent) {
        throw new Error(`No agent found for: ${step.agentType}`);
      }
      
      // ๅง”ๆดพไปปๅŠก
      const task = await agent.sendTask({
        role: 'user',
        parts: [
          { type: 'text', text: step.instruction },
          // ๅŒ…ๅซๅ‰ๅบๆญฅ้ชค็š„็ป“ๆžœ
          ...this.formatPreviousResults(results)
        ]
      });
      
      // ็ญ‰ๅพ…ๅฎŒๆˆ
      const result = await this.waitForCompletion(agent, task.id);
      results.push({ step: step.name, result });
    }
    
    // 3. ๆฑ‡ๆ€ป็ป“ๆžœ
    return this.summarizeResults(results);
  }
  
  private async waitForCompletion(client: A2AClient, taskId: string): Promise<any> {
    return new Promise((resolve, reject) => {
      const unsubscribe = client.subscribeToTask(taskId, {
        onStatus: (status) => {
          if (status.state === 'completed') {
            unsubscribe();
            client.getTask(taskId).then(task => resolve(task?.artifacts));
          } else if (status.state === 'failed') {
            unsubscribe();
            reject(new Error(status.message));
          }
        }
      });
    });
  }
}

ๅไฝœๅทฅไฝœๆต็คบไพ‹ โ€‹

typescript
// ๅฎž็Žฐไธ€ไธชๅคš Agent ๆ•ฐๆฎๅค„็†ๅทฅไฝœๆต
async function dataProcessingWorkflow(dataUrl: string) {
  const orchestrator = new OrchestratorAgent([
    { skillType: 'data-cleaning', url: 'https://cleaner.example.com', token: '...' },
    { skillType: 'analysis', url: 'https://analyst.example.com', token: '...' },
    { skillType: 'visualization', url: 'https://viz.example.com', token: '...' },
    { skillType: 'report-generation', url: 'https://reporter.example.com', token: '...' }
  ]);
  
  const result = await orchestrator.processRequest(`
    ๅค„็†ไปฅไธ‹ๆ•ฐๆฎ๏ผš${dataUrl}
    
    1. ๆธ…ๆด—ๆ•ฐๆฎ๏ผŒๅค„็†็ผบๅคฑๅ€ผๅ’Œๅผ‚ๅธธๅ€ผ
    2. ่ฟ›่กŒ็ปŸ่ฎกๅˆ†ๆž๏ผŒๆ‰พๅ‡บๅ…ณ้”ฎ่ถ‹ๅŠฟ
    3. ็”Ÿๆˆๅฏ่ง†ๅŒ–ๅ›พ่กจ
    4. ๆ’ฐๅ†™ๅˆ†ๆžๆŠฅๅ‘Š
  `);
  
  return result;
}

4. ๅ่ฎฎๅฏนๆฏ”ไธŽ้€‰ๆ‹ฉ โ€‹

4.1 ๅŠŸ่ƒฝๅฏนๆฏ” โ€‹

ๅŠŸ่ƒฝMCPA2A
ๅทฅๅ…ท่ฐƒ็”จโœ… ๆ ธๅฟƒๅŠŸ่ƒฝโŒ ไธ็›ดๆŽฅๆ”ฏๆŒ
่ต„ๆบ่ฎฟ้—ฎโœ… ResourcesโŒ ้€š่ฟ‡ Message ้—ดๆŽฅ
Agent ๅ‘็ŽฐโŒ ๆ— โœ… Agent Card
ไปปๅŠก็ฎก็†โŒ ๆ— โœ… Task ็”Ÿๅ‘ฝๅ‘จๆœŸ
ๆตๅผๅ“ๅบ”โŒ ๆœ‰้™ๆ”ฏๆŒโœ… SSE ๅŽŸ็”Ÿๆ”ฏๆŒ
ๅคšๆจกๆ€โœ… ๆ”ฏๆŒโœ… ๆ”ฏๆŒ
้•ฟไปปๅŠกโŒ ่ฎพ่ฎกไธบๅŒๆญฅโœ… ๅผ‚ๆญฅใ€ๆŽจ้€้€š็Ÿฅ
่บซไปฝ่ฎค่ฏๅŸบ็ก€โœ… OAuth 2.0, W3C DID

4.2 ้€‰ๆ‹ฉๆŒ‡ๅ— โ€‹

้€‰ๆ‹ฉ MCP ๅฝ“:
โ”œโ”€โ”€ ้œ€่ฆ่ฎฉ AI ่ฎฟ้—ฎๅทฅๅ…ทๅ’Œๆ•ฐๆฎๆบ
โ”œโ”€โ”€ ๆž„ๅปบๅ• Agent ๅบ”็”จ
โ”œโ”€โ”€ ้œ€่ฆ่ฏปๅ–ๆ–‡ไปถใ€่ฐƒ็”จ API
โ””โ”€โ”€ ้œ€่ฆๅฟซ้€Ÿ้›†ๆˆๅทฒๆœ‰ๆœๅŠก

้€‰ๆ‹ฉ A2A ๅฝ“:
โ”œโ”€โ”€ ้œ€่ฆๅคšไธช Agent ๅไฝœ
โ”œโ”€โ”€ Agent ๆฅ่‡ชไธๅŒไพ›ๅบ”ๅ•†/ๆก†ๆžถ
โ”œโ”€โ”€ ้œ€่ฆๅค„็†้•ฟๆ—ถ้—ด่ฟ่กŒ็š„ไปปๅŠก
โ””โ”€โ”€ ้œ€่ฆไผไธš็บงๅฎ‰ๅ…จๅ’Œๅฎก่ฎก

ไธค่€…็ป“ๅˆๅฝ“:
โ”œโ”€โ”€ ๆž„ๅปบๅคๆ‚็š„ๅคš Agent ็ณป็ปŸ
โ”œโ”€โ”€ Agent ๆ—ข้œ€่ฆๅทฅๅ…ทไนŸ้œ€่ฆๅไฝœ
โ””โ”€โ”€ ไผไธš็บง AI ๅทฅไฝœๆต

4.3 ้›†ๆˆๆžถๆž„ โ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     ไผไธš AI ็ณป็ปŸๆžถๆž„็คบไพ‹                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                         API Gateway                              โ”‚    โ”‚
โ”‚  โ”‚                    (่ฎค่ฏใ€้™ๆตใ€ๆ—ฅๅฟ—)                              โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                              โ”‚                                           โ”‚
โ”‚                              โ–ผ                                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                    Orchestrator Agent                            โ”‚    โ”‚
โ”‚  โ”‚              (ไปปๅŠก่ง„ๅˆ’ใ€Agent ่ฐƒๅบฆใ€็ป“ๆžœๆฑ‡ๆ€ป)                       โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                              โ”‚                                           โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”‚
โ”‚              โ”‚ A2A           โ”‚ A2A           โ”‚ A2A                       โ”‚
โ”‚              โ–ผ               โ–ผ               โ–ผ                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚  Specialist      โ”‚ โ”‚  Specialist      โ”‚ โ”‚  Specialist      โ”‚        โ”‚
โ”‚  โ”‚  Agent A         โ”‚ โ”‚  Agent B         โ”‚ โ”‚  Agent C         โ”‚        โ”‚
โ”‚  โ”‚  (ๆ•ฐๆฎๅˆ†ๆž)       โ”‚ โ”‚  (ๆ–‡ๆกฃ็”Ÿๆˆ)       โ”‚ โ”‚  (้‚ฎไปถๅ‘้€)       โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚           โ”‚ MCP                 โ”‚ MCP                โ”‚ MCP              โ”‚
โ”‚           โ–ผ                     โ–ผ                    โ–ผ                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚  MCP Servers     โ”‚ โ”‚  MCP Servers     โ”‚ โ”‚  MCP Servers     โ”‚        โ”‚
โ”‚  โ”‚  - Database      โ”‚ โ”‚  - Google Docs   โ”‚ โ”‚  - SMTP          โ”‚        โ”‚
โ”‚  โ”‚  - Analytics API โ”‚ โ”‚  - Templates     โ”‚ โ”‚  - Calendar      โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

5. ๅฎ‰ๅ…จ่€ƒ้‡ โ€‹

5.1 MCP ๅฎ‰ๅ…จ โ€‹

typescript
// 1. Server ่ƒฝๅŠ›้™ๅˆถ
const server = new Server({
  name: "secure-server",
  version: "1.0.0"
}, {
  capabilities: {
    // ๅชๅผ€ๆ”พๅฟ…่ฆ็š„่ƒฝๅŠ›
    tools: {},
    // resources: {},  // ไธๆšด้œฒ่ต„ๆบ
    // prompts: {},    // ไธๆšด้œฒๆ็คบ
  }
});

// 2. ่ทฏๅพ„็™ฝๅๅ•
const ALLOWED_PATHS = [
  '/safe/directory',
  '/another/safe/path'
];

function isPathAllowed(path: string): boolean {
  const resolved = path.resolve(path);
  return ALLOWED_PATHS.some(allowed => 
    resolved.startsWith(path.resolve(allowed))
  );
}

// 3. ๆ•ๆ„Ÿๆ•ฐๆฎ่ฟ‡ๆปค
function sanitizeOutput(data: any): any {
  const sensitiveKeys = ['password', 'token', 'secret', 'apiKey'];
  
  if (typeof data === 'object') {
    for (const key of Object.keys(data)) {
      if (sensitiveKeys.some(s => key.toLowerCase().includes(s))) {
        data[key] = '[REDACTED]';
      } else if (typeof data[key] === 'object') {
        data[key] = sanitizeOutput(data[key]);
      }
    }
  }
  
  return data;
}

5.2 A2A ๅฎ‰ๅ…จ โ€‹

typescript
// 1. OAuth 2.0 ่ฎค่ฏ
app.use('/a2a', async (req, res, next) => {
  const authHeader = req.headers.authorization;
  
  if (!authHeader?.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Missing authentication' });
  }
  
  const token = authHeader.slice(7);
  
  try {
    const payload = await verifyToken(token);
    req.user = payload;
    next();
  } catch {
    return res.status(401).json({ error: 'Invalid token' });
  }
});

// 2. ไปปๅŠกๆƒ้™ๆฃ€ๆŸฅ
function canAccessTask(user: User, taskId: string): boolean {
  const task = tasks.get(taskId);
  
  // ๆฃ€ๆŸฅ็”จๆˆทๆ˜ฏๅฆๆœ‰ๆƒ้™่ฎฟ้—ฎๆญคไปปๅŠก
  return task?.metadata?.ownerId === user.id ||
         user.roles.includes('admin');
}

// 3. ่ฏทๆฑ‚้ชŒ่ฏ
import { z } from 'zod';

const TaskSendSchema = z.object({
  id: z.string().uuid().optional(),
  message: z.object({
    role: z.enum(['user', 'agent']),
    parts: z.array(z.union([
      z.object({ type: z.literal('text'), text: z.string().max(100000) }),
      z.object({ type: z.literal('file'), file: z.object({
        name: z.string(),
        mimeType: z.string(),
        uri: z.string().url().optional(),
        bytes: z.string().optional()
      })})
    ]))
  })
});

// 4. ๅฎก่ฎกๆ—ฅๅฟ—
function auditLog(action: string, details: any) {
  const entry = {
    timestamp: new Date().toISOString(),
    action,
    userId: details.userId,
    taskId: details.taskId,
    ip: details.ip,
    // ไธ่ฎฐๅฝ•ๆ•ๆ„Ÿๅ†…ๅฎน
  };
  
  auditLogger.info(entry);
}

6. ็”Ÿๆ€็ณป็ปŸ โ€‹

6.1 MCP ็”Ÿๆ€ โ€‹

ๅฎ˜ๆ–น Servers๏ผš

ServerๅŠŸ่ƒฝๅฎ‰่ฃ…
@modelcontextprotocol/server-filesystemๆ–‡ไปถ็ณป็ปŸ่ฎฟ้—ฎnpx -y @modelcontextprotocol/server-filesystem /path
@modelcontextprotocol/server-githubGitHub APInpx -y @modelcontextprotocol/server-github
@modelcontextprotocol/server-postgresPostgreSQL ๆ•ฐๆฎๅบ“npx -y @modelcontextprotocol/server-postgres
@modelcontextprotocol/server-sqliteSQLite ๆ•ฐๆฎๅบ“npx -y @modelcontextprotocol/server-sqlite
@modelcontextprotocol/server-puppeteerๆต่งˆๅ™จ่‡ชๅŠจๅŒ–npx -y @modelcontextprotocol/server-puppeteer

็คพๅŒบ Servers๏ผš

  • Notion, Slack, Discord ้›†ๆˆ
  • AWS, GCP, Azure ไบ‘ๆœๅŠก
  • Jira, Linear ้กน็›ฎ็ฎก็†
  • Figma ่ฎพ่ฎกๅทฅๅ…ท

6.2 A2A ็”Ÿๆ€ โ€‹

ๆ”ฏๆŒ็š„ๆก†ๆžถ๏ผš

  • LangChain / LangGraph
  • CrewAI
  • Google ADK (Agent Development Kit)
  • Microsoft AutoGen

ไผไธšๅˆไฝœไผ™ไผด๏ผš

  • Salesforce, SAP, ServiceNow
  • Atlassian, Box, MongoDB
  • Accenture, Deloitte, PwC

7. ๅ…ณ้”ฎ่ฆ็‚น โ€‹

MCP ่ฆ็‚น โ€‹

  1. ไธ‰ๅคง่ƒฝๅŠ›: Resources๏ผˆ่ต„ๆบ๏ผ‰ใ€Tools๏ผˆๅทฅๅ…ท๏ผ‰ใ€Prompts๏ผˆๆ็คบ๏ผ‰
  2. Client-Server ๆžถๆž„: Host ๆ‰˜็ฎกๅบ”็”จ๏ผŒClient ๅค„็†ๅ่ฎฎ๏ผŒServer ๆไพ›่ƒฝๅŠ›
  3. JSON-RPC 2.0: ๆ ‡ๅ‡†ๅŒ–็š„่ฏทๆฑ‚-ๅ“ๅบ”ๆ ผๅผ
  4. ๅฎ‰ๅ…จ็ฌฌไธ€: ่ทฏๅพ„้ชŒ่ฏใ€ๆƒ้™ๆŽงๅˆถใ€ๅฎก่ฎกๆ—ฅๅฟ—

A2A ่ฆ็‚น โ€‹

  1. Agent Card: Agent ็š„่ƒฝๅŠ›ๅ็‰‡๏ผŒๆ”ฏๆŒๅ‘็ŽฐไธŽๅฏนๆŽฅ
  2. Task ็”Ÿๅ‘ฝๅ‘จๆœŸ: submitted โ†’ working โ†’ completed/failed
  3. SSE ๆตๅผๆ›ดๆ–ฐ: ๅฎžๆ—ถ็Šถๆ€ๆŽจ้€ๅ’Œ้ƒจๅˆ†็ป“ๆžœ
  4. ไผไธš็บงๅฎ‰ๅ…จ: OAuth 2.0ใ€W3C DID ่บซไปฝ่ฎค่ฏ

้€‰ๆ‹ฉๅปบ่ฎฎ โ€‹

ๅœบๆ™ฏๆŽจ่ๅ่ฎฎ
AI ่ฎฟ้—ฎๆ–‡ไปถ/ๆ•ฐๆฎๅบ“MCP
AI ่ฐƒ็”จๅค–้ƒจ APIMCP
ๅคš Agent ๅไฝœA2A
่ทจ็ป„็ป‡ Agent ไบ’ๆ“ไฝœA2A
ๅฎŒๆ•ดไผไธš AI ็ณป็ปŸMCP + A2A

8. ๅ‚่€ƒ่ต„ๆบ โ€‹

ๅฎ˜ๆ–นๆ–‡ๆกฃ โ€‹

SDK โ€‹

ๆทฑๅบฆๆ–‡็ซ  โ€‹

ๅ‰็ซฏ้ข่ฏ•็Ÿฅ่ฏ†ๅบ“