<?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[AI Agents]]></title><description><![CDATA[AI Agents]]></description><link>https://aiagentsworld.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 11 Sep 2026 21:40:48 GMT</lastBuildDate><atom:link href="https://aiagentsworld.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Zomato x A2A: The Google Way of Agent Talk]]></title><description><![CDATA[🧠 Why Even Tech Giants Feel FOMO (And Why Agents Are the Future)
You know what's common in startups, developers, and even tech giants?FOMO. Fear of missing out on the next big thing.
And right now, that "big thing" is AI agents.
Ever since Anthropic...]]></description><link>https://aiagentsworld.hashnode.dev/zomato-x-a2a-the-google-way-of-agent-talk</link><guid isPermaLink="true">https://aiagentsworld.hashnode.dev/zomato-x-a2a-the-google-way-of-agent-talk</guid><category><![CDATA[ai agents]]></category><category><![CDATA[A2A]]></category><category><![CDATA[mcp]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Shayan Danish]]></dc:creator><pubDate>Mon, 14 Apr 2025 18:25:30 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-why-even-tech-giants-feel-fomo-and-why-agents-are-the-future">🧠 Why Even Tech Giants Feel FOMO (And Why Agents Are the Future)</h2>
<p>You know what's common in startups, developers, and even tech giants?<br /><strong>FOMO.</strong> Fear of missing out on the next big thing.</p>
<p>And right now, that <strong>"big thing" is AI agents.</strong></p>
<p>Ever since <strong>Anthropic released MCP</strong>, the landscape started shifting. Now even <strong>Google</strong> is deep-diving into agentic workflows. Why?</p>
<p>Because no one wants to be late to the <strong>Agent Party</strong>. 🎉</p>
<hr />
<p>Let’s break it down with a fun analogy. 🍕</p>
<hr />
<h3 id="heading-meet-the-characters">Meet the Characters</h3>
<p>Imagine you're using <strong>Zomato</strong> and you say:</p>
<blockquote>
<p><em>"Hey, I want to have some pizza."</em></p>
</blockquote>
<p>Zomato is smart now — it’s powered by an AI <strong>agent</strong>.<br />But here's the thing:</p>
<p>👉 Zomato <strong>cannot directly talk</strong> to PizzaHut’s database.<br />👉 Nor can it contact McDee’s secret sauce (MongoDB).</p>
<p>So, what does it do?</p>
<hr />
<h3 id="heading-enter-mcp-amp-a2a-the-real-mvps">Enter MCP &amp; A2A: The Real MVPs</h3>
<ul>
<li><p><strong>MCP (Model Context Protocol)</strong> is how agents talk to their <strong>own data</strong> — like ordering from their own kitchen.</p>
</li>
<li><p><strong>A2A (Agent-to-Agent)</strong> is how they talk to <strong>each other</strong> — like calling PizzaHut and McDee for collaboration.</p>
</li>
</ul>
<p>Here’s how it looks visually:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744654502152/2d29e5a9-25ab-4f3d-81f9-4ffdfa3683a9.png" alt class="image--center mx-auto" /></p>
<hr />
<h3 id="heading-behind-the-scenes">Behind the Scenes</h3>
<ul>
<li><p>PizzaHut’s agent connects to a PostgreSQL database via <strong>MCP</strong>.</p>
</li>
<li><p>McDee’s agent uses <strong>MCP</strong> to access MongoDB.</p>
</li>
<li><p>Zomato’s agent, powered by Kafka + Postgres, says:</p>
<blockquote>
<p><em>“Hey PizzaHut Agent, what pizzas do you have?”</em><br /><em>“Hey McDee Agent, any burgers to go with it?”</em></p>
</blockquote>
</li>
</ul>
<p>All this through <strong>A2A protocol</strong>. Smooth, secure, and scalable.</p>
<hr />
<h3 id="heading-the-future-is-inter-agent">The Future is Inter-Agent</h3>
<p>Today, everyone’s building apps.<br />Tomorrow, you’ll be building <strong>agents that talk to each other</strong>.</p>
<p>This isn’t just integration.<br />It’s <strong>cooperation.</strong><br />And MCP + A2A is how they pull it off.</p>
<hr />
<h3 id="heading-final-thought">Final Thought</h3>
<p>Zomato never directly talks to PizzaHut.<br />It respects boundaries.<br />But with A2A, they’re still besties. 🧑‍🤝‍🧑</p>
<p>And that’s the future of composable, intelligent systems.</p>
<hr />
<p>Want to build your own agents?<br />Start with MCP.<br />Level up with A2A.</p>
<p>Because FOMO isn't just for devs. Even Zomato doesn’t wanna miss that pizza party. 🍕</p>
<hr />
<h5 id="heading-i-post-regular-content-on-ai-agents-mcp-and-the-agentic-future">🧠 I post regular content on <strong>AI Agents, MCP, and the agentic future</strong> —</h5>
<p><strong>Subscribe</strong> so you don’t miss the next big thing in this evolving ecosystem!</p>
<p>📩 Got questions or ideas?<br />Reach out at <strong>shayan.developer12@gmail.com</strong> — always happy to connect!</p>
]]></content:encoded></item><item><title><![CDATA[Forget Claude Desktop: Build Your Own Custom AI Agent with MCP Client + Server]]></title><description><![CDATA[This is a simplified implementation of the official ModelContextProtocol SDK, aimed at helping developers quickly understand how LLM agents (like Claude) can reason, invoke tools, and interpret the results — step by step.
Unlike most tutorials that r...]]></description><link>https://aiagentsworld.hashnode.dev/forget-claude-desktop-build-your-own-custom-ai-agent-with-mcp-client-server</link><guid isPermaLink="true">https://aiagentsworld.hashnode.dev/forget-claude-desktop-build-your-own-custom-ai-agent-with-mcp-client-server</guid><category><![CDATA[mcp server]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[AI]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[claude.ai]]></category><category><![CDATA[Claude 3]]></category><category><![CDATA[#anthropic]]></category><category><![CDATA[anthropic/claude-3.5-sonnet:beta]]></category><dc:creator><![CDATA[Shayan Danish]]></dc:creator><pubDate>Fri, 28 Mar 2025 19:31:12 GMT</pubDate><content:encoded><![CDATA[<p>This is a <strong>simplified implementation of the official ModelContextProtocol SDK</strong>, aimed at helping developers quickly understand how LLM agents (like Claude) can reason, invoke tools, and interpret the results — <strong>step by step</strong>.</p>
<p>Unlike most tutorials that rely on Claude Desktop, I built my own MCP client from scratch using the official MCP SDK and Anthropic’s Claude API. This gave me full control and flexibility to customize behavior, tool invocation, and responses—exactly how real AI agents should work.</p>
<hr />
<h2 id="heading-what-youll-build">🌟 What You'll Build</h2>
<p>You’ll build an AI agent that:</p>
<p>✅ Understands natural queries like</p>
<blockquote>
<p>“What’s the weather in Florida?”</p>
</blockquote>
<p>✅ Uses Claude as the LLM<br />✅ Invokes <strong>custom tools</strong> via MCP (e.g. <code>get-alerts</code>, <code>get-forecast</code>)<br />✅ Works locally using <code>Node.js</code>, TypeScript, and Open Tool Protocols<br />✅ Looks like a CLI but works like an agent 🤖</p>
<hr />
<h2 id="heading-final-project-structure">📁 Final Project Structure</h2>
<pre><code class="lang-javascript">mcp-ai-agents/
├── mcp-client-typescript/
│   ├── index.ts
│   ├── tsconfig.json
│   └── package.json
├── weather/
│   ├── src/
│   │   └── index.ts
│   ├── tsconfig.json
│   └── package.json
</code></pre>
<hr />
<h2 id="heading-step-1-setup-the-mcp-client-claude-agent">✅ Step 1: Setup the MCP Client (Claude Agent)</h2>
<h3 id="heading-11-create-the-client-directory">1.1 Create the Client Directory</h3>
<pre><code class="lang-javascript">mkdir mcp-ai-agents
cd mcp-ai-agents
mkdir mcp-client-typescript
cd mcp-client-typescript
</code></pre>
<h3 id="heading-12-initialize-and-install-dependencies">1.2 Initialize and Install Dependencies</h3>
<pre><code class="lang-javascript">npm init -y
npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv
npm install -D typescript @types/node
</code></pre>
<h3 id="heading-13-add-basic-setup-files">1.3 Add Basic Setup Files</h3>
<pre><code class="lang-javascript">touch index.ts
touch .env
</code></pre>
<p><code>.env</code> content:</p>
<pre><code class="lang-javascript">ANTHROPIC_API_KEY=sk-xxx-your-anthropic-key
</code></pre>
<hr />
<h3 id="heading-14-configure-typescript">1.4 Configure TypeScript</h3>
<h4 id="heading-tsconfigjson"><code>tsconfig.json</code>:</h4>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"compilerOptions"</span>: {
    <span class="hljs-string">"target"</span>: <span class="hljs-string">"ES2022"</span>,
    <span class="hljs-string">"module"</span>: <span class="hljs-string">"Node16"</span>,
    <span class="hljs-string">"moduleResolution"</span>: <span class="hljs-string">"Node16"</span>,
    <span class="hljs-string">"outDir"</span>: <span class="hljs-string">"./build"</span>,
    <span class="hljs-string">"rootDir"</span>: <span class="hljs-string">"./"</span>,
    <span class="hljs-string">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"skipLibCheck"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"forceConsistentCasingInFileNames"</span>: <span class="hljs-literal">true</span>
  },
  <span class="hljs-string">"include"</span>: [<span class="hljs-string">"index.ts"</span>],
  <span class="hljs-string">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<h4 id="heading-packagejson-add-type-and-scripts"><code>package.json</code> (add <code>"type"</code> and <code>"scripts"</code>)</h4>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"module"</span>,
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"tsc &amp;&amp; chmod 755 build/index.js"</span>
  }
}
</code></pre>
<hr />
<h3 id="heading-15-mcp-client-code-indexts">1.5 MCP Client Code (<code>index.ts</code>)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Anthropic } <span class="hljs-keyword">from</span> <span class="hljs-string">"@anthropic-ai/sdk"</span>;
<span class="hljs-keyword">import</span> {
  MessageParam,
  Tool,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@anthropic-ai/sdk/resources/messages/messages.mjs"</span>;
<span class="hljs-keyword">import</span> { Client } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/client/index.js"</span>;
<span class="hljs-keyword">import</span> { StdioClientTransport } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/client/stdio.js"</span>;
<span class="hljs-keyword">import</span> readline <span class="hljs-keyword">from</span> <span class="hljs-string">"readline/promises"</span>;
<span class="hljs-keyword">import</span> dotenv <span class="hljs-keyword">from</span> <span class="hljs-string">"dotenv"</span>;

dotenv.config();

<span class="hljs-keyword">const</span> ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
<span class="hljs-keyword">if</span> (!ANTHROPIC_API_KEY) {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"ANTHROPIC_API_KEY is not set"</span>);
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MCPClient</span> </span>{
  private mcp: Client;
  private anthropic: Anthropic;
  private transport: StdioClientTransport | <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;
  private tools: Tool[] = [];

  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.anthropic = <span class="hljs-keyword">new</span> Anthropic({ <span class="hljs-attr">apiKey</span>: ANTHROPIC_API_KEY });
    <span class="hljs-built_in">this</span>.mcp = <span class="hljs-keyword">new</span> Client({ <span class="hljs-attr">name</span>: <span class="hljs-string">"mcp-client-cli"</span>, <span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span> });
  }

  <span class="hljs-keyword">async</span> connectToServer(serverScriptPath: string) {
    <span class="hljs-keyword">const</span> command = serverScriptPath.endsWith(<span class="hljs-string">".py"</span>)
      ? process.platform === <span class="hljs-string">"win32"</span> ? <span class="hljs-string">"python"</span> : <span class="hljs-string">"python3"</span>
      : process.execPath;

    <span class="hljs-built_in">this</span>.transport = <span class="hljs-keyword">new</span> StdioClientTransport({ command, <span class="hljs-attr">args</span>: [serverScriptPath] });
    <span class="hljs-built_in">this</span>.mcp.connect(<span class="hljs-built_in">this</span>.transport);

    <span class="hljs-keyword">const</span> toolsResult = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.mcp.listTools();
    <span class="hljs-built_in">this</span>.tools = toolsResult.tools.map(<span class="hljs-function">(<span class="hljs-params">tool</span>) =&gt;</span> ({
      <span class="hljs-attr">name</span>: tool.name,
      <span class="hljs-attr">description</span>: tool.description,
      <span class="hljs-attr">input_schema</span>: tool.inputSchema,
    }));
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"✅ Connected to server with tools:"</span>, <span class="hljs-built_in">this</span>.tools.map(<span class="hljs-function"><span class="hljs-params">t</span> =&gt;</span> t.name));
  }

  <span class="hljs-keyword">async</span> processQuery(query: string) {
    <span class="hljs-keyword">const</span> messages: MessageParam[] = [{ <span class="hljs-attr">role</span>: <span class="hljs-string">"user"</span>, <span class="hljs-attr">content</span>: query }];
    <span class="hljs-keyword">const</span> finalText = [];

    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.anthropic.messages.create({
      <span class="hljs-attr">model</span>: <span class="hljs-string">"claude-3-5-sonnet-20241022"</span>,
      <span class="hljs-attr">max_tokens</span>: <span class="hljs-number">1000</span>,
      messages,
      <span class="hljs-attr">tools</span>: <span class="hljs-built_in">this</span>.tools,
    });

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> content <span class="hljs-keyword">of</span> response.content) {
      <span class="hljs-keyword">if</span> (content.type === <span class="hljs-string">"text"</span>) {
        finalText.push(content.text);
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (content.type === <span class="hljs-string">"tool_use"</span>) {
        <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.mcp.callTool({
          <span class="hljs-attr">name</span>: content.name,
          <span class="hljs-attr">arguments</span>: content.input <span class="hljs-keyword">as</span> object,
        });

        finalText.push(<span class="hljs-string">`[Calling tool <span class="hljs-subst">${content.name}</span> with args <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(content.input)}</span>]`</span>);

        messages.push({ <span class="hljs-attr">role</span>: <span class="hljs-string">"user"</span>, <span class="hljs-attr">content</span>: result.content <span class="hljs-keyword">as</span> string });

        <span class="hljs-keyword">const</span> followUp = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.anthropic.messages.create({
          <span class="hljs-attr">model</span>: <span class="hljs-string">"claude-3-5-sonnet-20241022"</span>,
          <span class="hljs-attr">max_tokens</span>: <span class="hljs-number">1000</span>,
          messages,
        });

        finalText.push(
          followUp.content[<span class="hljs-number">0</span>].type === <span class="hljs-string">"text"</span> ? followUp.content[<span class="hljs-number">0</span>].text : <span class="hljs-string">""</span>
        );
      }
    }

    <span class="hljs-keyword">return</span> finalText.join(<span class="hljs-string">"\n"</span>);
  }

  <span class="hljs-keyword">async</span> chatLoop() {
    <span class="hljs-keyword">const</span> rl = readline.createInterface({ <span class="hljs-attr">input</span>: process.stdin, <span class="hljs-attr">output</span>: process.stdout });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\n🤖 MCP Client Started!\n(Type 'quit' to exit)"</span>);

    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">const</span> message = <span class="hljs-keyword">await</span> rl.question(<span class="hljs-string">"\nQuery: "</span>);
      <span class="hljs-keyword">if</span> (message.toLowerCase() === <span class="hljs-string">"quit"</span>) <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.processQuery(message);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\n"</span> + response);
    }

    rl.close();
  }

  <span class="hljs-keyword">async</span> cleanup() {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.mcp.close();
  }
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> mcpClient = <span class="hljs-keyword">new</span> MCPClient();
  <span class="hljs-keyword">const</span> scriptPath = process.argv[<span class="hljs-number">2</span>];
  <span class="hljs-keyword">if</span> (!scriptPath) <span class="hljs-keyword">return</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"❌ Usage: node index.js &lt;path_to_server_script&gt;"</span>);

  <span class="hljs-keyword">await</span> mcpClient.connectToServer(scriptPath);
  <span class="hljs-keyword">await</span> mcpClient.chatLoop();
  <span class="hljs-keyword">await</span> mcpClient.cleanup();
}

main();
</code></pre>
<hr />
<h2 id="heading-step-2-set-up-the-weather-tool-server">☁️ Step 2: Set Up the Weather Tool Server</h2>
<h3 id="heading-21-create-and-init-server-folder">2.1 Create and Init Server Folder</h3>
<pre><code class="lang-javascript">cd ..
mkdir weather
cd weather
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
mkdir src
touch src/index.ts
</code></pre>
<h3 id="heading-22-tsconfigjson">2.2 <code>tsconfig.json</code></h3>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"compilerOptions"</span>: {
    <span class="hljs-string">"target"</span>: <span class="hljs-string">"ES2022"</span>,
    <span class="hljs-string">"module"</span>: <span class="hljs-string">"Node16"</span>,
    <span class="hljs-string">"moduleResolution"</span>: <span class="hljs-string">"Node16"</span>,
    <span class="hljs-string">"outDir"</span>: <span class="hljs-string">"./build"</span>,
    <span class="hljs-string">"rootDir"</span>: <span class="hljs-string">"./src"</span>,
    <span class="hljs-string">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"skipLibCheck"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-string">"forceConsistentCasingInFileNames"</span>: <span class="hljs-literal">true</span>
  },
  <span class="hljs-string">"include"</span>: [<span class="hljs-string">"src/**/*"</span>],
  <span class="hljs-string">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<h3 id="heading-23-packagejson">2.3 <code>package.json</code></h3>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"module"</span>,
  <span class="hljs-string">"bin"</span>: {
    <span class="hljs-string">"weather"</span>: <span class="hljs-string">"./build/index.js"</span>
  },
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"tsc &amp;&amp; chmod 755 build/index.js"</span>
  },
  <span class="hljs-string">"files"</span>: [
    <span class="hljs-string">"build"</span>
  ]
}
</code></pre>
<hr />
<h3 id="heading-24-weather-server-code">2.4 Weather Server Code</h3>
<p>Inside <code>src/index.ts</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { McpServer } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/mcp.js"</span>;
<span class="hljs-keyword">import</span> { StdioServerTransport } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/stdio.js"</span>;
<span class="hljs-keyword">import</span> { z } <span class="hljs-keyword">from</span> <span class="hljs-string">"zod"</span>;

<span class="hljs-keyword">const</span> NWS_API_BASE = <span class="hljs-string">"https://api.weather.gov"</span>;
<span class="hljs-keyword">const</span> USER_AGENT = <span class="hljs-string">"weather-app/1.0"</span>;

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> McpServer({
  <span class="hljs-attr">name</span>: <span class="hljs-string">"weather"</span>,
  <span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">capabilities</span>: { <span class="hljs-attr">tools</span>: {}, <span class="hljs-attr">resources</span>: {} },
});

<span class="hljs-comment">// Helper to fetch NWS API</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeNWSRequest</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">url: string</span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">T</span> | <span class="hljs-title">null</span>&gt; </span>{
  <span class="hljs-keyword">const</span> headers = {
    <span class="hljs-string">"User-Agent"</span>: USER_AGENT,
    <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/geo+json"</span>,
  };
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(url, { headers });
    <span class="hljs-keyword">if</span> (!res.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Fetch error "</span> + res.status);
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> res.json();
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"NWS fetch error:"</span>, err);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }
}

<span class="hljs-comment">// --- Weather Tool: Get Alerts ---</span>
server.tool(<span class="hljs-string">"get-alerts"</span>, <span class="hljs-string">"Get weather alerts for a state"</span>, {
  <span class="hljs-attr">state</span>: z.string().length(<span class="hljs-number">2</span>),
}, <span class="hljs-keyword">async</span> ({ state }) =&gt; {
  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> makeNWSRequest(<span class="hljs-string">`<span class="hljs-subst">${NWS_API_BASE}</span>/alerts?area=<span class="hljs-subst">${state}</span>`</span>);
  <span class="hljs-keyword">if</span> (!data || !data.features?.length) {
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">"No alerts found."</span> }] };
  }

  <span class="hljs-keyword">const</span> formatted = data.features.map(<span class="hljs-function">(<span class="hljs-params">f: any</span>) =&gt;</span>
    <span class="hljs-string">`Event: <span class="hljs-subst">${f.properties.event}</span>\nArea: <span class="hljs-subst">${f.properties.areaDesc}</span>\n---`</span>
  ).join(<span class="hljs-string">"\n"</span>);

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: formatted }],
  };
});

<span class="hljs-comment">// --- Weather Tool: Get Forecast ---</span>
server.tool(<span class="hljs-string">"get-forecast"</span>, <span class="hljs-string">"Get weather forecast for a location"</span>, {
  <span class="hljs-attr">latitude</span>: z.number(),
  <span class="hljs-attr">longitude</span>: z.number(),
}, <span class="hljs-keyword">async</span> ({ latitude, longitude }) =&gt; {
  <span class="hljs-keyword">const</span> points = <span class="hljs-keyword">await</span> makeNWSRequest(<span class="hljs-string">`<span class="hljs-subst">${NWS_API_BASE}</span>/points/<span class="hljs-subst">${latitude}</span>,<span class="hljs-subst">${longitude}</span>`</span>);
  <span class="hljs-keyword">const</span> forecastUrl = points?.properties?.forecast;
  <span class="hljs-keyword">if</span> (!forecastUrl) <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">"No forecast available."</span> }] };

  <span class="hljs-keyword">const</span> forecastData = <span class="hljs-keyword">await</span> makeNWSRequest(forecastUrl);
  <span class="hljs-keyword">const</span> periods = forecastData?.properties?.periods || [];

  <span class="hljs-keyword">const</span> forecastText = periods.map(<span class="hljs-function">(<span class="hljs-params">p: any</span>) =&gt;</span>
    <span class="hljs-string">`<span class="hljs-subst">${p.name}</span>: <span class="hljs-subst">${p.temperature}</span>°<span class="hljs-subst">${p.temperatureUnit}</span>, <span class="hljs-subst">${p.shortForecast}</span>`</span>
  ).join(<span class="hljs-string">"\n"</span>);

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: forecastText }],
  };
});

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> transport = <span class="hljs-keyword">new</span> StdioServerTransport();
  <span class="hljs-keyword">await</span> server.connect(transport);
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"🌤️ Weather MCP Server running..."</span>);
}
main();
</code></pre>
<hr />
<h2 id="heading-step-3-run-your-agent">🚀 Step 3: Run Your Agent</h2>
<h3 id="heading-31-build-both-client-and-server">3.1 Build both client and server</h3>
<pre><code class="lang-javascript"># From project root
cd weather
npm run build
cd ../mcp-client-typescript
npm run build
</code></pre>
<h3 id="heading-32-start-the-client-server">3.2 Start the Client + Server</h3>
<p>Inside the client directory run:</p>
<pre><code class="lang-javascript">node build/index.js ../weather/build/index.js
</code></pre>
<p>You’ll see:</p>
<pre><code class="lang-javascript">✅ Connected to server <span class="hljs-keyword">with</span> tools: [ <span class="hljs-string">'get-alerts'</span>, <span class="hljs-string">'get-forecast'</span> ]
🤖 MCP Client Started!
</code></pre>
<p>Now type your query:</p>
<pre><code class="lang-javascript">Query: what’s the weather <span class="hljs-keyword">in</span> Florida?
</code></pre>
<hr />
<h2 id="heading-how-it-works">🧠 How It Works</h2>
<p>🧩 The Client = Claude + MCP SDK<br />🛠️ The Server = Tool logic exposed via MCP SDK<br />🗣️ Claude = uses tools when needed (<code>tool_use</code>)<br />🔁 Client = reads <code>tool_use</code>, sends to server, replies back to Claude<br />🎯 Final response = intelligent + tool-aware</p>
<hr />
<h2 id="heading-visual-summary">🖼️ Visual Summary</h2>
<pre><code class="lang-javascript">You ➝ Claude ➝ tool_use ➝ MCP Client ➝ Tool Server ➝ result ➝ Claude ➝ Final Answer
</code></pre>
<hr />
<h2 id="heading-example-output">💬 Example Output</h2>
<pre><code class="lang-javascript">Query: what<span class="hljs-string">'s the weather in Florida?
[Calling tool get-alerts with args {"state":"FL"}]
... returns active alerts like:

- Rip Currents
- Red Flag Warnings
- Fire Weather Conditions</span>
</code></pre>
<hr />
<h2 id="heading-thats-a-wrap">🏁 That's a Wrap!</h2>
<p>You’ve now built your first <strong>Claude + MCP-powered AI Agent</strong> with:</p>
<p>✅ Tool use<br />✅ Local dev<br />✅ Type-safe schemas with Zod<br />✅ Full loop integration</p>
<p>👋 Got Questions or Ideas? If you have any queries or concerns regarding the AI Agent domain, just drop me an email at <a target="_blank" href="mailto:shayan.developer12@gmail.com">shayan.developer12@gmail.com</a>.</p>
<p>🔔 Subscribe for more updates, walkthroughs, and deep dives as we build the future of agents together.</p>
]]></content:encoded></item><item><title><![CDATA[🧠 What is Model Context Protocol (MCP) and Why It Matters for AI Agents]]></title><description><![CDATA[As AI moves beyond just generating text, we’re entering an era where LLMs must use tools, access data, and act intelligently. That’s where Model Context Protocol (MCP) comes in — the invisible layer powering modern AI agents like Claude.
If you've he...]]></description><link>https://aiagentsworld.hashnode.dev/what-is-model-context-protocol-mcp-and-why-it-matters-for-ai-agents</link><guid isPermaLink="true">https://aiagentsworld.hashnode.dev/what-is-model-context-protocol-mcp-and-why-it-matters-for-ai-agents</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[mcp]]></category><category><![CDATA[mcp server]]></category><dc:creator><![CDATA[Shayan Danish]]></dc:creator><pubDate>Sat, 22 Mar 2025 18:04:28 GMT</pubDate><content:encoded><![CDATA[<p>As AI moves beyond just generating text, we’re entering an era where <strong>LLMs must use tools, access data, and act intelligently</strong>. That’s where <strong>Model Context Protocol (MCP)</strong> comes in — the invisible layer powering modern AI agents like Claude.</p>
<p>If you've heard buzzwords like "LLM tool-use", "AI agents", or "context injection", MCP is the protocol quietly making it all work.</p>
<hr />
<h2 id="heading-what-is-mcp">📦 What is MCP?</h2>
<p><strong>Model Context Protocol (MCP)</strong> is a standard that allows language models (LLMs) to:</p>
<ul>
<li><p><strong>Call external tools</strong></p>
</li>
<li><p><strong>Access dynamic context</strong></p>
</li>
<li><p><strong>Retrieve real-world data</strong></p>
</li>
<li><p><strong>Take actions</strong> based on reasoning</p>
</li>
</ul>
<p>It creates a clean separation between:</p>
<ul>
<li><p>🧠 <em>Thinking</em> (done by the LLM)</p>
</li>
<li><p>🛠 <em>Doing</em> (handled by tools, APIs, servers)</p>
</li>
</ul>
<p>Think of it as a <strong>developer-friendly API layer for the brain of an AI</strong>.</p>
<hr />
<h2 id="heading-core-components-of-mcp">🧩 Core Components of MCP</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742666520356/6931551c-4aa3-4c4c-a81f-42e55a84d766.png" alt class="image--center mx-auto" /></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Term</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><strong>LLM</strong></td><td>The model itself (e.g., Claude) that reasons and decides what to do</td></tr>
<tr>
<td><strong>MCP Host</strong></td><td>The environment where the LLM and MCP Client run — usually your IDE or local machine</td></tr>
<tr>
<td><strong>MCP Client</strong></td><td>The bridge that passes tool requests from the LLM to the correct server</td></tr>
<tr>
<td><strong>MCP Server</strong></td><td>A program that implements tools (functions) and returns results</td></tr>
<tr>
<td><strong>Tool</strong></td><td>A callable function (e.g., <code>get_weather</code>) the LLM can use</td></tr>
<tr>
<td><strong>Resource</strong></td><td>A structured source of data, like a file or profile</td></tr>
<tr>
<td><strong>MCP Protocol</strong></td><td>The structured format (JSON) used for communication between client and server</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-how-mcp-works-the-flow">🧠 How MCP Works – The Flow</h2>
<p>Here’s what happens under the hood when an AI agent interacts with tools:</p>
<ol>
<li><p><strong>You</strong> ask the model to do something (e.g., "summarize these files")</p>
</li>
<li><p><strong>LLM</strong> thinks: “I need to read some files”</p>
</li>
<li><p>It decides to call a tool like <code>read_file</code></p>
</li>
<li><p><strong>MCP Client</strong> sends that tool call to the right <strong>MCP Server</strong></p>
</li>
<li><p><strong>MCP Server</strong> fetches the data and returns it</p>
</li>
<li><p><strong>LLM</strong> continues reasoning and gives you the final result</p>
</li>
</ol>
<blockquote>
<p>It's not just text generation anymore — it's intelligent action.</p>
</blockquote>
<hr />
<h2 id="heading-tools-vs-resources">⚖️ Tools vs Resources</h2>
<ul>
<li><p><strong>Tools</strong> are functions that do something:<br />  → Fetch weather, run a query, send a message</p>
</li>
<li><p><strong>Resources</strong> are context providers:<br />  → Load file contents, get a config, fetch a user profile</p>
</li>
</ul>
<p>LLMs decide when to use each — just like a human dev would decide what script or API to call.</p>
<hr />
<h2 id="heading-why-mcp-matters">💡 Why MCP Matters</h2>
<ul>
<li><p>🧠 <strong>Smarter models</strong>: They don’t just guess, they access actual context</p>
</li>
<li><p>🤖 <strong>True AI agents</strong>: LLMs that can act like developers or assistants</p>
</li>
<li><p>🔌 <strong>Plug-and-play extensibility</strong>: Add your own APIs, data, tools</p>
</li>
<li><p>🔒 <strong>Separation of concerns</strong>: Models reason, tools do the work</p>
</li>
</ul>
<hr />
<h2 id="heading-where-does-this-run-mcp-host">🧭 Where Does This Run? (MCP Host)</h2>
<p>The <strong>MCP Host</strong> is the environment where everything happens:</p>
<ul>
<li><p>It contains the <strong>LLM (like Claude)</strong></p>
</li>
<li><p>It runs the <strong>MCP Client</strong></p>
</li>
<li><p>It’s usually your <strong>IDE</strong>, <strong>Replit</strong>, or <strong>local machine</strong></p>
</li>
</ul>
<p>The host lets your agent access tools <strong>securely and locally</strong>, instead of sending data to the cloud.</p>
<hr />
<h2 id="heading-summary">Summary</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Term</td><td>Role</td></tr>
</thead>
<tbody>
<tr>
<td><strong>MCP</strong></td><td>Standard protocol for LLMs to call tools/resources</td></tr>
<tr>
<td><strong>MCP Server</strong></td><td>Where the logic of tools lives</td></tr>
<tr>
<td><strong>MCP Client</strong></td><td>The relay between LLM and servers</td></tr>
<tr>
<td><strong>Tool</strong></td><td>Function the LLM can call (e.g., <code>add</code>, <code>fetch-weather</code>)</td></tr>
<tr>
<td><strong>Resource</strong></td><td>Contextual data (e.g., <a target="_blank"><code>file://notes.md</code></a>)</td></tr>
<tr>
<td><strong>Host</strong></td><td>The environment running LLM + client</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-the-bigger-picture">🌐 The Bigger Picture</h2>
<p>MCP isn’t just a dev protocol — it’s the <strong>foundation for real AI agents</strong> that:</p>
<ul>
<li><p>Use tools</p>
</li>
<li><p>Think in loops</p>
</li>
<li><p>Automate workflows</p>
</li>
<li><p>Work locally and securely</p>
</li>
</ul>
<p>If you're building with LLMs, the <strong>future is not prompt-chaining</strong> — it’s <strong>protocol-driven tool use</strong>, and <strong>MCP is leading the way</strong>.</p>
]]></content:encoded></item></channel></rss>