{"id":2532,"date":"2025-07-30T00:00:45","date_gmt":"2025-07-29T15:00:45","guid":{"rendered":"https:\/\/skanto.co.kr\/?p=2532"},"modified":"2025-07-30T18:43:54","modified_gmt":"2025-07-30T09:43:54","slug":"mcpmodel-context-protocol-deep-dive","status":"publish","type":"post","link":"https:\/\/skanto.co.kr\/?p=2532","title":{"rendered":"MCP(Model Context Protocol) Deep Dive"},"content":{"rendered":"\n<p>\uc694\uc998 AI \uac1c\ubc1c\uc5d0 \ub300\ud574 \uc598\uae30\ud558\uc790\uba74 MCP\ub97c \ube7c\ub193\uace0 \uc598\uae30\ud560 \uc218 \uc5c6\ub2e4. LLM\uc774 \ub098\uc624\uba74\uc11c AI\uac00 \ubaa8\ub4e0 \uac83\uc744 \ubc14\uafd4 \ubc84\ub9b4 \uac83\uc774\ub77c\ub294 \uc6b0\ub824\uac00 \uc788\uc5c8\uc9c0\ub9cc \ub9c9\uc0c1 Chatbot\uc218\uc900\uc758 \uc815\ubcf4\ub97c \uc5bb\ub294 \uac83 \ub9d0\uace0\ub294 \ud65c\uc6a9 \uac00\uce58\uac00 \uadf8\ub9ac \ud06c\uc9c0 \uc54a\uc558\ub2e4. \ud558\uc9c0\ub9cc Antropic\uc5d0\uc11c MCP\uaddc\uaca9(2024.11)\uc744 \ub0b4 \ub193\uc73c\uba74\uc11c \uae30\ub958\ub294 \ud06c\uac8c \ubc14\ub00c\uc5c8\ub2e4. LLM\uc774 \uc778\uacf5\uc9c0\ub2a5 \uc989, \ub450\ub1cc \uc5ed\ud560\uc744 \ub2f4\ub2f9\ud588\ub2e4\uba74 MCP\ub294 \uc774 \ub450\ub1cc\uc5d0 \ud314\uacfc \ub2e4\ub9ac\ub97c \ub2ec\uc544\uc8fc\uc5c8\uae30 \ub54c\ubb38\uc774\ub2e4. \uacb0\uad6d \uc0ac\ub78c\uc774 AI\uc5d0\uac8c \ub9d0\uc744 \uac74\ub124\uba74 AI\ub294 \uadf8 \ub9d0\ub97c \uc774\ud574\ud558\uace0 \uc2e4\uc81c \ub3c4\uc6c0\uc774 \ub418\ub294 \ud589\ub3d9\uc744 \ud560 \uc218 \uc788\uac8c \ub41c \uc148\uc774\ub2e4.<\/p>\n\n\n\n<p>\uc774 \uae00\uc5d0\uc11c\ub294 MCP\uac00 \ubb34\uc5c7\uc778\uc9c0 \uaddc\uaca9(Specification)\uc704\uc8fc\ub85c \uac04\ub7b5\ud558\uac8c \uc124\uba85\ud558\uace0 <a href=\"https:\/\/www.npmjs.com\/package\/@langchain\/mcp-adapters\">Langchain MCP Adapter<\/a>\uc640 MCP SDK\ub97c \ud65c\uc6a9\ud558\uc5ec \uac04\ub2e8\ud55c \uc2dc\ub098\ub9ac\uc624\uac00 \uc2e4\uc81c \uad6c\ud604\ub418\uc5b4 \ub3d9\uc791\ud558\ub294 \ubaa8\uc2b5\uae4c\uc9c0 \ub530\ub77c\uac00 \ubcf4\uace0\uc790 \ud55c\ub2e4. \ud655\uc5b8\ucee8\ub370, \uc774 \uae00\uc744 \ub05d\uae4c\uc9c0 \ub530\ub77c \uac04\ub2e4\uba74 MCP\uac00 \uc5b4\ub5a4 \ub9e4\ucee4\ub2c8\uc998\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \uac1c\ub150\uc815\ub9ac \ubfd0\ub9cc \uc544\ub2c8\ub77c MCP Tool\uc744 \ud65c\uc6a9\ud558\ub294 AI \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c\uc5d0\ub3c4 \uc790\uc2e0\uac10\uc744 \ubd88\uc5b4 \ub123\uc5b4 \uc904 \uac83\uc73c\ub85c \uc0dd\uac01\ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Model Context Protocol<\/h2>\n\n\n\n<p><a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\">Model Context Protocol \uc2a4\ud399<\/a>\uc758 \uc815\uc758\ub97c \ube4c\ub9ac\uc790\uba74 \uac1c\ubc29\ud615(Open) \ud504\ub85c\ud1a0\ucf5c\ub85c\uc11c LLM \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \uadf8 \uc678\ubd80\uc758 \ub370\uc774\ud130 \uadf8\ub9ac\uace0 \ud234(tool) \uc0ac\uc774\ub97c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ud1b5\ud569\uc2dc\ucf1c\uc8fc\ub294 \uaddc\uaca9\uc774\ub77c \ud560 \uc218 \uc788\ub2e4. \uc774 \uae00\uc744 \uc791\uc131\ud558\ub294 \uc2dc\uc810\uc758 \ucd5c\uc2e0 \ubc84\uc804\uc740 2025-06-18\uc774\uba70, \uc544\uc9c1\uc740 \uc131\uc219 \ub2e8\uacc4\ub77c \uc548\uc815\ud654 \ub420 \ub54c\uae4c\uc9c0\ub294 \uc7a6\uc740 \ubcc0\uacbd \ubc0f \uac1c\uc120\uc0ac\ud56d \ubc18\uc601\uc774 \uc608\uc0c1\ub41c\ub2e4.<\/p>\n\n\n\n<p>\ud504\ub85c\ud1a0\ucf5c\uc740 \ub0b4\ubd80\uc801\uc73c\ub85c <a href=\"https:\/\/www.jsonrpc.org\/specification\">JSON-RPC 2.0 \uaddc\uaca9<\/a>\uc744 \ub530\ub974\uba70 \uc544\ub798 \uad6c\uc131\uc694\uc18c\ub4e4 \uac04\uc758 \ub370\uc774\ud130 \ud1b5\uc2e0\uc5d0 \uc801\uc6a9\ub41c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Hosts<\/strong>: LLM \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158(or Agent)\uc73c\ub85c Connection\uc744 \ub9fa\ub294 \uc8fc\uccb4\uc774\ub2e4.<\/li>\n\n\n\n<li><strong>Clients<\/strong>: Host\uc5b4\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\ubd80\uc758 Connector\uc5d0 \ud574\ub2f9\ud55c\ub2e4.<\/li>\n\n\n\n<li><strong>Servers<\/strong>: Context\uc640 \ub2a5\ub825\uce58(<em>tool \uc744 \ud3ec\ud568\ud55c capability<\/em>)\ub97c \uc81c\uacf5\ud55c\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p>MCP\ub294 Client-Host-Server \uc544\ud0a4\ud14d\ucc98\ub97c \ub530\ub974\uba70 Host \ud558\ub098\uac00 \ub2e4\uc218\uc758 Client\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. \uc774\ub4e4 \uad6c\uc131\uc694\uc18c\ub97c \uadf8\ub9bc\uc73c\ub85c \ud45c\ud604\ud558\uba74 \uc544\ub798\uc640 \uac19\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"713\" src=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54-1024x713.png\" alt=\"\" class=\"wp-image-2534\" srcset=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54-1024x713.png 1024w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54-300x209.png 300w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54-768x534.png 768w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54-388x270.png 388w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/\uc2a4\ud06c\ub9b0\uc0f7-2025-07-27-\uc624\ud6c4-11.11.54.png 1486w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\uc8fc\uc694 \uad6c\uc131\uc694\uc18c(Components)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Host<\/h3>\n\n\n\n<p>\uc11c\ube14\ub9bf(Servlet) \ucee8\ud14c\uc774\ub108 \ucc98\ub7fc \ucee8\ud14c\uc774\ub108 \uc5ed\ud560\uacfc \uc870\uc815\uc790(Coordinator) \uc5ed\ud560\uc744 \ub2f4\ub2f9\ud55c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ub2e4\uc218\uc758 Client \uc778\uc2a4\ud134\uc2a4 \uc0dd\uc131 \ubc0f \uad00\ub9ac<\/li>\n\n\n\n<li>Client\uc758 Connection permission\uacfc Lifecycle \uc81c\uc5b4<\/li>\n\n\n\n<li>\ubcf4\uc548\uc815\ucc45(Security Policy)\uc5d0 \ubd80\ud569\ud558\ub294 \uc694\uad6c\uc0ac\ud56d \uac15\uc81c\ud654<\/li>\n\n\n\n<li>\uc0ac\uc6a9\uc790 Authorization \ucc98\ub9ac<\/li>\n\n\n\n<li>AI\/LLM \ud1b5\ud569\uacfc <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/client\/sampling\">Sampling<\/a>\uc744 \uc870\uc815<\/li>\n\n\n\n<li>Client \uac04\uc758 Context aggregation \uad00\ub9ac<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Clients<\/h3>\n\n\n\n<p>Host\uc5d0 \uc758\ud574 \uc0dd\uc131\ub418\uba70 \uac01\uc790 \ub3c5\ub9bd\ub41c(isolated) \ud615\ud0dc\ub85c \uc11c\ubc84\uc640 \uc5f0\uacb0(Connection)\uc744 \uc720\uc9c0\ud55c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\uac01 \uc11c\ubc84\ubcc4 Stateful \uc138\uc158 \ud615\uc131<\/li>\n\n\n\n<li>Protocol Negotiation\uacfc Capability \uad50\ud658(exchange) \ucc98\ub9ac(handshaking)<\/li>\n\n\n\n<li>\uc591\ubc29\ud5a5 \ud504\ub85c\ud1a0\ucf5c \uba54\uc2dc\uc9c0 \ub77c\uc6b0\ud305<\/li>\n\n\n\n<li>Subscription\uacfc Notification \uad00\ub9ac<\/li>\n\n\n\n<li>\uc11c\ubc84\ub4e4 \uac04\uc758 Security Boundary \uc720\uc9c0<\/li>\n<\/ul>\n\n\n\n<p>Host \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158\uc740 \ub2e4\uc218\uc758 Client\ub97c \uc0dd\uc131 \uad00\ub9ac\ud558\uba70 \uc774\ub54c \uac01 Client\uc640 \ud2b9\uc815 \uc11c\ubc84\uac04\uc758 \uad00\uacc4\ub294 1:1 \uc774\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Servers<\/h3>\n\n\n\n<p>\ud2b9\ud654\ub41c Context\uc640 \ub2a5\ub825\uce58(Capabilities)\uc744 \uc81c\uacf5\ud55c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ub9ac\uc18c\uc2a4(Resources), \ud234(Tools), \ud504\ub86c\ud504\ud2b8(Prompts) \uacf5\uac1c<\/li>\n\n\n\n<li>\ud2b9\uc815 \uc5c5\ubb34 \ub610\ub294 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4 \ub3c5\ub9bd\uc801\uc73c\ub85c \ub3d9\uc791<\/li>\n\n\n\n<li>\ud074\ub77c\uc774\uc5b8\ud2b8\uc758 interface\ub97c \ud1b5\ud574 Sampling \uc694\uccad<\/li>\n\n\n\n<li>Security \uc81c\uc57d\uc0ac\ud56d \uc900\uc218 \ud544\uc218<\/li>\n\n\n\n<li>\ub85c\uceec process\ub85c \ub3d9\uc791 \ub610\ub294 \uc6d0\uaca9 \uc11c\ube44\uc2a4 \ud615\ud0dc\ub85c \uac00\ub2a5<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Capability Negotiation<\/h2>\n\n\n\n<p>MCP\ub294 \ub2a5\ub825\uce58\uc5d0 \uae30\ubc18(Capability-based)\ud55c \ud611\uc758(Negotiation) \uc2dc\uc2a4\ud15c\uc744 \ud65c\uc6a9\ud558\uba70 \ud611\uc758 \uacfc\uc815\uc5d0\uc11c Client\uc640 Server\ub294 \uac01\uc790 \ud65c\uc6a9 \uac00\ub2a5\ud55c \uae30\ub2a5\uc744 \uba85\uc2dc\uc801\uc73c\ub85c \uc120\uc5b8\ud55c\ub2e4. Capability\ub294 \uc138\uc158\uc774 \uc720\uc9c0\ub418\ub294 \ub3d9\uc548 \ud504\ub85c\ud1a0\ucf5c \uc0c1\uc758 \uc5b4\ub5a4 \uae30\ub2a5\uacfc primitive\ub97c \uc0ac\uc6a9 \uac00\ub2a5\ud55c\uc9c0\ub97c \uacb0\uc815\ud55c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Server\ub294 \uad6c\ub3c5 \uac00\ub2a5\ud55c <strong>\ub9ac\uc18c\uc2a4<\/strong>(Resource Subscription), \uc9c0\uc6d0\ud558\ub294 <strong>\ud234<\/strong>(Tool Support), <strong>\ud504\ub86c\ud504\ud2b8<\/strong> \ud15c\ud50c\ub9bf(Prompt Template)\uacfc \uac19\uc740 \uac83\uc744 \uc120\uc5b8\ud55c\ub2e4.<\/li>\n\n\n\n<li>Client\ub294 Sampling \uc9c0\uc6d0 \uc5ec\ubd80\uc640 Notification \ucc98\ub9ac \uc5ec\ubd80 \uac19\uc740 \uae30\ub2a5\uc744 \uc120\uc5b8\ud55c\ub2e4.<\/li>\n\n\n\n<li>Client\uc640 Server\ub294 \uc138\uc158\uc774 \uc720\uc9c0\ub418\ub294 \ub3d9\uc548 \uac01\uc790 \uc120\uc5b8\ud55c \uae30\ub2a5\uc744 \uc11c\ub85c \uc2e0\ub8b0\ud574\uc57c \ud55c\ub2e4.<\/li>\n\n\n\n<li>Protocol \ud655\uc7a5(extension)\uc744 \ud1b5\ud574 \ucd94\uac00\uc801\uc778 \uae30\ub2a5\uc744 negotiation\ud560 \uc218 \uc788\ub2e4.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"763\" height=\"1024\" src=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-763x1024.png\" alt=\"\" class=\"wp-image-2538\" srcset=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-763x1024.png 763w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-224x300.png 224w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-768x1030.png 768w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-201x270.png 201w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image.png 1054w\" sizes=\"auto, (max-width: 763px) 100vw, 763px\" \/><\/figure>\n\n\n\n<p>\uc774\uc640 \uac19\uc740 Capability negotiation\uc740 \ud504\ub85c\ud1a0\ucf5c\uc758 \ud655\uc7a5\uc131\uc744 \uc720\uc9c0\ud558\uba74\uc11c Client\uc640 Server\uac00 \uac01\uc790 \uc9c0\uc6d0\ud558\ub294 \uae30\ub2a5\uc744 \uba85\ud655\ud558\uac8c \uc774\ud574 \ud558\ub3c4\ub85d \ub3d5\ub294\ub2e4. \uc704 \uc2dc\ud000\uc2a4\ub2e4\uc774\uc5b4\uadf8\ub7a8\uc11c \ub098\uc624\ub294 <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/server\/tools\">Tool<\/a>, <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/server\/resources\">Resource<\/a>, <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/client\/sampling\">Sampling<\/a>, <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/server\/prompts\">Prompt<\/a>(<em>\uadf8\ub9bc\uc5d0 \uc5c6\uc74c<\/em>) \ub4f1\uc740 \ud575\uc2ec \uae30\ub2a5\ub4e4\uc774\uae34 \ud558\uc9c0\ub9cc \ud234\uc744 \uc81c\uc678\ud55c \uae30\ub2a5\ub4e4\uc740 \ud5a5\ud6c4 \uae30\ud68c\uac00 \ub420 \ub54c \ub2e4\ub8e8\uae30\ub85c \ud558\uace0 \uc774 \uae00\uc5d0\uc11c\ub294 \uc0dd\ub7b5\ud55c\ub2e4. \uc9c0\uae08\uae4c\uc9c0 Client\uc640 Server\uac00 MCP\ub97c \ud1b5\ud574 \uc81c\uacf5\ud558\ub294 \uc8fc\uc694 \ub2a5\ub825\uce58(Capability)\uc640 \uc774\ub4e4 \uac04\uc758 \ub3d9\uc791\uc744 \uc0b4\ud3b4 \ubd24\ub2e4\uba74 \uc774\uc81c \ub3d9\uc791 \uacfc\uc815\uc5d0\uc11c \uc5b4\ub5a0\ud55c Lifecycle \ub2e8\uacc4\ub97c \uac70\uce58\ub294\uc9c0 \uc0b4\ud3b4 \ubcf4\uc790.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lifecycle<\/h2>\n\n\n\n<p>MCP\ub294 Client-Server \uc5f0\uacb0\uc744 \uc704\ud574 \uc5c4\uaca9\ud55c Lifecycle\uc744 \uc815\uc758\ud558\uace0 \uc788\uc73c\uba70 \uc774\ub97c \ud1b5\ud574 \uc801\uc808\ud55c Capability Negotiation\uacfc \uc0c1\ud0dc \uad00\ub9ac\uac00 \ub418\ub3c4\ub85d \ud55c\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"396\" height=\"635\" src=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-1.png\" alt=\"\" class=\"wp-image-2544\" srcset=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-1.png 396w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-1-187x300.png 187w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-1-168x270.png 168w\" sizes=\"auto, (max-width: 396px) 100vw, 396px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Initialization<\/h3>\n\n\n\n<p>\ucd08\uae30\ud654(Intialization)\ub2e8\uacc4\ub294 Client\uc640 Server\uac04\uc5d0 \uc218\ud589\ub418\ub294 \ucd5c\ucd08\uc758 interaction\uc73c\ub85c Client\uc640 Server\ub294 \uc544\ub798\uc758 \ub3d9\uc791\uc744 \uc218\ud589\ud55c\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud504\ub85c\ud1a0\ucf5c \ubc84\uc804 \ud638\ud658\uc131 \ud655\ub9bd<\/li>\n\n\n\n<li>\uae30\ub2a5(Capability) \uad50\ud658\uacfc \ud611\uc0c1(negotiation)<\/li>\n\n\n\n<li>\uc138\ubd80 \uad6c\ud604\uc0ac\ud56d \uacf5\uc720<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operation<\/h3>\n\n\n\n<p>\ub3d9\uc791(Operation) \ub2e8\uacc4\uc5d0\uc11c Client\uc640 Server\ub294 \uc0c1\ud638 \ud611\uc758\ub41c Capability\uc5d0 \ub530\ub77c \uba54\uc2dc\uc9c0\ub97c \uad50\ud658\ud55c\ub2e4. \uc774\ub54c<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\uc0c1\ud638 \ud611\uc758\ub41c \ud504\ub85c\ud1a0\ucf5c \ubc84\uc804\uc744 \uc900\uc218\ud574\uc57c \ud558\uba70<\/li>\n\n\n\n<li>\ud611\uc758\ub41c Capability\ub4e4 \ub9cc\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Shutdown<\/h3>\n\n\n\n<p>\uc885\ub8cc(Shutdown) \ub2e8\uacc4\ub294 \uc5b4\ub290 \ud55c \ucabd(\ubcf4\ud1b5 Client \ucabd)\uc5d0\uc11c \ud504\ub85c\ud1a0\ucf5c\uc758 Connection\uc744 \uc885\ub8cc\ud55c\ub2e4. \uba85\uc2dc\uc801\uc778 shutdown \uba54\uc2dc\uc9c0\ub294 \uc815\uc758\ub418\uc9c0 \uc54a\uc558\uc73c\ub098 \ub0b4\ubd80\uc801\uc73c\ub85c Connection \uc885\ub8cc \uc2e0\ud638\ub97c \ubcf4\ub0b4\uae30 \uc704\ud55c Transport \ub9e4\ucee4\ub2c8\uc998\uc774 \uc801\uc6a9\ub41c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Transport<\/h2>\n\n\n\n<p>Client\uc640 Server\uac04\uc758 \ud1b5\uc2e0\uc5d0\uc11c \ud504\ub85c\ud1a0\ucf5c\uc740 \ub450 \uac00\uc9c0\uc758 \uc804\uc1a1 \uba54\ucee4\ub2c8\uc998\uc744 \ud45c\uc900\uc73c\ub85c \uaddc\uc815\ud558\uace0 \uc788\uc73c\uba70 MCP\uc5d0\uc11c \uc911\uc694\ud55c \ubd80\ubd84\uc744 \ucc28\uc9c0\ud55c\ub2e4. \ub124\ud2b8\uc6cc\ud06c \ud504\ub85c\uadf8\ub7a8\uc744 \uac1c\ubc1c\ud558\ub824\uba74 Socket\uc5d0 \ub300\ud55c \uc9c0\uc2dd\uc774 \uc788\uc5b4\uc57c \ud558\ub4ef\uc774 MCP \ud504\ub85c\uadf8\ub7a8\uc744 \uac1c\ubc1c\ud558\ub824\uba74 Trasport\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \ud544\uc218\uc801\uc774\ub2e4. MCP\ub294 \uba54\uc2dc\uc9c0 \uc1a1\uc218\uc2e0\uc744 \uc778\ucf54\ub529\ud558\uae30 \uc704\ud574 JSON-RPC\ub97c \uc774\uc6a9\ud558\uba70 \ubc18\ub4dc\uc2dc UTF-8\ub85c \uc778\ucf54\ub529 \ub418\uc5b4\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p>\ud604\uc7ac MCP \ud504\ub85c\ud1a0\ucf5c(<em>ver 2025-06-18<\/em>)\uc740 Client\uc640 Server \ud1b5\uc2e0\uc5d0 \ub450 \uac00\uc9c0\uc758 \ud45c\uc900 Transport \ub9e4\ucee4\ub2c8\uc998\uc744 \uc815\uc758\ud558\uace0 \uc788\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>stdio (\ud45c\uc900 input\/output \uc744 \uc774\uc6a9\ud55c \ud1b5\uc2e0)<\/li>\n\n\n\n<li>Streamable HTTP<\/li>\n<\/ul>\n\n\n\n<p>\ucc38\uace0\ub85c, stdio \ubc29\uc2dd\uc740 Client\uac00 \ud544\uc218 \uad6c\ud604\uc0ac\ud56d\uc73c\ub85c \uaddc\uc815\ud558\uace0 \uc788\uc73c\uba70, \ucee4\uc2a4\ud140(custom) trasport\ub97c \ub9cc\ub4e4\uc5b4 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uac00\ub2a5\ud558\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \ub300\ubd80\ubd84\uc758 AI \ud504\ub85c\uadf8\ub7a8\uc740 \uc6f9 \ud658\uacbd\uc5d0\uc11c \ub3d9\uc791\ud558\ubbc0\ub85c \uc5ec\uae30\uc11c\ub294 Streamable HTTP \uae30\ubc18\uc73c\ub85c \uc124\uba85\ud558\uace0 sdio\ub294 \ucd94\ud6c4 \ud544\uc694\uc2dc \uc124\uba85\ud558\ub3c4\ub85d \ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Streamable HTTP<\/h2>\n\n\n\n<p><strong>Streamable HTTP<\/strong> Transport\ub294 2024-11-05 \ubc84\uc804\uc758 \ud504\ub85c\ud1a0\ucf5c\uc5d0\uc11c \uc18c\uac1c\ub41c HTTP + SSE transport\ub97c \ub300\uccb4\ud558\ub294 \uac83\uc73c\ub85c Server\ub294 \ub3c5\ub9bd \ud504\ub85c\uc138\uc2a4\ub85c \ub3d9\uc791\ud558\uba70 \ub2e4\uc218\uc758 Client Connection \ucc98\ub9ac\uac00 \uac00\ub2a5\ud558\ub2e4. \uc774 Transport\ub294 HTTP Method\uc911 POST\uc640 GET \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uba70 \ub2e4\uc218\uc758 \uc11c\ubc84 \uba54\uc2dc\uc9c0\ub97c \uc2a4\ud2b8\ub9ac\ubc0d\ud558\uae30 \uc704\ud574 \uc120\ud0dd\uc801\uc73c\ub85c SSE(Server-Sent Event)\ub97c \uc801\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<p><span style=\"text-decoration: underline;\">Server\ub294 POST\uc640 GET\uc744 \uc9c0\uc6d0\ud558\ub294 MCP Endpoint(<em>\/mcp<\/em>)\ub97c \ubc18\ub4dc\uc2dc \uc81c\uacf5<\/span>\ud574\uc57c \ud558\uba70 \uc77c\ubc18\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ud615\ud0dc\ub97c \uac00\uc9c4\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:\/\/example.com<strong>\/mcp<\/strong><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\uba54\uc2dc\uc9c0 \uc1a1\uc2e0(to server)<\/h3>\n\n\n\n<p>Client\uc5d0\uc11c JSON-RPC \uba54\uc2dc\uc9c0 \uc1a1\uc2e0\uc758 \uc2dc\uc791\uc740 \ubc18\ub4dc\uc2dc <span style=\"text-decoration: underline;\">HTTP POST \ub97c \ud1b5\ud574 MCP Endpoint\ub85c  \uc694\uccad<\/span>\ub418\uc5b4\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\uba54\uc2dc\uc9c0 \uc218\uc2e0(from server)<\/h3>\n\n\n\n<p>Client\uac00 <span style=\"text-decoration: underline;\">SSE \uc2a4\ud2b8\ub9bc\uc744 \uc624\ud508\ud558\ub824\uba74 HTTP GET \ubc29\uc2dd\uc73c\ub85c MCP Endpoint\ub85c \uc694\uccad<\/span>\uc744 \ubcf4\ub0b4\uba74 \ub41c\ub2e4. \uc774 \uacbd\uc6b0 Client\ub294 HTTP POST\ub85c \uc694\uccad\uc744 \uba3c\uc800 \ubcf4\ub0b4\uc9c0 \uc54a\ub354\ub77c\ub3c4 \uc11c\ubc84\uc640 \ud1b5\uc2e0\uc744 \ud560 \uc218 \uc788\ub2e4. \uc774\ub54c Client Request \uc758 \ud5e4\ub354\uc758 <em><code>Accept<\/code><\/em> \ud0a4 \uac12\uc73c\ub85c <em><code>text\/event-stream<\/code><\/em>\uc744 \uae30\uc220\ud55c\ub2e4. \ub610\ud55c \uc5ed\uc73c\ub85c \uc11c\ubc84\uac00 \uba3c\uc800 SSE stream\uc744 \uc2dc\uc791\ud560 \uc218\ub3c4 \uc788\ub2e4(<em>\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \uaddc\uaca9 \ucc38\uc870<\/em>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Multiple Connections<\/h3>\n\n\n\n<p>Client\ub294 \ub3d9\uc2dc\uc5d0 \ub2e4\uc218\uc758 SSE \uc2a4\ud2b8\ub9bc\uc744 \uc5f0\uacb0\ud558\uace0 \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Session Management<\/h3>\n\n\n\n<p>MCP\uc5d0\uc11c Session\uc740 \ucd08\uae30\ud654(initialization) \ub2e8\uacc4\uc5d0\uc11c \uc2dc\uc791\ud558\uba70 Client\uc640 Server\uc0ac\uc774\uc5d0\uc11c \ub17c\ub9ac\uc801\uc73c\ub85c \uc11c\ub85c \uc5f0\uacb0\ub41c interaction\ub4e4\uc744 \ub9d0\ud55c\ub2e4. \ucd08\uae30\ud654 \ub2e8\uacc4\uc5d0\uc11c \uc11c\ubc84\ub294 session id\ub97c \uc0dd\uc131\ud558\uace0 HTTP Response\uc758 Header\uc5d0 <code>Mcp-Session-Id<\/code> \ud0a4\ub85c \uadf8 \uac12\uc744 \uc124\uc815\ud55c \ud6c4 \uc804\uc1a1\ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc0ac\uc6a9\uc790\uac00 \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc885\ub8cc\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \ub354\uc774\uc0c1 Client\uac00 session\uc744 \uc720\uc9c0\ud560 \ud544\uc694\uac00 \uc5c6\ub2e4\uba74 \uba85\uc2dc\uc801\uc73c\ub85c session\uc744 \uc885\ub8cc\ud560 \uc218 \uc788\ub3c4\ub85d \ud5e4\ub354\uc5d0 <code>Mcp-Session-Id<\/code> \ub97c \ud3ec\ud568\ud558\uc5ec MCP Endpoint\ub85c HTTP DELETE Request\ub97c \uc804\uc1a1\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Sequence Diagram<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"394\" height=\"1024\" src=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-394x1024.png\" alt=\"\" class=\"wp-image-2549\" srcset=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-394x1024.png 394w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-115x300.png 115w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-768x1996.png 768w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-591x1536.png 591w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-788x2048.png 788w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3-104x270.png 104w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-3.png 814w\" sizes=\"auto, (max-width: 394px) 100vw, 394px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Server Features<\/h2>\n\n\n\n<p>MCP\ub294 LLM\uc5d0 Context\ub97c \ucd94\uac00\ud560 \uc218 \uc788\ub3c4\ub85d Server\ub294 \uc544\ub798\uc544 \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uad6c\uc131 \uc694\uc18c\ub97c \uc81c\uacf5\ud55c\ub2e4. \uc774\ub97c \uae30\ubc18\uc73c\ub85c Client\uc640 Server \uadf8\ub9ac\uace0 LLM\uc0ac\uc774\uc5d0 \ud65c\ubc1c\ud55c \uc0c1\ud638\uc791\uc6a9\uc774 \uac00\ub2a5\ud574 \uc9c4\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Prompt<\/strong>: \uc0ac\uc804 \uc815\uc758\ub41c \ud15c\ud50c\ub9bf \ub610\ub294 \uba85\ub839\uc5b4\ub85c LLM\uacfc\uc758 \uc0c1\ud638\uc791\uc6a9\uc744 \uac00\uc774\ub4dc \ud55c\ub2e4.<\/li>\n\n\n\n<li><strong>Resource<\/strong>: \uad6c\uc870\uc801\uc778 \ub370\uc774\ud130 \ub610\ub294 \ucee8\ud150\uce20\ub85c LLM\uc5d0 \ucd94\uac00\uc801\uc778 context\ub97c \uc81c\uacf5\ud55c\ub2e4.<\/li>\n\n\n\n<li><strong>Tools<\/strong>: \uc2e4\ud589\uac00\ub2a5\ud55c function\uc73c\ub85c LLM\uc774 \ub3d9\uc791\uc744 \uc218\ud589\ud558\uac70\ub098 \uc815\ubcf4\ub97c \ucd94\ucd9c\ud560 \uc218 \uc788\ub3c4\ub85d \ud55c\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p>\uc694\uc57d\ud558\uba74, Prompt\ub294 \uc571\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uba54\ub274 \ud615\ud0dc\ub85c \uc0ac\uc6a9\uc790\uac00 \uc9c1\uc811 \uc81c\uc5b4\ud558\uba70, Resource\ub294 \ud30c\uc77c \uc2dc\uc2a4\ud15c\uc0c1\uc758 \ud30c\uc77c \ubaa9\ub85d\uacfc \uac19\uc774 Client\uc5d0\uc11c \uad00\ub9ac\ub418\uba70 \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc81c\uc5b4\ud55c\ub2e4. \ub9c8\uc9c0\ub9c9\uc73c\ub85c Tool\uc740 LLM\uc774 \uc9c1\uc811 \uc11c\ubc84 \uc0c1\uc5d0 \uc788\ub294 fuction(RESTful API)\uc744 \ud638\ucd9c\ud558\ub294 \ud615\ud0dc\ub85c LLM\uc774 Context\uc5d0 \uc801\ud569\ud55c \ub3c4\uad6c\ub97c \uc120\ud0dd\ud558\uace0 \uc9c1\uc811 \uc218\ud589\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. Tool\uc774 \uc0ac\ub78c\uc758 \ud314\uacfc \ub2e4\ub9ac \uc5ed\ud560\uc744 \ud55c\ub2e4\uba74 Resource\ub294 \ub208\uacfc \uadc0, \uadf8\ub9ac\uace0 Prompt\ub294 \uc785\uc758 \uc5ed\ud560\uc744 \ud55c\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc5b4\ub824\uc6c0\uc774 \uc5c6\uc744 \uac83\uc774\ub2e4. \uc774 \ubb38\uc11c\uc5d0\uc11c\ub294 MCP\uc5d0\uc11c \ud575\uc2ec \uae30\ub2a5\uc73c\ub85c \uc778\uc2dd\ub418\ub294 Tool \ud65c\uc6a9\uc5d0 \ucd1b\uc810\uc744 \ub9de\ucdb0 \uc124\uba85\uc744 \uc774\uc5b4\uac00\ub3c4\ub85d \ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tools<\/h2>\n\n\n\n<p>MCP\ub97c \uc774\uc6a9\ud558\uba74 LLM\uc774 \uc774\uc6a9\ud560 \uc218 \uc788\ub294 \ud234\uc744 Server\ub97c \ud1b5\ud574 \ub178\ucd9c\ud560 \uc218 \uc788\ub2e4. \uc774\ub7f0 Tool\uc744 \ud65c\uc6a9\ud558\uba74 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \ucffc\ub9ac \uc2e4\ud589\uc774\ub098 API \ud638\ucd9c\uacfc \uac19\uc774 LLM\uc774 \uc678\ubd80\uc5d0 \uc788\ub294 \uc2dc\uc2a4\ud15c\uacfc \uc5f0\ub3d9\uc774 \uac00\ub2a5\ud574 \uc9c4\ub2e4.<\/p>\n\n\n\n<p>\ud234(tool)\uc740 LLM\uc774 \ucee8\ud2b8\ub864 \ud560 \uc218 \uc788\ub3c4\ub85d \uc124\uacc4 \ub418\uc5b4 \uc788\ub2e4. \uc989, \uc0ac\uc6a9\uc790\uc758 Prompt\uc640 Context\uc5d0 \uae30\ubc18\ud558\uc5ec LLM\uc774 \uc790\ub3d9\uc73c\ub85c \ud234\uc744 \uc2dd\ubcc4\ud558\uace0 \uc2e4\ud589\uae4c\uc9c0 \ud560 \uc218 \uc788\uc74c\uc744 \uc758\ubbf8\ud55c\ub2e4. Tool\uc744 \uc2dd\ubcc4\ud558\uace0 \uc2e4\ud589\ud558\ub294 \uacfc\uc815\uc740 \uc544\ub798\uc758 \uadf8\ub9bc\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Message Flow<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"487\" height=\"676\" src=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-4.png\" alt=\"\" class=\"wp-image-2551\" srcset=\"https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-4.png 487w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-4-216x300.png 216w, https:\/\/skanto.co.kr\/wp-content\/uploads\/2025\/07\/image-4-195x270.png 195w\" sizes=\"auto, (max-width: 487px) 100vw, 487px\" \/><\/figure>\n\n\n\n<p>\uc9c0\uae08\uae4c\uc9c0 MCP\uc5d0 \uad00\ud55c \ub300\ub7b5\uc801\uc778 \ubd80\ubd84\uc744 \uc0b4\ud3b4 \ubd24\ub2e4\uba74 \uc774\uc81c \uc774\ub7f0 \ub0b4\uc6a9\uc744 \ubc14\ud0d5\uc73c\ub85c \uad6c\uccb4\uc801\uc778 Agent\ub97c \uc81c\uc791\ud574 \ubcf4\uc790. \uc18c\uc2a4\ucf54\ub529\uc73c\ub85c \uc9c1\uc811 AI Agent\ub97c \uac1c\ubc1c\ud558\ub824\uba74 \uc2ec\ub3c4\uc788\uac8c\ub294 \uc544\ub2c8\ub354\ub77c\ub3c4 MCP\uac00 \ub0b4\ubd80\uc801\uc73c\ub85c \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294 \uc9c0\ub97c \uc774\ud574\ud558\ub294 \uac83\uc774 \ub9e4\uc6b0 \uc911\uc694\ud558\ub2e4. \uc778\ud130\ub137\uc5d0 \ub3cc\uc544\ub2e4\ub2c8\ub294 MCP\uad00\ub828 \ub2e8\ud3b8\uc801\uc778 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ub2e4\uc6b4\ubc1b\uc544 \ud3b8\ud558\uac8c \uc2e4\ud589\ud574 \ubcfc \uc218\ub294 \uc788\uaca0\uc9c0\ub9cc \uc774\ub807\uac8c \ud574\uc11c\ub294 \ub290\ub08c \uc815\ub3c4\ub9cc \ud30c\uc545\ud560 \ubfd0 \ub9c9\uc0c1 \uac1c\ubc1c\ud558\ub824\uba74 \ub9c9\ub9c9\ud574 \uc9c0\uae30 \ub54c\ubb38\uc774\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Applying MCP in Real Scenario<\/h2>\n\n\n\n<p>MCP\ub97c \ud65c\uc6a9\ud558\uc5ec Agent\ub97c \uac1c\ubc1c\ud558\ub824\uba74 \uc6b0\uc120 \uc5b4\ub5a4 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\ub85c \uc2dc\uc791 \ud560\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4. \ud65c\uc6a9 \uac00\ub2a5\ud55c \uc5ec\ub7ec\uac00\uc9c0 \uc5b8\uc5b4\ub4e4\uc774 \uc788\uaca0\uc9c0\ub9cc \uc5ec\uae30\uc11c\ub294 JavaScript\ub97c \uc774\uc6a9\ud558\uc5ec Agent\ub97c \uad6c\ud604\ud574 \ubcf4\ub3c4\ub85d \ud55c\ub2e4. \ud544\uc694\ud558\ub2e4\uba74 Python\uacfc \uac19\uc774 \uc790\uc2e0\uc5d0\uac8c \uc775\uc219\ud55c \uc5b8\uc5b4\ub97c \uc0ac\uc6a9\ud574\ub3c4 \ubb34\ubc29\ud558\ub2e4. \uc774 \uacbd\uc6b0 \uc804\ubc18\uc801\uc778 \uac1c\ub150\uc740 \ub3d9\uc77c \ud558\ub354\ub77c\ub3c4 \uad6c\ud604 \ubc29\ubc95\uc5d0\ub294 \ucc28\uc774\uac00 \ub9ce\uc73c\ub2c8 \ucc38\uace0\ud558\uae30 \ubc14\ub780\ub2e4.<\/p>\n\n\n\n<p>\uc6b0\uc120 AI Agent \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uac1c\ubc1c \ud234\ud0b7\uc774 \ud544\uc694\ud558\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>LLM \uae30\ubc18\uc758 AI \uc5b4\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c \ud504\ub808\uc784\uc6cc\ud06c\uc778 <a href=\"https:\/\/github.com\/langchain-ai\/langchainjs\">LangChain.js<\/a><\/li>\n\n\n\n<li>MCP \ud504\ub85c\ud1a0\ucf5c \uc2a4\ud399 \uad6c\ud604\uccb4\uc778 <a href=\"https:\/\/github.com\/modelcontextprotocol\/typescript-sdk\">MCP SDK<\/a><\/li>\n\n\n\n<li>LangChain \uc0c1\uc5d0\uc11c MCP\ub97c \uae30\ub2a5\uc744 \ud655\uc7a5\ud560 \uc218 \uc788\ub3c4\ub85d \uc9c0\uc6d0\ud558\ub294 <a href=\"https:\/\/www.npmjs.com\/package\/@langchain\/mcp-adapters\">LangChain.js MCP Adapter<\/a><\/li>\n\n\n\n<li>MCP Server\ub97c \uad6c\ub3d9\ud558\uae30 \uc704\ud55c <a href=\"https:\/\/expressjs.com\">Express.js<\/a><\/li>\n<\/ul>\n\n\n\n<p>\uc774\ub4e4 \ud234\ud0b7\uc744 \uc124\uce58\ud558\ub294 \ubc29\ubc95\uc740 \ub9c1\ud06c\ub85c \uc5f0\uacb0\ub41c \uac01 \ud398\uc774\uc9c0\ub97c \ucc38\uc870\ud558\uae30 \ubc14\ub780\ub2e4.<\/p>\n\n\n\n<p>\uc5ec\uae30\uc11c\ub294 \uc0ac\uce59\uc5f0\uc0b0 \ud234\uacfc \ub0a0\uc528\ub97c \uc54c\ub824\uc8fc\ub294 \ud234\uc744 \uac01\uac01 \uc11c\ub85c \ub2e4\ub978 MCP\uc11c\ubc84\ub85c \uad6c\ud604\ud558\uace0 AI Agent\ub294 \uc0ac\uc6a9\uc790\uac00 \uc785\ub825\ud558\ub294 \ud504\ub86c\ud504\ud2b8\ub97c \uc774\ud574\ud55c \ud6c4 \uc801\uc808\ud558\uac8c \uc774\ub4e4 \ud234\uc744 \ud65c\uc6a9\ud558\ub294 \uc9c0 \uc0b4\ud3b4\ubcf4\ub3c4\ub85d \ud55c\ub2e4. \uc6b0\uc120, \uc2dc\uce59\uc5f0\uc0b0\uc744 \uc704\ud55c MCP \ud234\uc744 \ub9cc\ub4e4\uace0 <a href=\"https:\/\/expressjs.com\">Express.js<\/a> \ub97c \uc774\uc6a9\ud558\uc5ec MCP Client\ub85c \ud574\ub2f9 \ud234\uc744 \ub178\ucd9c\ud558\ub294 \uacfc\uc815\uc744 \uc81c\uc791\ud574 \ubcf4\uc790.<\/p>\n\n\n\n<p>\uac1c\ubc1c \ub2e8\uacc4\ubcc4\ub85c \ud575\uc2ec\uc774 \ub418\ub294 \ub0b4\uc6a9\uc744 \uba3c\uc800 \uc124\uba85\ud558\uace0 \uc804\uccb4 \uc18c\uc2a4\ucf54\ub4dc\ub294 \ub9e8 \ub098\uc911\uc5d0 \ud655\uc778\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\uc131\ud588\ub2e4. \uc804\uccb4 \ucf54\ub4dc\ub97c \uba3c\uc800 \ud655\uc778\ud558\uace0 \uc2f6\ub2e4\uba74 \ub4b7\ubd80\ubd84\uc73c\ub85c \ubc14\ub85c \uc774\ub3d9\ud574\ub3c4 \ubb34\ubc29\ud558\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">MCP Server \uc0dd\uc131\uacfc \ud234(Tool) \ub4f1\ub85d<\/h3>\n\n\n\n<p>\ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c MCP Server\ub97c \uc0dd\uc131\ud558\uace0 \ud234\ub3c4 \uc27d\uac8c \uc81c\uc791 \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const server = () =&gt; {\n  <strong>const mcp = new McpServer({ name: 'calc-server', version: '1.0.0' });<\/strong>\n\n  \/\/ tool registeration\n  <strong>mcp.registerTool<\/strong>('add', {\n    title: 'Addition Tool',\n    description: 'Add two numbers',\n    inputSchema: { a: z.number(), b: z.number() }\n  }, async ({ a, b }) =&gt; {\n    console.log(`executes operation ${a} + ${b}`);\n    return { content: &#91;{ type: 'text', text: String(a + b) }] };\n  });\n\n  <strong>mcp.registerTool<\/strong>('multiply', {\n    title: 'Multiply Tool',\n    description: 'Multiply two numbers',\n    inputSchema: { a: z.number(), b: z.number() }\n  }, async ({ a, b }) =&gt; {\n    console.log(`executes operation ${a} * ${b}`);\n    return { content: &#91;{ type: 'text', text: String(a * b) }] };\n  });\n\n  console.log('tool and resource are registered!');\n  return mcp;\n};<\/code><\/pre>\n\n\n\n<p><em><code>McpServer<\/code><\/em> \uac1d\uccb4\ub97c \uc0dd\uc131\ud55c \ud6c4 <em><code>registerTool()<\/code><\/em> \uba54\uc18c\ub4dc\ub97c \ud65c\uc6a9\ud558\uc5ec tool <em>name<\/em>\uacfc <em>title<\/em>, <em>description<\/em>, \uadf8\ub9ac\uace0 \uc785\ub825 \ud30c\ub77c\ubbf8\ud130\uc758 Schema(\ud30c\ub77c\ubbf8\ud130 \uc2dc\uadf8\ub108\ucc98)\ub97c \uc815\uc758\ud55c\ub2e4. \uc5ec\uc11c\uae30 \uae30\uc220\ud558\ub294 <em>title<\/em>\uacfc <em>description<\/em>\uc740 MCP Client\uc640\uc758 \ucd08\uae30\ud654 \uacfc\uc815(hand-shaking)\uc5d0\uc11c Agent(LLM)\ub85c \uc804\ub2ec\ub41c \ud6c4 Context\ub97c \ud615\uc131\ud558\ubbc0\ub85c AI\uac00 \uc774\ud574\ud558\uae30 \uc26c\uc6b4 \ub0b4\uc6a9\uc73c\ub85c \uc791\uc131\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \uadf8\ub9ac\uace0 \ub9c8\uc9c0\ub9c9 \ud30c\ub77c\ubbf8\ud130\ub294 Agent\uac00 tool \uc2e4\ud589\uc744 \uc704\ud574 Request\ub97c \ubcf4\ub0b4\uba74 \uc2e4\ud589\ub418\ub294 callback function\uc73c\ub85c \uc774 \ubd80\ubd84\uc5d0\uc11c tool\uc758 \uc0c1\uc138 \uae30\ub2a5\uc744 \uad6c\ud604\ud558\uba74 \ub41c\ub2e4. callback function\uc758 \ud30c\ub77c\ubbf8\ud130\ub294 <code>inputSchema<\/code>\uc5d0\uc11c \uc815\uc758\ud55c \uba85\uc138\ub97c \ub530\ub978\ub2e4. \uc704 \uc608\uc81c\uc5d0\uc11c\ub294 \ub354\ud558\uae30\uc640 \uacf1\ud558\uae30 \ud234\uc744 \ub9cc\ub4e4\uace0 \ub4f1\ub85d\ud588\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Transport \uc0dd\uc131 \ud6c4 \uc11c\ubc84\uc640 \uc5f0\uacb0<\/h3>\n\n\n\n<p>MCP \ud504\ub85c\ud1a0\ucf5c \ucc98\ub9ac\ub97c \uc704\ud574 <code>StreamableHTTPServerTransport<\/code> \uac1d\uccb4\ub97c \uc0dd\uc131\ud558\uace0 \uc55e\uc5d0\uc11c \uc0dd\uc131\ud55c <code>McpServer<\/code>\uac1d\uccb4\uc640 \uc5f0\uacb0\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ holds transport instances for caching\nconst transports = { };\n\n<strong>let transport = new StreamableHTTPServerTransport<\/strong>({\n  sessionIdGenerator: () =&gt; randomUUID(),\n  onsessioninitialized: (sessionId) =&gt; {\n    console.log(`Session initialized with ID: ${sessionId}`);\n    transports&#91;sessionId] = transport;\n  },\n  enableDnsRebindingProtection: true,\n  allowHosts: &#91;'127.0.0.1']\n});\n\ntransport.onclose = () =&gt; {\n  const { sessionId } = transport;\n  if (sessionId &amp;&amp; transport&#91;sessionId]) {\n    console.log(`Transport closed for session ${sessionId}, removing from cahce`);\n    delete transports&#91;sessionId];\n  }\n};\n\n<strong>await server().connect(transport);<\/strong>\n<strong>await transport.handleRequest(req, res, req.body);<\/strong>\nconsole.log('Server is connected with StreamableHTTPServerTransport!');<\/code><\/pre>\n\n\n\n<p><code>StreamableHTTPServerTransport<\/code> \uac1d\uccb4 \uc0dd\uc131\uc2dc <code>Mcp-Session-Id<\/code>\ub97c \uac19\uc774 \uc0dd\uc131\ud558\uba70 \uc774\ub807\uac8c \uc0dd\uc131\ub41c Session Id\ub97c \uc774\uc6a9\ud558\uc5ec \ub3d9\uc77c \uc138\uc158\uc5d0\ub294 \ub3d9\uc77c\ud55c <code>StreamableHTTPServerTransport<\/code>\uac00 \uc0ac\uc6a9\ub418\ub3c4\ub85d <em><code>onsessioninitialized<\/code><\/em> \ud638\ucd9c\uc2dc Session Id\ub97c \ud0a4\ub85c\ud558\uc5ec Caching \ucc98\ub9ac\ud55c\ub2e4. \uadf8\ub9ac\uace0 Security(<em><a href=\"https:\/\/en.wikipedia.org\/wiki\/DNS_rebinding\">DNS rebinding attacks<\/a><\/em>) \uc81c\uc57d\uc0ac\ud56d\uc73c\ub85c <em><code>allowHosts<\/code><\/em>\ub294 \ub85c\uceec\uba38\uc2e0 \uc0c1\uc5d0\uc11c Client\uc640 \uc5f0\ub3d9\ub418\ub294 Host\ub97c \uba85\uc2dc\ud558\ub3c4\ub85d \ud558\uba70 <em><code>enableDnsRebindingProtection<\/code><\/em> \uc635\uc158\uc744 \uc124\uc815(default: true)\ud558\ub3c4\ub85d \ud558\uace0 \uc788\ub2e4.<\/p>\n\n\n\n<p>\ub9c8\uc9c0\ub9c9\uc73c\ub85c Transport\uac00 Close\ub420 \ub54c callback \ubc1b\ub294 <em><code>onclose()<\/code><\/em> \uba54\uc18c\ub4dc\uc5d0\uc11c\ub294 Caching \ud588\ub358 StreamableHTTPServerTransport\ub97c \uc0ad\uc81c\ucc98\ub9ac \ud55c\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Express.js\ub97c \uc774\uc6a9\ud55c RESTful API \uad6c\ud604<\/h3>\n\n\n\n<p>\uc55e\uc5d0\uc11c HTTP POST, GET \uc740 \ubc18\ub4dc\uc2dc \uad6c\ud604\ud574\uc57c \ud558\uba70 session\uc744 \uc885\ub8cc\ud558\uae30 \uc704\ud574 DELETE \ub3c4 \uac19\uc774 \uad6c\ud604\ud574 \uc8fc\uc5b4\uc57c \ud55c\ub2e4\uace0 \ud588\ub2e4. \uadf8\ub7fc \uac00\uc7a5 \uae30\ubcf8\uc774 \ub418\ub294 POST\ub97c \uba3c\uc800 \uad6c\ud604\ud558\ub3c4\ub85d \ud558\uc790.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">HTTP POST- <em>app.post(END_POINT, async (req, res) =&gt; { &#8230; }<\/em><\/h4>\n\n\n\n<p>HTTP POST\ub294 Client\uc5d0\uc11c \ucd5c\ucd08\ub85c \ud638\ucd9c\ud558\ub294 Endpoint\ub85c\uc11c Transport \uac1d\uccb4\ub97c \uc0dd\uc131\ud55c \ud6c4 \uc55e\uc5d0\uc11c \uc124\uba85\ud588\ub358 <code>server()<\/code>\uba54\uc18c\ub4dc\ub97c \uc774\uc6a9\ud558\uc5ec MCPServer\uc640 \uc5f0\uacb0(connect)\ud558\ub294 \uac83\uc774 \uc8fc\uc694 \uae30\ub2a5\uc774\ub2e4. \ucd94\uac00\uc801\uc73c\ub85c \ud55c \ubc88 \uc0dd\uc131\ub41c Transport \uac1d\uccb4\ub97c \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc704\ud574 sessionId\ub97c \uc774\uc6a9\ud558\uc5ec Caching\ud558\ub294 \uae30\ub2a5\ub3c4 \uac19\uc774 \uad6c\ud604 \ud588\ub2e4.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">HTTP GET- <em>app.get(END_POINT, async (req, res) =&gt; { &#8230; }<\/em><\/h4>\n\n\n\n<p>HTTP GET\uc740 SSE(Server Sent Event) \uc2a4\ud2b8\ub9bc\uc744 \ucc98\ub9ac\ud558\ub294 \uae30\ub2a5\uc744 \ub2f4\ub2f9\ud55c\ub2e4.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">HTTP DELETE- <em><strong>a<\/strong>pp.delete(END_POINT, async (req, res) =&gt; { &#8230; }<\/em><\/h4>\n\n\n\n<p>HTTP DELETE\ub294 Client\uc640 Server\uac04\uc5d0 \ub9fa\uc5b4\uc9c4 Session\uc744 \uc885\ub8cc\ud560 \ub54c \ud638\ucd9c\ub418\uba70 \uad00\ub828\ub41c \uae30\ub2a5\uc744 \ucc98\ub9ac\ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc9c0\uae08\uae4c\uc9c0 \uc124\uba85\ud55c \ub0b4\uc6a9\uc744 \uc644\uc804\ud55c \uc18c\uc2a4\ucf54\ub4dc\ub85c \uae30\uc220\ud558\uba74 \uc544\ub798\uc640 \uac19\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import express from 'express';\nimport { randomUUID } from \"node:crypto\";\nimport { McpServer, ResourceTemplate } from '@modelcontextprotocol\/sdk\/server\/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol\/sdk\/server\/streamableHttp.js';\nimport { isInitializeRequest } from '@modelcontextprotocol\/sdk\/types.js'\nimport { z } from 'zod';\nimport cors from 'cors';\n\n\/\/MCP endpoint and server listening port \nconst &#91;END_POINT, PORT] = &#91;'\/mcp', 3000];\n\n\/\/ Create an MCP server\nconst server = () =&gt; {\n  const mcp = new McpServer({ name: 'calc-server', version: '1.0.0' });\n\n  \/\/ tool registeration\n  mcp.registerTool('add', {\n    title: 'Addition Tool',\n    description: 'Add two numbers',\n    inputSchema: { a: z.number(), b: z.number() }\n  }, async ({ a, b }) =&gt; {\n    console.log(`executes operation ${a} + ${b}`);\n    return { content: &#91;{ type: 'text', text: String(a + b) }] };\n  });\n\n  mcp.registerTool('multiply', {\n    title: 'Multiply Tool',\n    description: 'Multiply two numbers',\n    inputSchema: { a: z.number(), b: z.number() }\n  }, async ({ a, b }) =&gt; {\n    console.log(`executes operation ${a} * ${b}`);\n    return { content: &#91;{ type: 'text', text: String(a * b) }] };\n  });\n\n  \/\/ resource registration\n  mcp.registerResource(\"greeting\", new ResourceTemplate(\"greeting:\/\/{name}\", {\n    list: undefined\n  }), { \n    title: \"Greeting Resource\",      \/\/ Display name for UI\n    description: \"Dynamic greeting generator\"\n  }, async (uri, { name }) =&gt; ({\n    contents: &#91;{\n      uri: uri.href,\n      text: `Hello, ${name}!`\n    }]\n  }));\n  console.log('Tools and Resources are registered!');\n  return mcp;\n};\n\n\/\/ new instance of Express\nconst app = express();\n\n\/\/ holds transport instances for caching\nconst transports = { };\napp.use(express.json());\napp.use(cors({\n  origin: '*',\n  exposedHeaders: &#91;'Mcp-Session-Id'],\n  allowHeaders: &#91;'Content-Type', 'mcp-session-id']\n}));\n\n\/** handle POST request to MCP endpoint *\/\napp.post(END_POINT, async (req, res) =&gt; {\n  const sessionId = req.headers&#91;'mcp-session-id'];\n  const msg = (sessionId) ? `Received MCP request for session: ${sessionId}`: 'Request body:';\n  console.log(msg, req.body);\n\n  let transport;\n  if (sessionId &amp;&amp; transports&#91;sessionId]) {\n    transport = transports&#91;sessionId];\n  } else if (!sessionId &amp;&amp; isInitializeRequest(req.body)) {\n    transport = new StreamableHTTPServerTransport({\n      sessionIdGenerator: () =&gt; randomUUID(),\n      onsessioninitialized: (sessionId) =&gt; {\n        console.log(`Session initialized with ID: ${sessionId}`);\n        transports&#91;sessionId] = transport;\n      },\n      enableDnsRebindingProtection: true,\n      allowHosts: &#91;'127.0.0.1']\n    });\n\n    transport.onclose = () =&gt; {\n      const { sessionId } = transport;\n      if (sessionId &amp;&amp; transport&#91;sessionId]) {\n        console.log(`Transport closed for session ${sessionId}, removing from cahce`);\n        delete transports&#91;sessionId];\n      }\n    };\n\n    await server().connect(transport);\n    await transport.handleRequest(req, res, req.body);\n    console.log('Server is connected with StreamableHTTPServerTransport!\\n');\n    return;\n  } else {\n    res.status(400).json({\n      jsonrpc: '2.0',\n      error: { code: -32000, message: 'Bad Request: No valid session ID provided' },\n      id: null\n    });\n    return;\n  }\n  await transport.handleRequest(req, res, req.body);\n});\n\n\/** handle GET request to MCP endpoint *\/\napp.get(END_POINT, async (req, res) =&gt; {\n  const sessionId = req.headers&#91;'mcp-session-id'];\n  if (!sessionId || !transports&#91;sessionId]) {\n    res.status(400).send('Invalid or missing sesionID');\n    return;\n  }\n  const lastEventId = req.headers&#91;'last-event-id'];\n  const msg = (lastEventId) ? `Client reconnecting with Last-Event-Id: ${lastEventId}`\n      : `Establishing new SSE stream for session ${sessionId}`;\n  console.log(msg);\n\n  await transports&#91;sessionId].handleRequest(req, res);\n});\n\n\/** handle DELETE request to MCP endpoint *\/\napp.delete(END_POINT, async (req, res) =&gt; {\n  const sessionId = req.headers&#91;'mcp-session-id'];\n  if (!sessionId || !transports&#91;sessionId]) {\n    res.status(400).send('Invalid or missing sesionID');\n    return;\n  }\n  console.log(`Received session termination request for session ${sessionId}`);\n  try {\n    await transports&#91;sessionId].handleRequest(req, res);\n  } catch (error) {\n    console.error('Error handling session termination:', error);\n    if (!res.headerSent) {\n      res.status(500).send('Error processing session termination');\n    }\n  }\n});\n\n\/\/ start server\napp.listen(PORT, () =&gt; {\n  console.log(`MCP Server is listening on port ${PORT}`);\n});<\/code><\/pre>\n\n\n\n<p>MCP \uc11c\ubc84 \uc5f0\ub3d9\uc744 \uc704\ud574 \uac04\ub2e8\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud574 \ubcf4\uc558\ub2e4. \uc774\uc81c, \uc774\ub807\uac8c \uad6c\ud604\ub41c \uc11c\ubc84 \uae30\ub2a5\uc744 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc704\ud574 Agent \ud504\ub85c\uadf8\ub7a8\uc744 \uac04\ub2e8\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ubcf4\ub3c4\ub85d \ud558\uc790.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">AI Agent \uad6c\ud604<\/h3>\n\n\n\n<p>LLM\uc73c\ub85c \uc804\ub2ec\ud558\uae30 \uc704\ud55c \uc0ac\uc6a9\uc790 \ud504\ub86c\ud504\ud2b8\ub97c \ucf58\uc194\ub85c\ubd80\ud130 \uc785\ub825 \ubc1b\uc73c\uba70, MCP \uc11c\ubc84\uac00 \ub178\ucd9c\ud55c \ud234\uacfc \uc5f0\uacc4\ub41c \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \uc815\uc0c1\uc801\uc73c\ub85c \ud574\ub2f9 \ud234\uc774 \uc2e4\ud589\ub418\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub3c4\ub85d \ube44\uad50\uc801 \uac04\ub2e8\ud55c AI Agent \ud504\ub85c\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\ub3c4\ub85d \ud558\uaca0\ub2e4.<\/p>\n\n\n\n<p>MCP SDK\uc5d0 <a href=\"https:\/\/github.com\/modelcontextprotocol\/typescript-sdk\/blob\/main\/src\/client\/index.ts\">Client \ud074\ub798\uc2a4<\/a>\uac00 \ud3ec\ud568\ub418\uc5b4 \uc788\uae34 \ud558\uc9c0\ub9cc \uc774 \ud074\ub798\uc2a4\ub294 \ud558\ub098\uc758 Transport\uc640 \uc5f0\uacb0(connect)\ud558\ub3c4\ub85d \ub418\uc5b4 \uc788\uc5b4 \uc5ec\ub7ec \uac1c\uc758 Server\uc640 \uc5f0\uacb0 \ud558\uae30\uc5d0\ub294 \uc81c\uc57d\uc0ac\ud56d\uc774 \ub9ce\ub2e4. \ud2b9\ud788 \ud558\ub098\uc758 AI Agent\ub294 \uc5ec\ub7ec MCP Server\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ud234\uc744 \ud65c\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud558\ubbc0\ub85c <a href=\"https:\/\/github.com\/langchain-ai\/langchainjs\/tree\/main\/libs\/langchain-mcp-adapters\">Langchain Adapter<\/a>\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 <a href=\"https:\/\/github.com\/langchain-ai\/langchainjs\/blob\/main\/libs\/langchain-mcp-adapters\/src\/client.ts\"><code>MultiServerMCPClient<\/code> \ud074\ub798\uc2a4<\/a>\ub97c \uc774\uc6a9\ud558\uba74 \ud3b8\ub9ac\ud558\uac8c \uc774 \uc81c\uc57d\uc0ac\ud56d\uc5d0\uc11c \ubc97\uc5b4\ub0a0 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p>\uc608\uc81c\uc5d0\uc11c\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c OpenAI\uc758 LLM\uc744 \ud65c\uc6a9\ud558\ubbc0\ub85c <a href=\"https:\/\/platform.openai.com\/docs\/overview\">OpenAI Platform<\/a>\uc744 \ubc29\ubb38\ud55c \ud6c4 API Key\ub97c \uba3c\uc800 \ubc1c\uae09 \ubc1b\uc544\uc57c \ud55c\ub2e4. \ubc1c\uae09\ubc1b\uc740 API Key\ub294 \ucf58\uc194\uc744 \ud1b5\ud574 <code>OPENAI_API_KEY<\/code> \ud658\uacbd\ubcc0\uc218\ub85c \uc124\uc815\ud558\uba74 \ubc14\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ terminal console\nexport OPENAI_API_KEY=sk-bQn.....<\/code><\/pre>\n\n\n\n<p>\ucc38\uace0\ub85c, \uc544\ub798\uc640 \uac19\uc774 AI Agent \uc18c\uc2a4\ud30c\uc77c \uc0c1\ub2e8\uc5d0 \uae30\uc220\ud574\ub3c4 \ub418\uae34 \ud558\uc9c0\ub9cc \ubcf4\uc548\uc5d0 \ucde8\uc57d\ud558\ubbc0\ub85c \uc774 \ubc29\ubc95\uc740 \ub418\ub3c4\ub85d\uc774\uba74 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ inside source file\nprocess.env.OPENAI_API_KEY = 'sk-bQn..... ';<\/code><\/pre>\n\n\n\n<p>MCP\ub97c \ud65c\uc6a9\ud558\uc5ec AI Agent \ub97c \uac1c\ubc1c\ud560 \ub54c \uac00\uc7a5 \ud575\uc2ec\uc774 \ub418\ub294 \ubd80\ubd84\uc740 MCP Server\ub97c \uc9c0\uc815\ud558\ub294 \uac83\uc774\ub2e4. MCP Server\ub294 <code>MultiServerMCPClient<\/code> \uac1d\uccb4 \uc0dd\uc131 \uc2dc\uc810\uc5d0 \ud30c\ub77c\ubbf8\ud130\ub85c \uc9c0\uc815\ud558\uba70 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>const servers<\/strong> = {\n  throwOnLoadError: true,\n  prefixToolNameWithServerName: false,\n  additionalToolNamePrefix: '',\n  useStandardContentBlocks: true,\n\n  mcpServers: {\n    calculator: {\n      url: '<strong>http:\/\/localhost:3000\/mcp<\/strong>', \/\/ endpoint is '\/mcp', check out server's exposed endpoint\n      automaticSSEFallback: true\n    },\n    weather: {\n      url: '<strong>http:\/\/localhost:3100\/sse<\/strong>', \/\/ endpoint is '\/sse', check out server's exposed endpoint\n      automaticSSEFallback: true\n    }\n  }\n}\n\n<strong>const client = new MultiServerMCPClient(servers);<\/strong><\/code><\/pre>\n\n\n\n<p><code>mcpServers<\/code> \ud0a4\ub85c \uc124\uc815\ud558\uba70 \uc704 \ucf54\ub4dc\uc5d0\uc11c\uc640 \uac19\uc774 \ub2e4\uc218\uc758 MCP Server\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4. \uc55e\uc11c \ub9cc\ub4e0 MCP Server\uac00 localhost\uc758 \ud3ec\ud2b8 3000\uc5d0\uc11c \uc2e4\ud589\uc911\uc774\ub77c\uba74 \uc784\uc758\uc758 \uc774\ub984(<em>calculator<\/em>)\uc73c\ub85c RESTful API target url\uc744 \uc9c0\uc815\ud558\uba74 \ub41c\ub2e4.<\/p>\n\n\n\n<p>\uc5ec\ub7ec \uac1c\uc758 MCP Server\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\uc73c\ubbc0\ub85c \ub3d9\uc791 \ud655\uc778\uc744 \uc704\ud574 \uc0d8\ud50c\ub85c \ub0a0\uc528\ub97c \uc54c\ub824\uc8fc\ub294 \uac04\ub2e8\ud55c Mock MCP Server\ub97c \ud558\ub098 \ub354 \ub9cc\ub4e4\uace0 \uc774 \uc11c\ubc84\uc758 RESTful API target url\uc744 \uc9c0\uc815\ud558\uc600\ub2e4. \ucc38\uace0\ub85c \uc774 MCP Server\ub294 \ud504\ub85c\ud1a0\ucf5c \ud558\uc704\ud638\ud658 \ub3d9\uc791 \ud655\uc778\uc744 \uc704\ud574 MCP \ud504\ub85c\ud1a0\ucf5c \ucd08\uae30 \ubc84\uc804\uc73c\ub85c \uad6c\ud604\ud558\uc600\uc73c\uba70 \uc2e4\ud589\ud574 \ubcf4\uba74 \ud604\uc7ac \ubc84\uc804(ver 2025-06-18)\uacfc \ud638\ud658\uc774 \ub428\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \ub0a0\uc528\ub97c \uc54c\ub824\uc8fc\ub294 Mock MCP Server \uc18c\uc18c\ucf54\ub4dc\ub294 \uae00 \ub9c8\uc9c0\ub9c9\uc5d0 \ucd94\uac00\ud558\uc600\uc73c\ub2c8 \ucc38\uace0\ud558\uae30 \ubc14\ub780\ub2e4.<\/p>\n\n\n\n<p>\ub2e4\uc74c\uc73c\ub85c OpenAI API\ub97c \uc774\uc6a9\ud558\uc5ec LLM\uc744 \ub9cc\ub4e4\uace0, \uc55e\uc5d0\uc11c \uc0dd\uc131\ud55c <code>client<\/code> \uac1d\uccb4\ub97c \uc774\uc6a9\ud558\uc5ec \uc11c\ubc84\ub85c\ubd80\ud130 Tool\ub97c \uc5bb\uc5b4\uc628 \ub2e4\uc74c Langchain\uc758 <a href=\"https:\/\/v03.api.js.langchain.com\/functions\/langchain.agents.createReactAgent.html\"><code>createReactAgent()<\/code><\/a>\ub97c \uc774\uc6a9\ud558\uc5ec AI Agent\ub97c \uc0dd\uc131\ud55c\ub2e4. \uc5ec\uae30\uc11c \ud65c\uc6a9\ud55c LLM \ubaa8\ub378\uc740 &#8216;<code>gpt-4o<\/code>&#8216;\uc774\uba70 \uac04\uacb0\ud558\uace0 \uba85\ud655\ud55c \ub2f5\uc744 \uc5bb\uc5b4\uc57c \ud558\ubbc0\ub85c <code>temperature<\/code>\ub97c 0\uc73c\ub85c \uc124\uc815\ud558\uc600\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const tools = await client.getTools();\nconst llm = new ChatOpenAI({ modelName: 'gpt-4o', temperature: 0 });\nconst agent = createReactAgent({ llm, tools });<\/code><\/pre>\n\n\n\n<p>\uc644\uc804\ud55c \uc18c\uc2a4\ucf54\ub4dc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. \uc18c\uc2a4\ucf54\ub4dc \uc911 MCP Server\uc5d0 \ub4f1\ub85d\ub41c Resource\ub97c \uac00\uc838\uc624\ub294 \ubd80\ubd84\uc744 \ucd94\uac00\ub294 \ud588\uc9c0\ub9cc \uad6c\uccb4\uc801 \ud65c\uc6a9 \uc2dc\ub098\ub9ac\uc624\uac00 \uc5c6\uc73c\ubbc0\ub85c \ucc38\uace0 \uc6a9\ub3c4\ub85c\ub9cc \ubcf4\uae30 \ubc14\ub780\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { ChatOpenAI } from '@langchain\/openai';\nimport { createReactAgent } from '@langchain\/langgraph\/prebuilt';\nimport { HumanMessage, AIMessage } from '@langchain\/core\/messages';\nimport { MultiServerMCPClient } from '@langchain\/mcp-adapters';\nimport { stdin as input, stdout as output } from 'node:process';\nimport * as readline from 'node:readline\/promises';\n\nconst servers = {\n  throwOnLoadError: true,\n  prefixToolNameWithServerName: false,\n  additionalToolNamePrefix: '',\n  useStandardContentBlocks: true,\n\n  mcpServers: {\n    calculator: {\n      url: 'http:\/\/localhost:3000\/mcp', \/\/ endpoint is '\/mcp', check out server's exposed endpoint\n      automaticSSEFallback: true\n    },\n    weather: {\n      url: 'http:\/\/localhost:3100\/sse', \/\/ endpoint is '\/sse', check out server's exposed endpoint\n      automaticSSEFallback: true\n    }\n  }\n}\n\nconst rl = readline.createInterface({ input, output });\nconst conversation = &#91;];\n\nconst client = new MultiServerMCPClient(servers);\nconst tools = await client.getTools();\nconsole.log('Tools available from servers are: ');\nfor (const { name, description } of tools) {\n  console.log(`\\t- ${name}: ${description}`);\n}\n\n\/\/ examples for fetching a resource from calculator server\nconst calc = await client.getClient('calculator');\nconst resource = await calc.readResource({uri: 'greeting:\/\/skanto'});\nconsole.log('resource: \\n', resource);\n\nconst llm = new ChatOpenAI({ modelName: 'gpt-4o', temperature: 0 });\nconst agent = createReactAgent({ llm, tools });\nconsole.log(`\\nAgent is ready. Type your message or 'exit' to quit.\\n`);\n\n\/\/ handle prompts user inputs\nwhile (true) {\n  const prompt = await rl.question('Your question: ');\n  if (!prompt.trim()) continue;\n  if (prompt.toLowerCase() === 'exit') break;\n\n  conversation.push(new HumanMessage(prompt));\n  console.log('Agent thinking...\\n');\n\n  try {\n    const { messages } = await agent.invoke({ messages: conversation });\n    let { content } = messages.pop(); \/\/ last item of messages array\n    if (typeof content === 'object')  content = JSON.stringify(content);\n\n    console.log('Agent: ', content, '\\n');\n    conversation.push(new AIMessage(content));\n  } catch (err) {\n    console.error('Agent error: ', err.message);\n  }\n}\n\nrl.close();\nawait client.close();\nconsole.log('Disconnected from MCP server');\nconsole.log('Chatting with agent is terminated.');<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Executing Scenarios<\/h2>\n\n\n\n<p>\uc774\uc81c \uc55e\uc5d0\uc11c \uc791\uc131\ud588\ub358 MCP Server\uc640 AI Agent\ub97c \uc2e4\ud589\ud55c \ud6c4 \uc608\uc0c1\ud588\ub358 \ub300\ub85c \uc0ac\uc6a9\uc790\uac00 \uc785\ub825\ud55c \ud504\ub86c\ud504\ud2b8\uc758 \ucee8\ud14d\uc2a4\ud2b8\uc5d0 \ub530\ub77c \ud574\ub2f9 \ud234\uc774 \uc2e4\ud589\ub418\ub294\uc9c0 \ud655\uc778\ud574 \ubcf4\uc790<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Run MCP Server<\/h3>\n\n\n\n<p>\uba3c\uc800 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uce59\uc5f0\uc0b0 MCP Server\uc640 \ub0a0\uc528 \uc608\ubcf4 MCP Server\ub97c \uac01\uac01 \ub2e4\ub978 PORT(<em>3000, 3100<\/em>)\ub85c \uc2e4\ud589\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@4d1382e3b115:\/home\/node\/mcp# node MCP_Calc_Server.mjs \nMCP Server is listening on port 3000<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>root@4d1382e3b115:\/home\/node\/mcp# node MCP_Weather_Server.mjs \nTool registeration completed!\nMCP Server is listening on port 3100<\/code><\/pre>\n\n\n\n<p>\uc704\uc640 \uac19\uc740 \uacb0\uacfc\uac00 \ucd9c\ub825\ub418\uc5c8\ub2e4\uba74 \ub450 MCP Server\ub294 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\uace0 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Run AI Agent<\/h3>\n\n\n\n<p>\uc774\uc81c \uc55e\uc5d0\uc11c \uc791\uc131\ud55c AI Agent \ud504\ub85c\uadf8\ub7a8\uc744 \uc2e4\ud589\ud558\uba74 \uc544\ub798\uc640 \uac19\uc740 \uacb0\uacfc\uac00 \ucd9c\ub825\ub420 \uac83\uc774\ub2e4. MCP Server\uc5d0 \ub4f1\ub85d\ub41c Tool(<em>3\uac00\uc9c0<\/em>)\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub3c4\ub85d \ub85c\uadf8 \uba54\uc2dc\uc9c0\ub97c \ucd94\uac00 \ud558\uc600\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@4d1382e3b115:\/home\/node\/mcp# node client.mjs \nTools available from servers are: \n\t- add: Add two numbers\n\t- multiply: Multiply two numbers\n\t- forecast: Forecast weather of a city on a specific date\nresource: \n { contents: &#91; { uri: 'greeting:\/\/skanto', text: 'Hello, skanto!' } ] }\n\nAgent is ready. Type your message or 'exit' to quit.\n\nYour question: <\/code><\/pre>\n\n\n\n<p>\uc774\ub54c MCP Server \ub4e4\uc740 Hand shaking \uacfc\uc815\uc5d0\uc11c \uac01\uac01 \uc544\ub798\uc640 \uac19\uc740 \uacb0\uacfc\ub97c \ucd9c\ub825\ud560 \uac83\uc774\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@4d1382e3b115:\/home\/node\/mcp# node MCP_Calc_Server.mjs \nMCP Server is listening on port 3000\nRequest body: {\n  method: 'initialize',\n  params: {\n    protocolVersion: '2025-06-18',\n    capabilities: {},\n    clientInfo: { name: 'langchain-mcp-adapter', version: '0.1.0' }\n  },\n  jsonrpc: '2.0',\n  id: 0\n}\nTools and Resources are registered!\nSession initialized with ID: bb2d3083-77fe-4c7e-b7da-8e9d1ca0e280\nServer is connected with StreamableHTTPServerTransport!\n\nReceived MCP request for session: bb2d3083-77fe-4c7e-b7da-8e9d1ca0e280 { method: 'notifications\/initialized', jsonrpc: '2.0' }\nEstablishing new SSE stream for session bb2d3083-77fe-4c7e-b7da-8e9d1ca0e280\nReceived MCP request for session: bb2d3083-77fe-4c7e-b7da-8e9d1ca0e280 { method: 'tools\/list', params: {}, jsonrpc: '2.0', id: 1 }\nReceived MCP request for session: bb2d3083-77fe-4c7e-b7da-8e9d1ca0e280 {\n  method: 'resources\/read',\n  params: { uri: 'greeting:\/\/skanto' },\n  jsonrpc: '2.0',\n  id: 2\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>root@4d1382e3b115:\/home\/node\/mcp# node MCP_Weather_Server.mjs \nTool registeration completed!\nMCP Server is listening on port 3100\nServer is connected with SSEServerTransport!\nReceived MCP request for session: 355b6ca1-ec94-4a4e-97c0-a9c5ac8fe984 {\n  method: 'initialize',\n  params: {\n    protocolVersion: '2025-06-18',\n    capabilities: {},\n    clientInfo: { name: 'langchain-mcp-adapter', version: '0.1.0' }\n  },\n  jsonrpc: '2.0',\n  id: 0\n}\nReceived MCP request for session: 355b6ca1-ec94-4a4e-97c0-a9c5ac8fe984 { method: 'notifications\/initialized', jsonrpc: '2.0' }\nReceived MCP request for session: 355b6ca1-ec94-4a4e-97c0-a9c5ac8fe984 { method: 'tools\/list', params: {}, jsonrpc: '2.0', id: 1 }<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ud504\ub86c\ud504\ud2b8\ub97c \uc774\uc6a9\ud55c \ub3d9\uc791 \ud655\uc778<\/h3>\n\n\n\n<p>AI Agent \ud504\ub86c\ud504\ud2b8\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc740 \ub0b4\uc6a9\uc744 \uc785\ub825\ud574 \ubcf4\uba74 AI\uac00 \uad00\ub828\ub41c \ud234\uc744 \uc2e4\ud589\ud558\uace0 \uadf8 \uacb0\uacfc\ub97c \uc54c\ub824 \uc900\ub2e4. \uc5ec\uae30\uc11c \ub208\uc5ec\uaca8 \ubcfc \ub9cc\ud55c \ubd80\ubd84\uc740 \ud504\ub86c\ud504\ud2b8\uc5d0 \ub450 \uac00\uc9c0 \ub2f5\uc744 \uc694\uad6c\ud558\ub294 \ud504\ub86c\ud504\ud2b8\ub97c \uc785\ub825\ud558\ub354\ub77c\ub3c4 \uc815\uc0c1\uc801\uc778 \ub2f5\uc744 \ucd9c\ub825\ud55c\ub2e4. \uc989, \ud558\ub098\uc758 \ud504\ub86c\ud504\ud2b8\ub85c \uac01\uac01 \uc11c\ub85c \ub2e4\ub978 MCP Server\uc758 \ud234\uc744 \uc2e4\ud589\ud558\uace0 \uadf8 \uacb0\uacfc\ub97c AI Agent\uac00 \ucde8\ud569\ud574\uc11c \uacb0\uacfc\ub85c \ubcf4\uc5ec \uc900\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Your question: What is the result if you add two numbers 22 and 33\nAgent thinking...\n\nAgent:  The result of adding 22 and 33 is 55. \n\nYour question: \uc624\ub298\uc740 7\uc6d4 29\uc77c\uc774\uc57c \ub0b4\uc77c \uc11c\uc6b8\uc758 \ub0a0\uc528\ub294 \uc5b4\ub584?\nAgent thinking...\n\nAgent:  \ub0b4\uc77c \uc11c\uc6b8\uc758 \ub0a0\uc528\ub294 \ub9d1\uace0 \ub365\uc2b5\ub2c8\ub2e4. \n\nYour question: 34\uc640 77\uc744 \uacf1\ud558\uace0 \ubaa8\ub808\uc758 \ub0a0\uc528\ub3c4 \uc54c\ub824\uc918\nAgent thinking...\n\nAgent:  34\uc640 77\uc744 \uacf1\ud558\uba74 2618\uc785\ub2c8\ub2e4. \ubaa8\ub808 \uc11c\uc6b8\uc758 \ub0a0\uc528\ub294 \ub9d1\uace0 \ub365\uc2b5\ub2c8\ub2e4. \n\nYour question: <\/code><\/pre>\n\n\n\n<p>\uc785\ub825\ud55c \uc5b8\uc5b4\uc5d0 \ub530\ub77c \uc801\uc808\ud558\uac8c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc8fc\ub294 \uac83\ub3c4 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \uc774\ub54c \uac01\uac01\uc758 MCP Server\uc5d0\uc11c\ub294 \uc5b4\ub5a4 \ub3d9\uc791\ud588\ub294\uc9c0 \ub85c\uadf8 \uba54\uc2dc\uc9c0\ub97c \ud655\uc778\ud574 \ubcf4\uba74 \uc544\ub798\uc640 \uac19\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Received MCP request for session: 96032a11-533a-4938-9319-5648a804f687 {\n  method: 'resources\/read',\n  params: { uri: 'greeting:\/\/skanto' },\n  jsonrpc: '2.0',\n  id: 2\n}\nReceived MCP request for session: 96032a11-533a-4938-9319-5648a804f687 {\n  method: 'tools\/call',\n  params: { name: 'add', arguments: { a: 22, b: 33 } },\n  jsonrpc: '2.0',\n  id: 3\n}\nReceived MCP request for session: 96032a11-533a-4938-9319-5648a804f687 {\n  method: 'tools\/call',\n  params: { name: 'multiply', arguments: { a: 34, b: 77 } },\n  jsonrpc: '2.0',\n  id: 5\n}\nexecutes operation 34 * 77<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Received MCP request for session: 50ba8f5e-1660-4275-a8f4-9cc0608ee6af { method: 'tools\/list', params: {}, jsonrpc: '2.0', id: 1 }\nReceived MCP request for session: 50ba8f5e-1660-4275-a8f4-9cc0608ee6af {\n  method: 'tools\/call',\n  params: { name: 'forecast', arguments: { city: '\uc11c\uc6b8', date: '2023-07-30' } },\n  jsonrpc: '2.0',\n  id: 2\n}\nforecast weather of \uc11c\uc6b8 on 2023-07-30\nReceived MCP request for session: 50ba8f5e-1660-4275-a8f4-9cc0608ee6af {\n  method: 'tools\/call',\n  params: { name: 'forecast', arguments: { city: '\uc11c\uc6b8', date: '2023-07-31' } },\n  jsonrpc: '2.0',\n  id: 3\n}\nforecast weather of \uc11c\uc6b8 on 2023-07-31<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">MCP Server &#8211; \ub0a0\uc528 \uc608\ubcf4 Mock \ud234<\/h3>\n\n\n\n<p>\uc774 \uc608\uc81c\ub294 MCP \ud504\ub85c\ud1a0\ucf5c \ucd08\uae30\ubc84\uc804\uc758 \ud558\uc704 \ud638\ud658\uc744 \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uc791\uc131\ud558\uc600\uc73c\ub2c8 \ucc38\uace0\uc6a9\uc73c\ub85c\ub9cc \ud65c\uc6a9\ud558\uace0 \uc2e4\uc81c AI Agent\uac1c\ubc1c\uc5d0\ub294 \ub418\ub3c4\ub85d\uc774\uba74 \ucd5c\uc2e0 \ubc84\uc804\uc758 \ud504\ub85c\ud1a0\ucf5c\uacfc SDK\ub97c \ud65c\uc6a9\ud558\uae30 \ubc14\ub780\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import express from 'express';\nimport { McpServer } from '@modelcontextprotocol\/sdk\/server\/mcp.js';\nimport { SSEServerTransport } from '@modelcontextprotocol\/sdk\/server\/sse.js';\nimport { z } from 'zod';\nimport cors from 'cors';\n\n\/\/EP: EndPoint for each target functionality\nconst &#91;SSE_EP, MSG_EP] = &#91;'\/sse', '\/messages'];\nconst PORT = 3100; \/\/ server listening port\n\nconst server = new McpServer({ name: 'weather-server', version: '1.0.0' });\nserver.registerTool('forecast', {\n  title: 'Weather Forecast Tool',\n  description: 'Forecast weather of a city on a specific date',\n  inputSchema: { city: z.string(), date: z.string() }\n}, async ({ city, date }) =&gt; {\n  console.log(`forecast weather of ${city} on ${date}`);\n  return { content: &#91;{ type: 'text', text: 'the weather is sunny and hot temperature' }] };\n});\nconsole.log('Tool registeration completed!');\n\nconst transports = { };\nconst app = express();\napp.use(express.json());\n\n\/** handle GET request for SSE endpoint *\/\napp.get(SSE_EP, async (req, res) =&gt; {\n  const transport = new SSEServerTransport(MSG_EP, res);\n  transports&#91;transport.sessionId] = transport;\n  res.on('close', () =&gt; {\n    delete transports&#91;transport.sessionId];\n  });\n  await server.connect(transport);\n  console.log('Server is connected with SSEServerTransport!');\n});\n\n\/** handle POST request for message endpoint *\/\napp.post(MSG_EP, async (req, res) =&gt; {\n  const sessionId = req.query.sessionId;\n  const transport = transports&#91;sessionId];\n  if (transport) {\n    const msg = (sessionId) ? `Received MCP request for session: ${sessionId}`: 'Request body:';\n    console.log(msg, req.body);\n    await transport.handlePostMessage(req, res, req.body);\n  } else {\n    console.error('No transport found for sessionId: ', sessionId);\n    res.status(400).send('No transport found for sessionId');\n  }\n});\n\n\/\/ start server\napp.listen(PORT, () =&gt; {\n  console.log(`MCP Server is listening on port ${PORT}`);\n});<\/code><\/pre>\n\n\n\n<p>\ub05d.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc694\uc998 AI \uac1c\ubc1c\uc5d0 \ub300\ud574 \uc598\uae30\ud558\uc790\uba74 MCP\ub97c \ube7c\ub193\uace0 \uc598\uae30\ud560 \uc218 \uc5c6\ub2e4. LLM\uc774 \ub098\uc624\uba74\uc11c AI\uac00 \ubaa8\ub4e0 \uac83\uc744 \ubc14\uafd4 \ubc84\ub9b4 \uac83\uc774\ub77c\ub294 \uc6b0\ub824\uac00 \uc788\uc5c8\uc9c0\ub9cc \ub9c9\uc0c1 Chatbot\uc218\uc900\uc758 \uc815\ubcf4\ub97c \uc5bb\ub294 \uac83 \ub9d0\uace0\ub294 \ud65c\uc6a9 \uac00\uce58\uac00 \uadf8\ub9ac \ud06c\uc9c0 \uc54a\uc558\ub2e4. \ud558\uc9c0\ub9cc Antropic\uc5d0\uc11c MCP\uaddc\uaca9(2024.11)\uc744 \ub0b4 \ub193\uc73c\uba74\uc11c \uae30\ub958\ub294 \ud06c\uac8c \ubc14\ub00c\uc5c8\ub2e4. LLM\uc774 \uc778\uacf5\uc9c0\ub2a5 \uc989, \ub450\ub1cc \uc5ed\ud560\uc744 \ub2f4\ub2f9\ud588\ub2e4\uba74 MCP\ub294 \uc774 \ub450\ub1cc\uc5d0 \ud314\uacfc \ub2e4\ub9ac\ub97c \ub2ec\uc544\uc8fc\uc5c8\uae30 \ub54c\ubb38\uc774\ub2e4. \uacb0\uad6d \uc0ac\ub78c\uc774 AI\uc5d0\uac8c \ub9d0\uc744 \uac74\ub124\uba74 AI\ub294 \uadf8 \ub9d0\ub97c \uc774\ud574\ud558\uace0 \uc2e4\uc81c \ub3c4\uc6c0\uc774 \ub418\ub294 \ud589\ub3d9\uc744 \ud560 \uc218 \uc788\uac8c \ub41c \uc148\uc774\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 MCP\uac00 \ubb34\uc5c7\uc778\uc9c0 \uaddc\uaca9(Specification)\uc704\uc8fc\ub85c \uac04\ub7b5\ud558\uac8c \uc124\uba85\ud558\uace0 Langchain MCP Adapter\uc640&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/skanto.co.kr\/?p=2532\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[14],"tags":[218,228,236,213],"class_list":["post-2532","post","type-post","status-publish","format-standard","hentry","category-sw-development","tag-a-i","tag-langchain","tag-langgraph","tag-mcp"],"_links":{"self":[{"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/2532","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2532"}],"version-history":[{"count":48,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/2532\/revisions"}],"predecessor-version":[{"id":2591,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/2532\/revisions\/2591"}],"wp:attachment":[{"href":"https:\/\/skanto.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2532"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2532"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/skanto.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}