<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SRKDAN</title>
    <description>The latest articles on DEV Community by SRKDAN (@srkdan_writes).</description>
    <link>https://dev.to/srkdan_writes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4176699%2Fd31ed5b4-4bdd-4cf1-9329-0570d85200b6.png</url>
      <title>DEV Community: SRKDAN</title>
      <link>https://dev.to/srkdan_writes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/srkdan_writes"/>
    <language>en</language>
    <item>
      <title>What is MCP? Build and call your first remote MCP tool in 15 minutes</title>
      <dc:creator>SRKDAN</dc:creator>
      <pubDate>Mon, 12 Oct 2026 12:38:34 +0000</pubDate>
      <link>https://dev.to/srkdan_writes/what-is-mcp-build-and-call-your-first-remote-mcp-tool-in-15-minutes-jep</link>
      <guid>https://dev.to/srkdan_writes/what-is-mcp-build-and-call-your-first-remote-mcp-tool-in-15-minutes-jep</guid>
      <description>&lt;p&gt;&lt;em&gt;AI-assisted draft. I wrote and verified the code against the current MCP docs and Python SDK.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;MCP (Model Context Protocol) is an open standard for connecting AI apps to external systems. Think of it like USB-C for AI: one shape of plug for tools, data, and workflows, instead of a custom integration for every host.&lt;/p&gt;

&lt;p&gt;If you have used Claude Desktop, Cursor, VS Code, or ChatGPT with connectors, you have already seen the client side. This post focuses on the server side: a tiny remote tool you can run locally, then call from a real MCP client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three building blocks
&lt;/h2&gt;

&lt;p&gt;An MCP server can expose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; - functions the model can call (search, create a ticket, generate an image).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; - read-only data the app can pull in as context (files, schemas, docs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt; - reusable templates the user picks on purpose.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most first servers start with tools. That is what we will build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local vs remote transport
&lt;/h2&gt;

&lt;p&gt;How the bytes move is the &lt;em&gt;transport&lt;/em&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Transport&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;When to use it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stdio&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host launches your process and talks over stdin/stdout&lt;/td&gt;
&lt;td&gt;Local servers on one machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;streamable-http&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A normal HTTP endpoint (default path &lt;code&gt;/mcp&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Anything you deploy or call over the network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;sse&lt;/code&gt; (old HTTP+SSE)&lt;/td&gt;
&lt;td&gt;Deprecated remote transport&lt;/td&gt;
&lt;td&gt;Only for older clients. Do not build new servers on it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Streamable HTTP replaced the older HTTP+SSE transport in the 2025-03-26 protocol revision. New remote servers should expose one MCP endpoint (for example &lt;code&gt;https://your-host/mcp&lt;/code&gt;) that accepts client POSTs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.11+&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; (or pip)&lt;/li&gt;
&lt;li&gt;About 15 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Scaffold a tiny server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv init greeter
&lt;span class="nb"&gt;cd &lt;/span&gt;greeter
uv venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
uv add &lt;span class="s2"&gt;"mcp[cli]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;server.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPServer&lt;/span&gt;

&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greeter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return a short greeting for the given name.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Streamable HTTP: clients hit http://127.0.0.1:3001/mcp
&lt;/span&gt;    &lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streamable-http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# Stateless + JSON is a simple default for a first remote server
&lt;/span&gt;        &lt;span class="n"&gt;stateless_http&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;json_response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes that trip people up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transport options (&lt;code&gt;host&lt;/code&gt;, &lt;code&gt;port&lt;/code&gt;, &lt;code&gt;stateless_http&lt;/code&gt;, …) go on &lt;code&gt;run()&lt;/code&gt;, not on &lt;code&gt;MCPServer(...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;stdio&lt;/code&gt; servers, never write to stdout (&lt;code&gt;print&lt;/code&gt; is unsafe). Use &lt;code&gt;logging&lt;/code&gt; to stderr. For HTTP servers, normal stdout logging is fine.&lt;/li&gt;
&lt;li&gt;The default MCP path is &lt;code&gt;/mcp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have &lt;code&gt;http://127.0.0.1:3001/mcp&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Call the tool from a Python client
&lt;/h2&gt;

&lt;p&gt;In another terminal (same venv, or another project with &lt;code&gt;mcp&lt;/code&gt; installed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:3001/mcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;listed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;listed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;greet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dev.to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="c1"&gt;# Simple string tools often expose structured_content;
&lt;/span&gt;        &lt;span class="c1"&gt;# otherwise inspect result.content for text blocks.
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;structured_content&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A URL string is treated as Streamable HTTP by the Python client. That is the remote path. For local stdio servers you would pass launch parameters instead of a URL.&lt;/p&gt;

&lt;p&gt;Expected shape of the happy path: &lt;code&gt;list_tools&lt;/code&gt; shows &lt;code&gt;greet&lt;/code&gt;, and &lt;code&gt;call_tool&lt;/code&gt; returns something like &lt;code&gt;Hello, Dev.to!&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Point a real host at it
&lt;/h2&gt;

&lt;p&gt;Hosts differ in UI, but the idea is the same: give them the MCP URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude (Custom Connector):&lt;/strong&gt; Settings → Connectors → Add custom connector → paste &lt;code&gt;http://127.0.0.1:3001/mcp&lt;/code&gt; (for a public server, use your HTTPS URL). Complete any auth the server asks for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor / VS Code-style config&lt;/strong&gt; often looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"greeter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:3001/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exact keys vary by client version. Prefer the client's current docs over screenshots from early 2025 tutorials, which still show &lt;code&gt;/sse&lt;/code&gt; endpoints.&lt;/p&gt;

&lt;p&gt;For a &lt;em&gt;local&lt;/em&gt; stdio server instead, the config uses &lt;code&gt;command&lt;/code&gt; + &lt;code&gt;args&lt;/code&gt; so the host can spawn your process. Remotes use a URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Smoke-test with the Inspector
&lt;/h2&gt;

&lt;p&gt;The MCP Inspector is the fastest way to see tools without wiring a full chat UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run mcp dev server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That path is aimed at stdio servers. For an already-running Streamable HTTP server, open the Inspector UI and connect to &lt;code&gt;http://127.0.0.1:3001/mcp&lt;/code&gt; as an HTTP / Streamable HTTP target. List tools, call &lt;code&gt;greet&lt;/code&gt;, confirm the text result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Building on SSE-only &lt;code&gt;/sse&lt;/code&gt; URLs.&lt;/strong&gt; That is the deprecated remote transport. Prefer &lt;code&gt;/mcp&lt;/code&gt; Streamable HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Putting &lt;code&gt;port=&lt;/code&gt; on &lt;code&gt;MCPServer(...)&lt;/code&gt;.&lt;/strong&gt; It belongs on &lt;code&gt;run(...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Printing to stdout on a stdio server.&lt;/strong&gt; Corrupts JSON-RPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copying 2024 client snippets.&lt;/strong&gt; Many still assume initialize/session headers that newer protocol revisions changed. Check the &lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;current MCP docs&lt;/a&gt; and the &lt;a href="https://py.sdk.modelcontextprotocol.io/v2/run/" rel="noopener noreferrer"&gt;Python SDK run guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What to build next
&lt;/h2&gt;

&lt;p&gt;Swap &lt;code&gt;greet&lt;/code&gt; for a real tool: wrap an internal API, return a resource URI for docs, or add a prompt template for a workflow your team repeats. Keep tools small and typed. Prefer one clear job per tool over a mega-tool with a dozen modes.&lt;/p&gt;

&lt;p&gt;If you ship the server beyond localhost, put it behind HTTPS, require auth (API key or OAuth), and turn on the SDK's transport security options before you expose it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;MCP intro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/develop/build-server" rel="noopener noreferrer"&gt;Build an MCP server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/develop/connect-remote-servers" rel="noopener noreferrer"&gt;Connect to remote MCP servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://py.sdk.modelcontextprotocol.io/v2/run/" rel="noopener noreferrer"&gt;Python SDK: Running your server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://py.sdk.modelcontextprotocol.io/client/transports/" rel="noopener noreferrer"&gt;Python SDK: Client transports&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Questions or corrections welcome in the comments. Protocol details move; if something here diverges from the live docs, trust the docs.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>api</category>
      <category>python</category>
    </item>
  </channel>
</rss>
