{"id":31980,"date":"2025-10-14T10:08:52","date_gmt":"2025-10-14T15:08:52","guid":{"rendered":"https:\/\/wpengine.com\/builders\/?p=31980"},"modified":"2025-10-14T12:38:05","modified_gmt":"2025-10-14T17:38:05","slug":"wp-engine-smart-search-mcp-in-headless-wp","status":"publish","type":"post","link":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/","title":{"rendered":"Implement WP Engine&#8217;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress"},"content":{"rendered":"\n<p>This guide demonstrates how to build a full-stack headless WordPress application featuring a chatbot that provides accurate, contextually relevant responses using WP Engine&#8217;s new Smart Search AI MCP.<\/p>\n\n\n\n<p>At the end of the article, we will have a chatbot that can call into your Smart Search AI MCP endpoint, which in turn leverages Smart Search to retrieve relevant content.<\/p>\n\n\n\n<div class=\"wp-block-group has-polar-background-color has-background is-layout-flow wp-container-core-group-is-layout-1 wp-block-group-is-layout-flow\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--40)\">\n<p class=\"has-large-font-size\"><strong>Table of Contents<\/strong><\/p>\n\n\n\n<ul id=\"Prerequisites\" class=\"wp-block-list\">\n<li id=\"Prerequisites\"><a href=\"#Prerequisites\">Prerequisites<\/a><\/li>\n\n\n\n<li><a href=\"#steps-for-setting-up\">Steps For Setting Up<\/a><\/li>\n\n\n\n<li id=\"steps-for-setting-up\"><a href=\"#calling-the-mcp-server\">Calling The WP Engine Smart Search MCP Server From Next.js<\/a><\/li>\n\n\n\n<li><a href=\"#create-ui-components\">Create UI Components For The Chat Interface<\/a><\/li>\n\n\n\n<li><a href=\"#update-page-template\">Update the page.tsx Template<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/update-layout-file\">Update The layout.tsx File With Metadata<\/a><\/li>\n\n\n\n<li><a href=\"#test-the-chatbot\">Test The Chatbot&#8217;s Dynamism<\/a><\/li>\n\n\n\n<li><a href=\"#conclusion\">Conclusion<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites<\/h2>\n\n\n\n<p>To benefit from this article, you should be familiar with the basics of working with the command line, <a href=\"https:\/\/wpengine.com\/builders\/headless-roadmap\/\">headless WordPress<\/a> development, <a href=\"http:\/\/next.js\">Next.js<\/a>, and the WP Engine User Portal.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Steps For Setting Up<\/h2>\n\n\n\n<p>1. Set up <a href=\"https:\/\/wpengine.com\/wordpress-hosting\/\">an account on WP Engine<\/a> and get a WordPress install running.  You can get a free headless platform sandbox here:<\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-heliotrope-background-color has-text-color has-background has-link-color wp-elements-60580c77f35127ab4c58efd3ae854863 has-global-padding is-layout-constrained wp-container-core-group-is-layout-3 wp-block-group-is-layout-constrained\" style=\"border-radius:12px;margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<div class=\"wp-block-group alignwide is-content-justification-left is-layout-flex wp-container-core-group-is-layout-2 wp-block-group-is-layout-flex\" style=\"padding-top:0;padding-right:0;padding-bottom:0;padding-left:0\">\n<p style=\"font-size:26px;font-style:normal;font-weight:700;letter-spacing:-1px;line-height:1\">Headless<br>Platform<\/p>\n\n\n\n<p class=\"has-small-font-size wp-container-content-1\" style=\"line-height:1.5\">The all-in-one platform for <br>radically fast headless sites.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-right is-nowrap is-layout-flex wp-container-core-buttons-is-layout-1 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline-base\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/wpeng.in\/headless-platform\/\" style=\"border-radius:99px;padding-top:10px;padding-right:24px;padding-bottom:10px;padding-left:24px\" target=\"_blank\" rel=\"noreferrer noopener\">Try for free \u2192<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p>2. Add a Smart Search AI license. Refer to the docs <a href=\"https:\/\/wpengine.com\/support\/wp-engine-smart-search\/#Enable\">here<\/a> for adding a license After you add the license, opt in for the Smart Search AI MCP.<br><\/p>\n\n\n\n<p>3. Navigate to the WP Admin of your install.\u00a0 Inside your WP Admin, go to <strong>WP Engine Smart Search > Settings<\/strong>.\u00a0 You will find your Smart Search AI MCP URL here.\u00a0 Currently, this shows your GraphQL endpoint. <strong>This is correct and what you want to see. <\/strong><\/p>\n\n\n\n<p>What you need to do is manually remove the <code>\/graphql<\/code> and add <code>\/mcp<\/code>. <\/p>\n\n\n\n<p>So your endpoint should look like this after replacing it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>https:<span class=\"hljs-comment\">\/\/your-wpenginesite-0999A-atlassearch-fkdfjckuaa-uc.a.run.app\/mcp<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"480\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-1024x480.png\" alt=\"\" class=\"wp-image-31994\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-1024x480.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-300x141.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-768x360.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-1536x720.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-14-at-9.58.22\u202fAM-2048x961.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>4. Next, navigate to <strong>Configuration<\/strong>, select the <strong>Hybrid<\/strong> card, and add the <code>`post_content`<\/code> and <code>`post_title`<\/code> fields in the <strong>Semantic settings<\/strong> section. We are going to use this field as our AI-powered field for similarity searches. Make sure to hit <strong>Save Configuration<\/strong> afterward.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"552\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png\" alt=\"\" class=\"wp-image-31981\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-300x162.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-768x414.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1536x828.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>5. After saving the configuration, head on over to the <strong>Index data<\/strong> page, then click <em>Index Now.&nbsp; <\/em>It will give you this success message once completed<em> :<\/em><br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"499\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1-1024x499.png\" alt=\"\" class=\"wp-image-31982\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1-1024x499.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1-300x146.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1-768x374.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1-1536x749.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>6. Create an <a href=\"https:\/\/ai.google.dev\/gemini-api\/docs#javascript\">API account on Google Gemini<\/a> (Or whatever AI model you choose, e.g., OpenAI API).&nbsp; Once created, navigate to your project\u2019s dashboard. If you are using Gemini API, go to the Google AI Studio. In your project\u2019s dashboard, go to API Keys.&nbsp; You should see a page like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"488\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2-1024x488.png\" alt=\"\" class=\"wp-image-31983\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2-1024x488.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2-300x143.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2-768x366.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2-1536x732.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-2.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Generate a new key, copy, and save your API key because we will need this later.&nbsp; The API key is free on Google Gemini,&nbsp; but the free tier has limits.<\/p>\n\n\n\n<p>7.&nbsp; Head over to your terminal or CLI and create a new <a href=\"http:\/\/next.js\">Next.js<\/a> project by pasting this utility command in:<br><br><code>`npx create-next-app@latest name-of-your-app`<\/code><\/p>\n\n\n\n<p>You will receive prompts in your terminal asking you how you want your <a href=\"http:\/\/next.js\">Next.js<\/a> app scaffolded.&nbsp; Answer them accordingly:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>Would you like to use TypeScript? Yes\n<\/span><\/span><span class='shcb-loc'><span>Wold you like to use ESLint? Yes\n<\/span><\/span><span class='shcb-loc'><span>Would you like to use Tailwind CSS? Yes\n<\/span><\/span><span class='shcb-loc'><span>Would you like to use the <span class=\"hljs-string\">`src\/`<\/span> directory? Yes\n<\/span><\/span><span class='shcb-loc'><span>Would you like to use App Router? Yes\n<\/span><\/span><span class='shcb-loc'><span>Would you like to customize the <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">import<\/span> alias (@<span class=\"hljs-comment\">\/*)? No<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Once your <a href=\"http:\/\/next.js\">Next.js<\/a> app is created, you will need to install the dependencies needed to ensure our app works.&nbsp; Copy and paste this command in your terminal:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">install<\/span> <span class=\"hljs-keyword\">@ai-sdk<\/span>\/google react-icons react-markdown @modelcontextprotocol\/sdk @ai-sdk\/react @ai\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><\/p>\n\n\n\n<p><strong><em>Note: We are using Google\u2019s AI sdk for this article. Please refer to the docs in relation to whatever AI model you choose.&nbsp; You can download their npm package.<\/em><\/strong><br><\/p>\n\n\n\n<p>Once the Next project is done scaffolding, <code>cd<\/code> into the project and then open up your code editor.<\/p>\n\n\n\n<p>8. In your Next project, create a&nbsp; <code>`.env.local`<\/code> file with the following environment variables:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>GOOGLE_GENERATIVE_AI_API_KEY=<span class=\"hljs-string\">\"&lt;your key here&gt;\"<\/span>(<span class=\"hljs-keyword\">if<\/span> you chose another AI model, you can name <span class=\"hljs-keyword\">this<\/span> key whatever you want)\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>AI_TOOLKIT_MCP_URL=<span class=\"hljs-string\">\"&lt;your smart search mcp url here&gt;\"<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/ToughCrab24\/smart-search-rag-chatbot\/tree\/mcp-connector\">Here is the link to the final code repo<\/a> so you can check step by step and follow along.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"calling-the-mcp-server\">Calling The WP Engine Smart Search AI MCP Server From Next.js<\/h2>\n\n\n\n<p>The first thing we need to do is set up the request to Smart Search AI MCP with <a href=\"https:\/\/ai-sdk.dev\/cookbook\/node\/mcp-tools\">the Vercel AI SDK<\/a>. \u00a0 Create a file in the <code>`src\/app`<\/code> directory called <code>`api\/chat\/route.ts`<\/code>.\u00a0 Copy the code below and paste it into that file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-comment\">\/\/ IMPORTANT! Set the runtime to edge<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> runtime = <span class=\"hljs-string\">\"edge\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  convertToCoreMessages,\n<\/span><\/span><span class='shcb-loc'><span>  experimental_createMCPClient,\n<\/span><\/span><span class='shcb-loc'><span>  Message,\n<\/span><\/span><span class='shcb-loc'><span>  streamText,\n<\/span><\/span><span class='shcb-loc'><span>} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"ai\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { createGoogleGenerativeAI } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@ai-sdk\/google\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { weatherTool } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@\/app\/utils\/tools\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { StreamableHTTPClientTransport } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@modelcontextprotocol\/sdk\/client\/streamableHttp.js\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> httpTransport = <span class=\"hljs-keyword\">new<\/span> StreamableHTTPClientTransport(\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">new<\/span> URL(process.env.AI_TOOLKIT_MCP_URL || <span class=\"hljs-string\">\"http:\/\/localhost:8080\/mcp\"<\/span>)\n<\/span><\/span><span class='shcb-loc'><span>);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> client = <span class=\"hljs-keyword\">await<\/span> experimental_createMCPClient({\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">transport<\/span>: httpTransport,\n<\/span><\/span><span class='shcb-loc'><span>});\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\">\/**<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\"> * Initialize the Google Generative AI API<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-comment\"> *\/<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> google = createGoogleGenerativeAI();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">POST<\/span>(<span class=\"hljs-params\">req: Request<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">try<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> aiTkTools = <span class=\"hljs-keyword\">await<\/span> client.tools();\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> { messages }: { <span class=\"hljs-attr\">messages<\/span>: <span class=\"hljs-built_in\">Array<\/span>&lt;Message&gt; } = <span class=\"hljs-keyword\">await<\/span> req.json();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> coreMessages = convertToCoreMessages(messages);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> smartSearchPrompt = <span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    - You can use the 'search' tool to find information relating to tv shows.<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      - WP Engine Smart Search is a powerful tool for finding information about TV shows.<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      - After the 'smartSearchTool' provides results (even if it's an error or no information found)<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      - You MUST then formulate a conversational response to the user based on those results but also use the tool if the users query is deemed plausible.<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        - If search results are found, summarize them for the user. <\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        - If no information is found or an error occurs, inform the user clearly.`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> systemPromptContent = <span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    - You are a friendly and helpful AI assistant <\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    - You can use the 'weatherTool' to provide current weather information for a specific location.<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    - Do not invent information. Stick to the data provided by the tool.`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">const<\/span> response = streamText({\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">model<\/span>: google(<span class=\"hljs-string\">\"models\/gemini-2.0-flash\"<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">system<\/span>: &#91;smartSearchPrompt, systemPromptContent].join(<span class=\"hljs-string\">\"\\n\"<\/span>),\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">messages<\/span>: coreMessages,\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">tools<\/span>: {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\">\/\/ smartSearchTool,<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        weatherTool,\n<\/span><\/span><span class='shcb-loc'><span>        ...aiTkTools,\n<\/span><\/span><span class='shcb-loc'><span>      },\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">onStepFinish<\/span>: <span class=\"hljs-keyword\">async<\/span> (result) =&gt; {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-comment\">\/\/ Log token usage for each step<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">if<\/span> (result.usage) {\n<\/span><\/span><span class='shcb-loc'><span>          <span class=\"hljs-built_in\">console<\/span>.log(\n<\/span><\/span><span class='shcb-loc'><span>            <span class=\"hljs-string\">`&#91;Token Usage] Prompt tokens: <span class=\"hljs-subst\">${result.usage.promptTokens}<\/span>, Completion tokens: <span class=\"hljs-subst\">${result.usage.completionTokens}<\/span>, Total tokens: <span class=\"hljs-subst\">${result.usage.totalTokens}<\/span>`<\/span>\n<\/span><\/span><span class='shcb-loc'><span>          );\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>      },\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">maxSteps<\/span>: <span class=\"hljs-number\">5<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-comment\">\/\/ Convert the response into a friendly text-stream<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> response.toDataStreamResponse({});\n<\/span><\/span><span class='shcb-loc'><span>  } <span class=\"hljs-keyword\">catch<\/span> (e) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">throw<\/span> e;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This Edge API route wires your chat endpoint to both Google\u2019s Gemini (via the Vercel AI SDK) and the Smart Search AI MCP server. It first creates a streaming-capable MCP HTTP transport pointed at <code>AI_TOOLKIT_MCP_URL<\/code>, builds an MCP client, and fetches the server-advertised tools at request time (<code>client.tools()<\/code>).<\/p>\n\n\n\n<p>Incoming chat messages from the client are normalized with <code>convertToCoreMessages<\/code>, and two concise system prompts instruct the model on how to use tools: a <em>\u201csearch\u201d<\/em> tool (backed by WP Engine Smart Search via MCP) and a local <code>weatherTool<\/code>. The prompts emphasize not inventing facts and summarizing search results (including the \u201cno results\u201d case).<\/p>\n\n\n\n<p>With that context, <code>streamText<\/code> runs gemini-2.0-flash, exposes <code>weatherTool<\/code> plus all MCP tools (&#8230;<code>aiTkTools<\/code>) to the model, and streams the assistant\u2019s reply back to the browser. The SDK may invoke tools during reasoning (up to <code>maxSteps: 5<\/code>). After each step, the handler logs token usage for basic observability.&nbsp;<\/p>\n\n\n\n<p>Finally, <code>toDataStreamResponse<\/code> returns a chunked HTTP response so the UI can render tokens as they arrive\u2014giving you a real-time, tool-augmented chat experience that queries Smart Search through your MCP server when needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-ui-components\">Create UI Components For The Chat Interface<\/h2>\n\n\n\n<p>In this section, let&#8217;s create our components to render the UI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Chat.tsx<\/h2>\n\n\n\n<p>In the <code>`src\/app`<\/code> directory, create a <code>`components`<\/code> folder.&nbsp; Then create a <code>`Chat.tsx`<\/code> file.&nbsp; Copy and paste this code block into that file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-string\">\"use client\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> React, { ChangeEvent } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> Messages <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/Messages\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Message } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"ai\/react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> LoadingIcon <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/Icons\/LoadingIcon\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> ChatInput <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/ChatInput\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>interface Chat {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">input<\/span>: string;\n<\/span><\/span><span class='shcb-loc'><span>  handleInputChange: <span class=\"hljs-function\">(<span class=\"hljs-params\">e: ChangeEvent&lt;HTMLInputElement&gt;<\/span>) =&gt;<\/span> <span class=\"hljs-keyword\">void<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  handleMessageSubmit: <span class=\"hljs-function\">(<span class=\"hljs-params\">e: React.FormEvent&lt;HTMLFormElement&gt;<\/span>) =&gt;<\/span> <span class=\"hljs-keyword\">void<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  messages: Message&#91;];\n<\/span><\/span><span class='shcb-loc'><span>  status: <span class=\"hljs-string\">\"submitted\"<\/span> | <span class=\"hljs-string\">\"streaming\"<\/span> | <span class=\"hljs-string\">\"ready\"<\/span> | <span class=\"hljs-string\">\"error\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> Chat: React.FC&lt;Chat&gt; = ({\n<\/span><\/span><span class='shcb-loc'><span>  input,\n<\/span><\/span><span class='shcb-loc'><span>  handleInputChange,\n<\/span><\/span><span class='shcb-loc'><span>  handleMessageSubmit,\n<\/span><\/span><span class='shcb-loc'><span>  messages,\n<\/span><\/span><span class='shcb-loc'><span>  status,\n<\/span><\/span><span class='shcb-loc'><span>}) =&gt; {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"chat\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex flex-col w-full mx-2\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Messages<\/span> <span class=\"hljs-attr\">messages<\/span>=<span class=\"hljs-string\">{messages}<\/span> \/&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      {status === \"submitted\" &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">LoadingIcon<\/span> \/&gt;<\/span>}<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">onSubmit<\/span>=<span class=\"hljs-string\">{handleMessageSubmit}<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"ml-1 mt-5 mb-5 relative rounded-lg\"<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      &gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ChatInput<\/span> <span class=\"hljs-attr\">input<\/span>=<span class=\"hljs-string\">{input}<\/span> <span class=\"hljs-attr\">handleInputChange<\/span>=<span class=\"hljs-string\">{handleInputChange}<\/span> \/&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">};<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Chat;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><br>This file defines a client-side React Chat component that ties together your message list, input field, and loading indicator. It declares a Chat props interface\u2014containing the current input value, change and submit handlers, the array of chat messages, and a status flag\u2014and uses those props to control its rendering.&nbsp;<br><\/p>\n\n\n\n<p>Inside the component, it first renders the <code>&lt;Messages&gt;<\/code> list to show the conversation history. If the status is &#8220;submitted&#8221;, it displays a <code>&lt;LoadingIcon&gt;<\/code> spinner to indicate that a response is pending. Finally, it renders a <code>&lt;form&gt;<\/code> wrapping a <code>&lt;ChatInput&gt;<\/code> component wired to the provided input value and change handler, so users can type and submit new messages.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Messages Component<\/h3>\n\n\n\n<p>Staying in the <code>`src\/app\/components`<\/code> directory, create a <code>Messages.tsx<\/code> file.&nbsp; Copy and paste this code block in:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Message } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"ai\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { useEffect, useRef } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> ReactMarkdown <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-markdown\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Messages<\/span>(<span class=\"hljs-params\">{ messages }: { messages: Message&#91;] }<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> messagesEndRef = useRef&lt;HTMLDivElement | <span class=\"hljs-literal\">null<\/span>&gt;(<span class=\"hljs-literal\">null<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    messagesEndRef.current?.scrollIntoView({ <span class=\"hljs-attr\">behavior<\/span>: <span class=\"hljs-string\">\"smooth\"<\/span> });\n<\/span><\/span><span class='shcb-loc'><span>  }, &#91;messages]);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"border-1 border-gray-100 overflow-y-scroll flex-grow flex-col justify-end p-1\"<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">scrollbarWidth:<\/span> \"<span class=\"hljs-attr\">none<\/span>\" }}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">    &gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\">      {messages.map((msg, index) =&gt; (<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{index}<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{<\/span>`${<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">            <span class=\"hljs-attr\">msg.role<\/span> === <span class=\"hljs-string\">\"assistant\"<\/span> ? \"<span class=\"hljs-attr\">bg-green-500<\/span>\" <span class=\"hljs-attr\">:<\/span> \"<span class=\"hljs-attr\">bg-blue-500<\/span>\"<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">          } <span class=\"hljs-attr\">my-2<\/span> <span class=\"hljs-attr\">p-3<\/span> <span class=\"hljs-attr\">shadow-md<\/span> <span class=\"hljs-attr\">hover:shadow-lg<\/span> <span class=\"hljs-attr\">transition-shadow<\/span> <span class=\"hljs-attr\">duration-200<\/span> <span class=\"hljs-attr\">flex<\/span> <span class=\"hljs-attr\">slide-in-bottom<\/span> <span class=\"hljs-attr\">bg-blue-500<\/span> <span class=\"hljs-attr\">border<\/span> <span class=\"hljs-attr\">border-gray-900<\/span> <span class=\"hljs-attr\">message-glow<\/span>`}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">        &gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\">          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"ml- rounded-tl-lg  p-2 border-r flex items-center\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">            {msg.role === \"assistant\" ? \"\ud83e\udd16\" : \"\ud83e\uddd2\ud83c\udffb\"}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"ml-2 text-white\"<\/span>&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ReactMarkdown<\/span>&gt;<\/span>{msg.content}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ReactMarkdown<\/span>&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      ))}<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">ref<\/span>=<span class=\"hljs-string\">{messagesEndRef}<\/span> \/&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The Messages component renders a scrollable list of chat messages, automatically keeping the view scrolled to the latest entry. It accepts a messages prop (an array of Message objects) and uses a <code>ref<\/code> to an empty <code>&lt;div&gt;<\/code> at the bottom; a <code>useEffect<\/code> hook watches for changes to the messages array and calls <code>scrollIntoView<\/code> on that <code>ref<\/code> so new messages smoothly come into view.&nbsp;<\/p>\n\n\n\n<p>Each message is wrapped in a styled <code>&lt;div&gt;<\/code> whose background color and avatar icon depend on the message\u2019s role <em>(\u201cassistant\u201d vs. \u201cuser\u201d)<\/em>, and the text content is rendered via <code>ReactMarkdown<\/code> to support Markdown formatting.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Chat Input Component<\/h3>\n\n\n\n<p>Lastly, staying in the <code>`components\/Chat`<\/code> directory,&nbsp; we have the chat input.&nbsp; Create a <code>`ChatInput.tsx`<\/code> file and copy and paste this code block in:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { ChangeEvent } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> SendIcon <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/Icons\/SendIcon\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>interface InputProps {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">input<\/span>: string;\n<\/span><\/span><span class='shcb-loc'><span>  handleInputChange: <span class=\"hljs-function\">(<span class=\"hljs-params\">e: ChangeEvent&lt;HTMLInputElement&gt;<\/span>) =&gt;<\/span> <span class=\"hljs-keyword\">void<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Input<\/span>(<span class=\"hljs-params\">{ input, handleInputChange }: InputProps<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"bg-gray-800 p-4 rounded-xl shadow-lg w-full max-w-2xl mx-auto\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{input}<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{handleInputChange}<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">{<\/span>\"<span class=\"hljs-attr\">Ask<\/span> <span class=\"hljs-attr\">Smart<\/span> <span class=\"hljs-attr\">Search<\/span> <span class=\"hljs-attr\">about<\/span> <span class=\"hljs-attr\">TV<\/span> <span class=\"hljs-attr\">shows...<\/span>\"}<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"w-full bg-transparent text-gray-200 placeholder-gray-500 focus:outline-none text-md mb-3\"<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      \/&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex\"<\/span>&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"submit\"<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"p-1 hover:bg-gray-700 rounded-md transition-colors ml-auto\"<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">aria-label<\/span>=<span class=\"hljs-string\">\"Send message\"<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">disabled<\/span>=<span class=\"hljs-string\">{!input.trim()}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        &gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SendIcon<\/span> \/&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Input;<\/span><\/span><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file exports an Input component that renders a styled text field and send button for your chat UI. It takes an input string and a <code>handleInputChange<\/code> callback to keep the input controlled, showing a placeholder prompt <em>(\u201cAsk Smart Search about TV shows\u2026\u201d)<\/em>. The send button, decorated with a <code>SendIcon<\/code>, is disabled when the input is empty or just whitespace.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"update-page-template\">Update the page.tsx Template<\/h2>\n\n\n\n<p><br>We need to modify the <code>src\/app\/page.tsx<\/code> file to add the Chat component to the page.&nbsp; In the <code>page.tsx<\/code> file, copy and paste this code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-string\">\"use client\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> Chat <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/components\/Chat\/Chat\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { useChat } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"@ai-sdk\/react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> Page: React.FC = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    messages,\n<\/span><\/span><span class='shcb-loc'><span>    input,\n<\/span><\/span><span class='shcb-loc'><span>    handleInputChange,\n<\/span><\/span><span class='shcb-loc'><span>    handleSubmit,\n<\/span><\/span><span class='shcb-loc'><span>    setMessages,\n<\/span><\/span><span class='shcb-loc'><span>    status,\n<\/span><\/span><span class='shcb-loc'><span>  } = useChat();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  useEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">if<\/span> (messages.length &lt; <span class=\"hljs-number\">1<\/span>) {\n<\/span><\/span><span class='shcb-loc'><span>      setMessages(&#91;\n<\/span><\/span><span class='shcb-loc'><span>        {\n<\/span><\/span><span class='shcb-loc'><span>          <span class=\"hljs-attr\">role<\/span>: <span class=\"hljs-string\">\"assistant\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>          <span class=\"hljs-attr\">content<\/span>: <span class=\"hljs-string\">\"Welcome to the Smart Search chatbot!\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>          <span class=\"hljs-attr\">id<\/span>: <span class=\"hljs-string\">\"welcome\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        },\n<\/span><\/span><span class='shcb-loc'><span>      ]);\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }, &#91;messages, setMessages]);\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex flex-col justify-between h-screen bg-white mx-auto max-w-full\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"flex w-full flex-grow overflow-hidden relative bg-slate-950\"<\/span>&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Chat<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">input<\/span>=<span class=\"hljs-string\">{input}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">handleInputChange<\/span>=<span class=\"hljs-string\">{handleInputChange}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">handleMessageSubmit<\/span>=<span class=\"hljs-string\">{handleSubmit}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">messages<\/span>=<span class=\"hljs-string\">{messages}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">          <span class=\"hljs-attr\">status<\/span>=<span class=\"hljs-string\">{status}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">        \/&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">};<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Page;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><br>This file defines our page component that leverages the <code>useChat<\/code> hook from the<code> @ai-sdk\/react<\/code> package to manage chat state, including messages, input text, submission handler, and status.&nbsp;<br>Upon initial render, a <code>useEffect<\/code> hook checks if there are no messages and injects a default assistant greeting. The component returns a full-viewport flexbox layout with a styled background area in which it renders the Chat component, passing along the chat state and handlers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"update-layout-file\">Update The layout.tsx File With Metadata<\/h2>\n\n\n\n<p>We need to add metadata to our layout.&nbsp; Copy and paste this code block into the <code>`src\/app\/layout.tsx`<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> type { Metadata } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { Inter } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/font\/google\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\".\/globals.css\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> inter = Inter({ <span class=\"hljs-attr\">subsets<\/span>: &#91;<span class=\"hljs-string\">\"latin\"<\/span>] });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> metadata: Metadata = {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">title<\/span>: <span class=\"hljs-string\">\"Smart Search RAG\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">description<\/span>: <span class=\"hljs-string\">\"Lets make a chatbot with Smart Search\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>};\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">RootLayout<\/span>(<span class=\"hljs-params\">{<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-params\">  children,<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-params\">}: Readonly&lt;{<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-params\">  children: React.ReactNode;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-function\"><span class=\"hljs-params\">}&gt;<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> (\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\">      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{inter.className}<\/span>&gt;<\/span>{children}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">  );<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\"><span class=\"hljs-tag\">}<\/span><\/span><\/span><\/span><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file configures the global layout and metadata for the app: it imports global styles, loads the Inter font, and sets the page title and description. The default <code>RootLayout<\/code> component wraps all page content in <code>&lt;html&gt;<\/code> and <code>&lt;body&gt;<\/code> tags, applying the Inter font\u2019s class to the body.<\/p>\n\n\n\n<p><strong><em>CSS Note: <\/em><\/strong>The last thing to add for the styling is the <code>globals.css<\/code> file. Visit the <a href=\"https:\/\/github.com\/ToughCrab24\/smart-search-rag-chatbot\/blob\/gemini-tools-integration\/src\/app\/globals.css\">code block here<\/a> and copy and paste it into your project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"test-the-chatbot\">Test The ChatBot&#8217;s Dynamism <\/h2>\n\n\n\n<p><br>The chatbot should be completed and testable in this state. In your terminal run <code>`npm run dev`<\/code> and navigate to <code>http:\/\/localhost:3000<\/code>. Try asking the chatbot a few questions.&nbsp; <\/p>\n\n\n\n<p>After you ask it a few questions related to your WordPress content, ask it something about a subject that is not in your WordPress content. The AI will try to fetch what you asked for knowing what tooling it has via MCP. It will know that the content does not exist in your WordPress site via Smart Search.<\/p>\n\n\n\n<p>Now, try adding a new post with a title and content. It could be any topic. Publish the post and then ask the chatbot about the subject.  It should give you the relevant content you are asking for in natural language.<\/p>\n\n\n\n<p>You should see this experience in your browser:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/AIchatbotMCP-1.gif\" alt=\"\" class=\"wp-image-31986\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>We hope this article helped you understand how to create a chatbot with WP Engine\u2019s Smart Search AI MCP server headless WordPress!\u00a0 Stay tuned for the next article on using this in traditional WordPress!!<\/p>\n\n\n\n<p>As always, we\u2019re super stoked to hear your feedback and learn about the headless projects you\u2019re working on, so hit us up in the <a href=\"https:\/\/wpeng.in\/devrel-discord\/\">Headless WordPress Discord!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide demonstrates how to build a full-stack headless WordPress application featuring a chatbot that provides accurate, contextually relevant responses using WP Engine&#8217;s new Smart Search AI MCP. At the [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_EventAllDay":false,"_EventTimezone":"","_EventStartDate":"","_EventEndDate":"","_EventStartDateUTC":"","_EventEndDateUTC":"","_EventShowMap":false,"_EventShowMapLink":false,"_EventURL":"","_EventCost":"","_EventCostDescription":"","_EventCurrencySymbol":"","_EventCurrencyCode":"","_EventCurrencyPosition":"","_EventDateTimeSeparator":"","_EventTimeRangeSeparator":"","_EventOrganizerID":[],"_EventVenueID":[],"_OrganizerEmail":"","_OrganizerPhone":"","_OrganizerWebsite":"","_VenueAddress":"","_VenueCity":"","_VenueCountry":"","_VenueProvince":"","_VenueState":"","_VenueZip":"","_VenuePhone":"","_VenueURL":"","_VenueStateProvince":"","_VenueLat":"","_VenueLng":"","_VenueShowMap":false,"_VenueShowMapLink":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-31980","post","type-post","status-publish","format-standard","hentry","category-headless"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Implement WP Engine&#039;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress - Builders<\/title>\n<meta name=\"description\" content=\"A How-to guide to implement WP Engine\u2019s Smart Search MCP in headless WordPress with Next.js + Vercel AI SDK + Google AI.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Implement WP Engine Smart Search MCP in Headless WordPress\" \/>\n<meta property=\"og:description\" content=\"Build an AI-ready headless WordPress app powered by WP Engine Smart Search via MCP. Learn Setup, MCP Server, An Edge Chat Route, and Tool Calling.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\" \/>\n<meta property=\"og:site_name\" content=\"Builders\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-14T15:08:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-14T17:38:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/WPE-Builders-YouTube-ScreenshotNavy-1920x1080-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Francis Agulto\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:site\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francis Agulto\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\"},\"author\":{\"name\":\"Francis Agulto\",\"@id\":\"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54\"},\"headline\":\"Implement WP Engine&#8217;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress\",\"datePublished\":\"2025-10-14T15:08:52+00:00\",\"dateModified\":\"2025-10-14T17:38:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\"},\"wordCount\":1533,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/wpengine.com\/builders\/#organization\"},\"image\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png\",\"articleSection\":[\"Headless\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\",\"url\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\",\"name\":\"Implement WP Engine's Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress - Builders\",\"isPartOf\":{\"@id\":\"https:\/\/wpengine.com\/builders\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png\",\"datePublished\":\"2025-10-14T15:08:52+00:00\",\"dateModified\":\"2025-10-14T17:38:05+00:00\",\"description\":\"A How-to guide to implement WP Engine\u2019s Smart Search MCP in headless WordPress with Next.js + Vercel AI SDK + Google AI.\",\"breadcrumb\":{\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage\",\"url\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image.png\",\"contentUrl\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image.png\",\"width\":1600,\"height\":862},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/wpengine.com\/builders\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Implement WP Engine&#8217;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/wpengine.com\/builders\/#website\",\"url\":\"https:\/\/wpengine.com\/builders\/\",\"name\":\"Builders\",\"description\":\"Reimagining the way we build with WordPress.\",\"publisher\":{\"@id\":\"https:\/\/wpengine.com\/builders\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/wpengine.com\/builders\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/wpengine.com\/builders\/#organization\",\"name\":\"WP Engine\",\"url\":\"https:\/\/wpengine.com\/builders\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png\",\"contentUrl\":\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png\",\"width\":348,\"height\":68,\"caption\":\"WP Engine\"},\"image\":{\"@id\":\"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/wpebuilders\",\"https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54\",\"name\":\"Francis Agulto\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/wpengine.com\/builders\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c24a68b84c9ad2b53c633d14917d8298?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c24a68b84c9ad2b53c633d14917d8298?s=96&d=mm&r=g\",\"caption\":\"Francis Agulto\"},\"description\":\"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!\",\"url\":\"https:\/\/wpengine.com\/builders\/author\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Implement WP Engine's Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress - Builders","description":"A How-to guide to implement WP Engine\u2019s Smart Search MCP in headless WordPress with Next.js + Vercel AI SDK + Google AI.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/","og_locale":"en_US","og_type":"article","og_title":"Implement WP Engine Smart Search MCP in Headless WordPress","og_description":"Build an AI-ready headless WordPress app powered by WP Engine Smart Search via MCP. Learn Setup, MCP Server, An Edge Chat Route, and Tool Calling.","og_url":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/","og_site_name":"Builders","article_published_time":"2025-10-14T15:08:52+00:00","article_modified_time":"2025-10-14T17:38:05+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/WPE-Builders-YouTube-ScreenshotNavy-1920x1080-1.png","type":"image\/png"}],"author":"Francis Agulto","twitter_card":"summary_large_image","twitter_creator":"@wpebuilders","twitter_site":"@wpebuilders","twitter_misc":{"Written by":"Francis Agulto","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#article","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/"},"author":{"name":"Francis Agulto","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54"},"headline":"Implement WP Engine&#8217;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress","datePublished":"2025-10-14T15:08:52+00:00","dateModified":"2025-10-14T17:38:05+00:00","mainEntityOfPage":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/"},"wordCount":1533,"commentCount":0,"publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"image":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage"},"thumbnailUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png","articleSection":["Headless"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/","url":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/","name":"Implement WP Engine's Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress - Builders","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/#website"},"primaryImageOfPage":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage"},"image":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage"},"thumbnailUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image-1024x552.png","datePublished":"2025-10-14T15:08:52+00:00","dateModified":"2025-10-14T17:38:05+00:00","description":"A How-to guide to implement WP Engine\u2019s Smart Search MCP in headless WordPress with Next.js + Vercel AI SDK + Google AI.","breadcrumb":{"@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#primaryimage","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2025\/10\/image.png","width":1600,"height":862},{"@type":"BreadcrumbList","@id":"https:\/\/wpengine.com\/builders\/wp-engine-smart-search-mcp-in-headless-wp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wpengine.com\/builders\/"},{"@type":"ListItem","position":2,"name":"Implement WP Engine&#8217;s Smart Search AI Model Context Protocol (MCP) Server in Headless WordPress"}]},{"@type":"WebSite","@id":"https:\/\/wpengine.com\/builders\/#website","url":"https:\/\/wpengine.com\/builders\/","name":"Builders","description":"Reimagining the way we build with WordPress.","publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wpengine.com\/builders\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wpengine.com\/builders\/#organization","name":"WP Engine","url":"https:\/\/wpengine.com\/builders\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","width":348,"height":68,"caption":"WP Engine"},"image":{"@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wpebuilders","https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g"]},{"@type":"Person","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54","name":"Francis Agulto","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c24a68b84c9ad2b53c633d14917d8298?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c24a68b84c9ad2b53c633d14917d8298?s=96&d=mm&r=g","caption":"Francis Agulto"},"description":"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!","url":"https:\/\/wpengine.com\/builders\/author\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\/"}]}},"_links":{"self":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/31980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/comments?post=31980"}],"version-history":[{"count":0,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/31980\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/media?parent=31980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/categories?post=31980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/tags?post=31980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}