<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hu Jin]]></title><description><![CDATA[Hu Jin]]></description><link>https://whoai.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 05 Nov 2026 07:55:12 GMT</lastBuildDate><atom:link href="https://whoai.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building Your First MCP Server: A Step-by-Step Guide]]></title><description><![CDATA[AI assistants are great at reasoning over what you give them, but out of the box they can't see your database, your files, or your internal APIs. For a…]]></description><link>https://whoai.hashnode.dev/building-your-first-mcp-server-a-step-by-step-guide</link><guid isPermaLink="true">https://whoai.hashnode.dev/building-your-first-mcp-server-a-step-by-step-guide</guid><category><![CDATA[AI]]></category><category><![CDATA[mcp]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Hu Jin]]></dc:creator><pubDate>Wed, 04 Nov 2026 21:40:18 GMT</pubDate><content:encoded><![CDATA[<p>AI assistants are great at reasoning over what you give them, but out of the box they can't see your database, your files, or your internal APIs. For a long time, every tool integration was custom glue code written for one model and one app. The Model Context Protocol (MCP) fixes that with one open standard: build a tool once as an MCP server, and any MCP-compatible client can use it.</p>
<p>This guide explains what MCP is, why it matters, and how to build and connect your first server. As in my previous article, we'll go in small steps and verify each one before moving on.</p>
<h2>What is MCP?</h2>
<p>MCP is an open protocol, introduced by Anthropic, that defines how an AI application (the <strong>client</strong>) talks to an external program (the <strong>server</strong>) that exposes capabilities. A server can offer three kinds of things:</p>
<ul>
<li><strong>Tools</strong>: functions the model can call, like "search orders" or "create ticket".</li>
<li><strong>Resources</strong>: read-only data the model can load, like files or database records.</li>
<li><strong>Prompts</strong>: reusable prompt templates.</li>
</ul>
<p>Client and server exchange JSON-RPC messages, either over <strong>stdio</strong> (the client launches the server as a local process) or over <strong>HTTP</strong> for remote servers.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae9f3d1eac8486c74422bf9/0c64d43b-12ed-42b3-9c9b-c5fd483b0c82.png" alt="MCP architecture: client, server, tools and data sources" style="display:block;margin:0 auto" />

<p>Here is what a single tool call looks like end to end:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae9f3d1eac8486c74422bf9/87f2da3d-0a22-4f68-a16c-4263cd637011.png" alt="" style="display:block;margin:0 auto" />

<p>Why it matters for AI tooling</p>
<ul>
<li><strong>Build once, use everywhere.</strong> The same server works in any client that speaks MCP.</li>
<li><strong>Clear boundaries.</strong> The model only sees what your server exposes, and you control the code that touches real systems.</li>
<li><strong>Composable.</strong> A client can connect to several servers at once: one for GitHub, one for your database, one for internal docs.</li>
<li><strong>Less glue code.</strong> You write plain functions; the SDK handles the protocol.</li>
</ul>
<h2>Step 1: Decide what your server exposes</h2>
<p>Before writing code, write down, in a short list:</p>
<ul>
<li>The 1 to 3 tools you need, with inputs and outputs.</li>
<li>What data the tools may read or change, and what they must never do.</li>
<li>2 or 3 real requests a user might make, and the result you expect. These are your acceptance tests.</li>
</ul>
<p>For this guide we'll build a tiny server with two tools: <code>add</code> (adds two numbers) and <code>get_weather_note</code> (returns a canned note for a city). Simple on purpose, so we can focus on the protocol.</p>
<h2>Step 2: Set up the project</h2>
<p>We'll use the official Python SDK.</p>
<pre><code class="language-bash">mkdir my-first-mcp &amp;&amp; cd my-first-mcp
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install "mcp[cli]"
</code></pre>
<p>Verify the install before going further:</p>
<pre><code class="language-bash">python -c "import mcp; print('ok')"
</code></pre>
<h2>Step 3: Write the server, one tool at a time</h2>
<p>Create <code>server.py</code> with just one tool first:</p>
<pre><code class="language-python">from mcp.server.fastmcp import FastMCP

mcp = FastMCP("my-first-mcp")

@mcp.tool()
def add(a: int, b: int) -&gt; int:
    """Add two numbers and return the sum."""
    return a + b

if __name__ == "__main__":
    mcp.run()  # uses stdio by default
</code></pre>
<p>The function's type hints and docstring become the tool's schema and description, which is what the model reads to decide when to call it. Write the docstring for the model, clearly.</p>
<h2>Step 4: Test it before connecting any AI</h2>
<p>The SDK ships with a development inspector:</p>
<pre><code class="language-bash">mcp dev server.py
</code></pre>
<p>This opens the MCP Inspector, where you can list the tools and call <code>add</code> with test inputs. Only move on when <code>add(2, 3)</code> returns <code>5</code>.</p>
<p>Now add the second tool:</p>
<pre><code class="language-python">@mcp.tool()
def get_weather_note(city: str) -&gt; str:
    """Return a short demo weather note for a city."""
    return f"Demo note: it's a nice day in {city}."
</code></pre>
<p>Run the inspector again and test it. One tool, one test, every time.</p>
<h2>Step 5: Connect it to an AI client</h2>
<p><strong>Claude Desktop.</strong> Add your server to Claude Desktop's config file (<code>claude_desktop_config.json</code>):</p>
<pre><code class="language-json">{
  "mcpServers": {
    "my-first-mcp": {
      "command": "/full/path/to/my-first-mcp/.venv/bin/python",
      "args": ["/full/path/to/my-first-mcp/server.py"]
    }
  }
}
</code></pre>
<p>Restart Claude Desktop, and the tools appear. Ask "What is 17 plus 25? Use the add tool." and check that it calls your server.</p>
<p><strong>Grok and other clients.</strong> Any assistant or agent framework that supports MCP connects the same way: either it launches your server locally over stdio, or you deploy the server over HTTP and give the client its URL. Check your client's documentation for how it registers MCP servers; the server code doesn't change.</p>
<h2>Step 6: Loop until your acceptance tests pass</h2>
<p>Go back to the requests you wrote in Step 1. Run each one through the client. If the model picks the wrong tool or passes bad arguments, the fix is usually a clearer docstring or tighter parameter types. Adjust, retest, repeat.</p>
<h2>Tips before going to production</h2>
<ul>
<li><strong>Least privilege.</strong> Give the server only the permissions it needs; prefer read-only tools until you trust the flow.</li>
<li><strong>Validate inputs.</strong> Treat everything the model sends as untrusted user input.</li>
<li><strong>Log every call.</strong> You'll want to see what the model asked for and what your server did.</li>
<li><strong>Keep secrets out of tool output.</strong> Anything a tool returns goes into the model's context.</li>
</ul>
<h2>The key principle</h2>
<p>Same as with any AI-assisted build: <strong>don't try to build the whole thing at once.</strong> Define a small set of tools, add them one at a time, test each in the inspector, then connect a client and verify with real requests.</p>
<hr />
<p>MCP turns "integrate this model with our system" into "write a few well-described functions." Start with one tool, get it working end to end, and grow from there.</p>
<hr />
<h2>About the author</h2>
<p>I write about Applied AI, MCP, Azure AI Search, and RAG. Follow me on <a href="https://dev.to/who_ai">Dev.to</a> and <a href="https://hashnode.com/@whoai">Hashnode</a> for more.</p>
]]></content:encoded></item><item><title><![CDATA[From Requirements Doc to Working Code with Grok: Azure AI Search Integrated with a SQL Database]]></title><description><![CDATA[The most common mistake people make with AI coding assistants is asking for the whole project at once: "Build me the entire thing." You get a pile of code…]]></description><link>https://whoai.hashnode.dev/from-requirements-doc-to-working-code-with-grok-azure-ai-search-integrated-with-a-sql-database</link><guid isPermaLink="true">https://whoai.hashnode.dev/from-requirements-doc-to-working-code-with-grok-azure-ai-search-integrated-with-a-sql-database</guid><category><![CDATA[Azure]]></category><category><![CDATA[AI]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[SQL]]></category><dc:creator><![CDATA[Hu Jin]]></dc:creator><pubDate>Tue, 03 Nov 2026 14:51:47 GMT</pubDate><content:encoded><![CDATA[<p>The most common mistake people make with AI coding assistants is asking for the whole project at once: "Build me the entire thing." You get a pile of code that doesn't run, and when it breaks you have no idea where to look. The better approach is small steps with verification: write clear requirements, have the AI produce a plan, then build one small piece at a time and run each piece before moving on.</p>
<p>Here's the workflow I actually use, with integrating a SQL database into Azure AI Search as the example.</p>
<h2>The workflow at a glance</h2>
<img src="https://cdn.hashnode.com/uploads/covers/6ae9f3d1eac8486c74422bf9/c0acb092-b400-4eb8-8de8-810e8e18990e.png" alt="Grok workflow from requirements doc to working code" style="display:block;margin:0 auto" />

<h2>Step 1: Prepare the requirements document</h2>
<p>It doesn't need to be long, but these four sections must be clear.</p>
<p><strong>1. Data Source</strong></p>
<ul>
<li>Which SQL database, and whether it's accessed through a connection string or a managed identity.</li>
<li>Which tables and fields get synced into the index.</li>
<li>Which fields stay out of the index and are only used to fetch full records back from the database.</li>
</ul>
<p><strong>2. Retrieval Requirements</strong></p>
<ul>
<li>Query type: keyword, semantic, vector, or a combination.</li>
<li>How many results each query returns.</li>
<li>Whether matching snippets should be highlighted.</li>
</ul>
<p><strong>3. Sync Strategy</strong></p>
<ul>
<li>Full sync or incremental sync.</li>
<li>How often it refreshes.</li>
<li>Who triggers it: a schedule, data changes, or a manual run.</li>
</ul>
<p><strong>4. Acceptance Criteria</strong></p>
<ul>
<li>Write down 3 to 5 real questions and the result you expect for each.</li>
<li>This is your pass standard: the feature is done only when all of them return the right results.</li>
</ul>
<h2>Step 2: Upload the doc and ask for a plan, not code</h2>
<p>Upload the requirements document to Grok and say explicitly: "Don't write any code yet. Give me a phased implementation plan."</p>
<p>Review the plan yourself. Are the phases sensible? Is anything missing, like sync or permissions? Is the order right? Ask it to adjust until you're happy with the plan.</p>
<h2>Step 3: Write the code one small piece at a time</h2>
<p>Following the plan, ask Grok for just one small piece at a time, such as "create the index schema" or "set up the data source connection."</p>
<p>Run it right away. If it errors, paste the full error back and have it fix it. If it works, paste the result back too, then move on to the next piece.</p>
<h2>Step 4: Loop until everything is checked off</h2>
<p>Repeat Step 3, checking off each feature in the plan. Finally, run the acceptance questions from Step 1 one by one. You're done only when they all pass.</p>
<h2>The key principle</h2>
<p><strong>Never let it generate the whole project at once.</strong> Small steps that can be verified and rolled back at any point are what make AI-assisted coding both fast and reliable.</p>
<h2>The Azure AI Search + SQL architecture</h2>
<ul>
<li><strong>Azure AI Search is the retrieval layer.</strong> It handles keyword, semantic, and vector search.</li>
<li><strong>The SQL database is the storage layer.</strong> It holds the complete, authoritative data.</li>
<li><strong>Azure Data Factory or Synapse</strong> syncs SQL data into the Search index.</li>
<li>At query time, search in Azure AI Search first, take the IDs from the results, then use those IDs to fetch the full records from SQL.</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/6ae9f3d1eac8486c74422bf9/0186442b-4957-4300-b477-4b25cf9c44fd.png" alt="Azure AI Search + SQL architecture" style="display:block;margin:0 auto" />

<p>You get a strong search experience while keeping a single source of truth in the database.</p>
<h2>Recommendation: use text embeddings</h2>
<p>Add text vector fields to your index. Azure AI Search has a built-in embedding skill that generates vector fields automatically while the index is created and data is imported, so you get vector and hybrid search without deploying or running a model yourself.</p>
<hr />
<p>Write clear requirements, get a plan first, code in small steps, and verify each one. Follow that workflow and your AI coding assistant will actually help you finish the project, instead of handing you a pile of code that won't run.</p>
]]></content:encoded></item></channel></rss>