Buckets:

hf-doc-build/doc-dev / context-course /pr_7 /en /unit2 /building-servers.html
download
raw
57.1 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Building MCP Servers with Python&quot;,&quot;local&quot;:&quot;building-mcp-servers-with-python&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Setting Up FastMCP&quot;,&quot;local&quot;:&quot;setting-up-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Creating Your First Server with FastMCP&quot;,&quot;local&quot;:&quot;creating-your-first-server-with-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;More Complex Tools with Parameters&quot;,&quot;local&quot;:&quot;more-complex-tools-with-parameters&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Adding Resources to Your Server&quot;,&quot;local&quot;:&quot;adding-resources-to-your-server&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Adding Prompts&quot;,&quot;local&quot;:&quot;adding-prompts&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Error Handling in FastMCP&quot;,&quot;local&quot;:&quot;error-handling-in-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Testing Your Server Locally&quot;,&quot;local&quot;:&quot;testing-your-server-locally&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Run the server directly&quot;,&quot;local&quot;:&quot;run-the-server-directly&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;MCP Inspector (recommended)&quot;,&quot;local&quot;:&quot;mcp-inspector-recommended&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Gradio MCP Integration&quot;,&quot;local&quot;:&quot;gradio-mcp-integration&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Key Takeaways&quot;,&quot;local&quot;:&quot;key-takeaways&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/context-course/pr_7/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/entry/start.55c3acaa.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/scheduler.4048030c.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/singletons.42509544.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/index.dd3f5310.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/paths.f6762227.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/entry/app.10ec5479.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/preload-helper.665302cf.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/index.5d0b9360.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/nodes/0.b63aa764.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/nodes/10.53fff320.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.99c2e6c8.js">
<link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/CodeBlock.ff2a3276.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Building MCP Servers with Python&quot;,&quot;local&quot;:&quot;building-mcp-servers-with-python&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Setting Up FastMCP&quot;,&quot;local&quot;:&quot;setting-up-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Creating Your First Server with FastMCP&quot;,&quot;local&quot;:&quot;creating-your-first-server-with-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;More Complex Tools with Parameters&quot;,&quot;local&quot;:&quot;more-complex-tools-with-parameters&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Adding Resources to Your Server&quot;,&quot;local&quot;:&quot;adding-resources-to-your-server&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Adding Prompts&quot;,&quot;local&quot;:&quot;adding-prompts&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Error Handling in FastMCP&quot;,&quot;local&quot;:&quot;error-handling-in-fastmcp&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Testing Your Server Locally&quot;,&quot;local&quot;:&quot;testing-your-server-locally&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Run the server directly&quot;,&quot;local&quot;:&quot;run-the-server-directly&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;MCP Inspector (recommended)&quot;,&quot;local&quot;:&quot;mcp-inspector-recommended&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Gradio MCP Integration&quot;,&quot;local&quot;:&quot;gradio-mcp-integration&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Key Takeaways&quot;,&quot;local&quot;:&quot;key-takeaways&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="building-mcp-servers-with-python" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#building-mcp-servers-with-python"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Building MCP Servers with Python</span></h1> <p data-svelte-h="svelte-12vwtcv">With the architecture in hand, this lesson builds real servers — first with the FastMCP SDK for lightweight servers, then with Gradio for servers that come with a web UI.</p> <iframe src="https://context-course-mcp-transports.static.hf.space" frameborder="0" width="850" height="450"></iframe> <h2 class="relative group"><a id="setting-up-fastmcp" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#setting-up-fastmcp"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Setting Up FastMCP</span></h2> <p data-svelte-h="svelte-178yg6d">FastMCP is the easiest way to build MCP servers. Install it with:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->pip install <span class="hljs-string">&quot;mcp[cli]&quot;</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-fl0izw">The <code>mcp</code> package includes the FastMCP SDK; the <code>[cli]</code> extra adds the <code>mcp</code> command used for testing further down.</p> <h2 class="relative group"><a id="creating-your-first-server-with-fastmcp" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#creating-your-first-server-with-fastmcp"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Creating Your First Server with FastMCP</span></h2> <p data-svelte-h="svelte-gc5dap">Let’s build a simple calculator server. Create <code>calculator_server.py</code>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> mcp.server.fastmcp <span class="hljs-keyword">import</span> FastMCP
mcp = FastMCP(<span class="hljs-string">&quot;calculator&quot;</span>)
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Add two numbers together.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> a + b
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">multiply</span>(<span class="hljs-params">a: <span class="hljs-built_in">int</span>, b: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Multiply two numbers together.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> a * b
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
mcp.run()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-13qxpgx">FastMCP automatically:</p> <ul data-svelte-h="svelte-o7a1c3"><li>Infers parameter types from function signatures</li> <li>Generates JSON schemas from docstrings</li> <li>Creates tool descriptions from function docstrings</li> <li>Uses stdio transport by default</li> <li>Handles the JSON-RPC protocol for you</li></ul> <p data-svelte-h="svelte-vg7em0">Run it:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->python calculator_server.py<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-loip7i">The server listens on stdin/stdout for JSON-RPC requests.</p> <h2 class="relative group"><a id="more-complex-tools-with-parameters" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#more-complex-tools-with-parameters"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>More Complex Tools with Parameters</span></h2> <p data-svelte-h="svelte-izwww9">Let’s build a tool that reads and analyzes files:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> mcp.server.fastmcp <span class="hljs-keyword">import</span> FastMCP
<span class="hljs-keyword">import</span> os
mcp = FastMCP(<span class="hljs-string">&quot;file-analyzer&quot;</span>)
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">read_file</span>(<span class="hljs-params">path: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Read the contents of a file.
Args:
path: The absolute file path to read
Returns:
The file contents as a string
&quot;&quot;&quot;</span>
<span class="hljs-keyword">try</span>:
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(path, <span class="hljs-string">&#x27;r&#x27;</span>) <span class="hljs-keyword">as</span> f:
<span class="hljs-keyword">return</span> f.read()
<span class="hljs-keyword">except</span> FileNotFoundError:
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Error: File not found at <span class="hljs-subst">{path}</span>&quot;</span>
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Error reading file: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>&quot;</span>
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">count_lines</span>(<span class="hljs-params">path: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Count the number of lines in a file.
Args:
path: The absolute file path
Returns:
The number of lines in the file
&quot;&quot;&quot;</span>
<span class="hljs-keyword">try</span>:
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(path, <span class="hljs-string">&#x27;r&#x27;</span>) <span class="hljs-keyword">as</span> f:
<span class="hljs-keyword">return</span> <span class="hljs-built_in">len</span>(f.readlines())
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
<span class="hljs-keyword">return</span> -<span class="hljs-number">1</span>
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">list_directory</span>(<span class="hljs-params">path: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">list</span>[<span class="hljs-built_in">str</span>]:
<span class="hljs-string">&quot;&quot;&quot;List files in a directory.
Args:
path: The directory path
Returns:
A list of file names in the directory
&quot;&quot;&quot;</span>
<span class="hljs-keyword">try</span>:
<span class="hljs-keyword">return</span> os.listdir(path)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
<span class="hljs-keyword">return</span> []
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
mcp.run()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1ooaz34">Key features:</p> <ul data-svelte-h="svelte-1h9llj1"><li><strong>Docstrings become descriptions</strong> — The first line is the tool description; additional sections describe parameters</li> <li><strong>Type hints enable validation</strong> — Parameters are automatically validated based on types</li> <li><strong>Error handling</strong> — Return meaningful error messages instead of raising exceptions</li> <li><strong>Return types</strong> — FastMCP infers what results to return</li></ul> <h2 class="relative group"><a id="adding-resources-to-your-server" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#adding-resources-to-your-server"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Adding Resources to Your Server</span></h2> <p data-svelte-h="svelte-labbge">Resources provide read-only data. Use the <code>@mcp.resource()</code> decorator:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> mcp.server.fastmcp <span class="hljs-keyword">import</span> FastMCP
mcp = FastMCP(<span class="hljs-string">&quot;documentation&quot;</span>)
<span class="hljs-comment"># Define resources</span>
<span class="hljs-meta">@mcp.resource(<span class="hljs-params"><span class="hljs-string">&quot;doc://api/overview&quot;</span></span>)</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">api_overview</span>() -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;API overview and getting started guide.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;&quot;&quot;# API Overview
This API provides tools for user management, data querying, and report generation.
## Getting Started
1. Authenticate with your API token
2. Call endpoints with appropriate parameters
3. Handle responses and errors gracefully
## Rate Limits
- 100 requests per minute per API key
- Burst limit: 10 requests per second
&quot;&quot;&quot;</span>
<span class="hljs-meta">@mcp.resource(<span class="hljs-params"><span class="hljs-string">&quot;doc://api/endpoints&quot;</span></span>)</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">api_endpoints</span>() -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Complete list of API endpoints.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;&quot;&quot;# API Endpoints
## Users
- GET /users - List all users
- POST /users - Create a user
- GET /users/{id} - Get a specific user
- PUT /users/{id} - Update a user
## Data
- POST /query - Execute a database query
- GET /data/{id} - Retrieve data
## Reports
- GET /reports - List reports
- POST /reports - Generate a report
&quot;&quot;&quot;</span>
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_api_status</span>() -&gt; <span class="hljs-built_in">dict</span>:
<span class="hljs-string">&quot;&quot;&quot;Check the current API status.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> {
<span class="hljs-string">&quot;status&quot;</span>: <span class="hljs-string">&quot;operational&quot;</span>,
<span class="hljs-string">&quot;uptime_percent&quot;</span>: <span class="hljs-number">99.99</span>,
<span class="hljs-string">&quot;response_time_ms&quot;</span>: <span class="hljs-number">45</span>
}
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
mcp.run()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1plfg5n">Resources:</p> <ul data-svelte-h="svelte-16secqa"><li>Are identified by URIs (e.g., <code>doc://api/overview</code>)</li> <li>Return static or semi-static content</li> <li>Can be text, JSON, or any string content</li> <li>Don’t require parameters (unlike tools)</li> <li>Are always available to agents</li></ul> <h2 class="relative group"><a id="adding-prompts" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#adding-prompts"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Adding Prompts</span></h2> <p data-svelte-h="svelte-1ahdyhq">Prompts are instruction templates that guide agent behavior:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> mcp.server.fastmcp <span class="hljs-keyword">import</span> FastMCP
mcp = FastMCP(<span class="hljs-string">&quot;prompts-server&quot;</span>)
<span class="hljs-meta">@mcp.prompt()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">code_review_prompt</span>(<span class="hljs-params">language: <span class="hljs-built_in">str</span> = <span class="hljs-string">&quot;python&quot;</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Template for reviewing code in a specific language.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;&quot;&quot;You are an expert <span class="hljs-subst">{language}</span> code reviewer.
Analyze the provided code and provide feedback on:
1. Correctness and logic
2. Performance and efficiency
3. Code style and readability
4. Security implications
5. Testing coverage
Be constructive and suggest improvements.&quot;&quot;&quot;</span>
<span class="hljs-meta">@mcp.prompt()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">security_audit_prompt</span>() -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Template for security audits.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;&quot;&quot;Conduct a security audit of the provided code or system. Check for:
1. Authentication vulnerabilities
2. Authorization issues
3. Data validation gaps
4. SQL injection or injection attacks
5. Insecure dependencies
6. Sensitive information exposure
Rate each finding by severity (critical, high, medium, low).&quot;&quot;&quot;</span>
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_available_prompts</span>() -&gt; <span class="hljs-built_in">list</span>[<span class="hljs-built_in">str</span>]:
<span class="hljs-string">&quot;&quot;&quot;List available prompt templates.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> [<span class="hljs-string">&quot;code_review_prompt&quot;</span>, <span class="hljs-string">&quot;security_audit_prompt&quot;</span>]
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
mcp.run()<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="error-handling-in-fastmcp" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#error-handling-in-fastmcp"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Error Handling in FastMCP</span></h2> <p data-svelte-h="svelte-kv27su">Handle errors gracefully by returning error messages:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> mcp.server.fastmcp <span class="hljs-keyword">import</span> FastMCP
mcp = FastMCP(<span class="hljs-string">&quot;safe-operations&quot;</span>)
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">divide</span>(<span class="hljs-params">numerator: <span class="hljs-built_in">float</span>, denominator: <span class="hljs-built_in">float</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Divide two numbers.
Args:
numerator: The dividend
denominator: The divisor
Returns:
The quotient or an error message
&quot;&quot;&quot;</span>
<span class="hljs-keyword">try</span>:
<span class="hljs-keyword">if</span> denominator == <span class="hljs-number">0</span>:
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Error: Cannot divide by zero&quot;</span>
result = numerator / denominator
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Result: <span class="hljs-subst">{result}</span>&quot;</span>
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Error: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>&quot;</span>
<span class="hljs-meta">@mcp.tool()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">parse_json</span>(<span class="hljs-params">data: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Parse a JSON string.
Args:
data: JSON string to parse
Returns:
Parsed JSON or error message
&quot;&quot;&quot;</span>
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">try</span>:
parsed = json.loads(data)
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Valid JSON: <span class="hljs-subst">{parsed}</span>&quot;</span>
<span class="hljs-keyword">except</span> json.JSONDecodeError <span class="hljs-keyword">as</span> e:
<span class="hljs-keyword">return</span> <span class="hljs-string">f&quot;Invalid JSON: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>&quot;</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
mcp.run()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1d7misi">Best practices:</p> <ul data-svelte-h="svelte-oj1vzh"><li>Return error messages instead of raising exceptions</li> <li>Include helpful context in error messages</li> <li>Validate input parameters before using them</li> <li>Log failures for debugging</li></ul> <h2 class="relative group"><a id="testing-your-server-locally" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#testing-your-server-locally"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Testing Your Server Locally</span></h2> <h3 class="relative group"><a id="run-the-server-directly" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#run-the-server-directly"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Run the server directly</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->python calculator_server.py<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-fu8e0s">This starts the server on stdio. You can send JSON-RPC messages on stdin, but it’s usually easier to use one of the inspectors below.</p> <h3 class="relative group"><a id="mcp-inspector-recommended" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#mcp-inspector-recommended"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>MCP Inspector (recommended)</span></h3> <p data-svelte-h="svelte-1mc8ou6">The official inspector is a web UI that connects to any MCP server and lets you call tools, read resources, and fetch prompts.</p> <p data-svelte-h="svelte-rxp6b3">Using the <code>mcp</code> CLI from <code>mcp[cli]</code>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->mcp dev calculator_server.py<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-ok50l4">Or run the inspector directly with npx:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->npx @modelcontextprotocol/inspector python calculator_server.py<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-besu9n">Both open the inspector in your browser and connect it to the server over stdio.</p> <h2 class="relative group"><a id="gradio-mcp-integration" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#gradio-mcp-integration"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Gradio MCP Integration</span></h2> <p data-svelte-h="svelte-2g7osb">FastMCP is the better default when you want a pure MCP server. Gradio is useful when you want the same functions to be usable by both agents and humans in a browser.</p> <p data-svelte-h="svelte-1ywgbwm">Install Gradio with MCP support:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->pip install <span class="hljs-string">&quot;gradio[mcp]&quot;</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-kgm108">Create a Gradio app with MCP:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> gradio <span class="hljs-keyword">as</span> gr
<span class="hljs-keyword">def</span> <span class="hljs-title function_">letter_counter</span>(<span class="hljs-params">word: <span class="hljs-built_in">str</span>, letter: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">int</span>:
<span class="hljs-string">&quot;&quot;&quot;Count occurrences of a letter in text.
Args:
word: The input text
letter: The letter to search for
Returns:
The count of the letter
&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> word.lower().count(letter.lower())
<span class="hljs-keyword">def</span> <span class="hljs-title function_">reverse_text</span>(<span class="hljs-params">text: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">str</span>:
<span class="hljs-string">&quot;&quot;&quot;Reverse a string.
Args:
text: The input text
Returns:
The reversed text
&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> text[::-<span class="hljs-number">1</span>]
<span class="hljs-comment"># Create UI</span>
<span class="hljs-keyword">with</span> gr.Blocks() <span class="hljs-keyword">as</span> demo:
<span class="hljs-keyword">with</span> gr.Tab(<span class="hljs-string">&quot;Letter Counter&quot;</span>):
word_input = gr.Textbox(label=<span class="hljs-string">&quot;Enter text&quot;</span>)
letter_input = gr.Textbox(label=<span class="hljs-string">&quot;Enter letter&quot;</span>)
count_output = gr.Number(label=<span class="hljs-string">&quot;Count&quot;</span>)
gr.Button(<span class="hljs-string">&quot;Count&quot;</span>).click(letter_counter, [word_input, letter_input], count_output)
<span class="hljs-keyword">with</span> gr.Tab(<span class="hljs-string">&quot;Text Reversal&quot;</span>):
text_input = gr.Textbox(label=<span class="hljs-string">&quot;Enter text&quot;</span>)
reversed_output = gr.Textbox(label=<span class="hljs-string">&quot;Reversed&quot;</span>)
gr.Button(<span class="hljs-string">&quot;Reverse&quot;</span>).click(reverse_text, [text_input], reversed_output)
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
demo.launch(mcp_server=<span class="hljs-literal">True</span>)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1k8gljj">Launch with <code>mcp_server=True</code> to automatically:</p> <ul data-svelte-h="svelte-1k4yqgv"><li>Convert functions into MCP tools</li> <li>Create a web UI at <code>http://localhost:7860</code></li> <li>Expose an MCP endpoint at <code>http://localhost:7860/gradio_api/mcp/</code></li> <li>Handle JSON-RPC serialization automatically</li></ul> <p data-svelte-h="svelte-11nl4z7">Your functions are now both web UI components AND MCP tools.</p> <blockquote class="note" data-svelte-h="svelte-u0nhro"><p>Exposing tools through a UI is useful because:</p> <ul><li>Non-agent users can interact with the same functions in a browser</li> <li>You get a quick human test harness for the tools</li></ul> <p>Agent-only setups do <strong>not</strong> require UI.</p></blockquote> <p data-svelte-h="svelte-10rgdeh">For <code>@gr.mcp.resource()</code>, <code>@gr.api()</code>, deployment, and authentication details, continue to the dedicated Gradio lesson next. This page only needs the core idea: <code>mcp_server=True</code> turns the same functions into both browser handlers and MCP tools.</p> <h2 class="relative group"><a id="key-takeaways" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#key-takeaways"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Key Takeaways</span></h2> <p data-svelte-h="svelte-culr3k">FastMCP turns docstrings into tool descriptions and type hints into JSON schemas. Tools are callable functions, resources expose read-only data through URIs, and prompts serve as instruction templates. Finish the pure-server path first: add error handling, test locally, and only then decide whether you want a browser UI. If you do, Gradio adds one with <code>mcp_server=True</code>, and the next lesson goes deeper on Gradio-specific MCP features.</p> <p data-svelte-h="svelte-1i7ojcg">Next we’ll point our agents at these servers.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/context-course/blob/main/units/en/unit2/building-servers.mdx" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_ck2jc = {
assets: "/docs/context-course/pr_7/en",
base: "/docs/context-course/pr_7/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/context-course/pr_7/en/_app/immutable/entry/start.55c3acaa.js"),
import("/docs/context-course/pr_7/en/_app/immutable/entry/app.10ec5479.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 10],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
57.1 kB
·
Xet hash:
0f673c8d0b0cf43c2cea58f4939f783c59403b7ef78bae257c0ee435167db51c

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.