{"id":45058,"date":"2025-11-20T15:44:37","date_gmt":"2025-11-20T20:44:37","guid":{"rendered":"https:\/\/netfoundry.io\/?p=45058"},"modified":"2025-11-20T16:17:58","modified_gmt":"2025-11-20T21:17:58","slug":"how-an-ai-agent-decides-to-call-mcp-tools","status":"publish","type":"post","link":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/","title":{"rendered":"How an AI Agent Decides to Call MCP Tools"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-the-mystery\">The Mystery<\/h2>\n\n\n\n<p>We\u2019ve all been there. We enter a prompt into an AI Agent, and then we wonder why it chose to invoke a particular Tool in a particular MCP server. Or the flip side \u2013 why it didn\u2019t invoke a Tool that you expected it to invoke.<\/p>\n\n\n\n<p>As it turns out, the explanation of how MCP Tools are chosen is both simpler <em>and<\/em> more nuanced than most people think.<\/p>\n\n\n\n<p>Below, I describe how an AI Agent\/LLM decides whether to call an MCP Tool, <em>which<\/em> tool to call, and <em>when not<\/em> to call one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-an-llm-decides-to-call-mcp-tools\"><strong>How an LLM Decides to Call MCP Tools<\/strong><\/h2>\n\n\n\n<p>MCP (<a href=\"https:\/\/modelcontextprotocol.io\/docs\/getting-started\/intro\">Model Context Protocol<\/a>) is designed so that external Tools can become part of the LLM\u2019s (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Large_language_model\">Large Language Model<\/a>) decision-making environment. But note that the LLM doesn\u2019t <strong><em>run<\/em><\/strong> tools on its own \u2014 it <strong><em>selects<\/em><\/strong> Tools based on the conversation context, various Tool schemas, and the LLM\u2019s own internal decision heuristics.<\/p>\n\n\n\n<p>The following mental model explains how it works.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-llm-sees-each-tool-as-a-function-with-a-contract\"><strong>The LLM sees each Tool as a function with a \u201ccontract\u201d<\/strong><\/h3>\n\n\n\n<p>The term &#8220;MCP Tool contract&#8221; refers to the <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\/server\/tools\">MCP specification<\/a> that defines how AI Agents communicate with external Tools and services. This protocol standardizes the interaction, acting as a universal interface between LLMs and the functions they can call to perform actions or access data.&nbsp;<\/p>\n\n\n\n<p>This contract is the schema and metadata that describe a Tool&#8217;s capabilities, inputs, and expected outputs.<\/p>\n\n\n\n<p>Every MCP Tool provides a definition structure that contains:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A <strong>name<\/strong><\/li>\n\n\n\n<li>A <strong>description<\/strong><\/li>\n\n\n\n<li>A <strong>JSON schema<\/strong> describing its expected input parameters and output shape<\/li>\n\n\n\n<li>(Optionally) a declared set of \u201chints\u201d related to tool behavior<\/li>\n<\/ul>\n\n\n\n<p>In this article, I will defer discussing detailed aspects involving vector representations (embeddings), named entity recognition (NER), etc. But at a high level, it is essential to understand that the Agent ingests the Tool\u2019s definition structure, and then the LLM forms a <strong><em>semantic<\/em><\/strong><em> <\/em><strong><em>signature<\/em><\/strong><em> <\/em>that<em> <\/em>represents the Tool.<\/p>\n\n\n\n<p>When Agents connect to an MCP server, the Tools metadata \u2014 an array with names, parameter schemas, descriptions, etc. \u2014 becomes <strong>vectorized<\/strong> inside the LLM. This produces an internal &#8220;tool embedding&#8221; for each Tool.<\/p>\n\n\n\n<p>Later, during NLP operations (input prompts from the user to the Agent), the LLM uses this semantic signature embedding to infer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What each Tool <em>does<\/em><\/li>\n\n\n\n<li>What kinds of problems the Tool solves<\/li>\n\n\n\n<li>What inputs the Tool needs<\/li>\n\n\n\n<li>What situations require calling the Tool<\/li>\n<\/ul>\n\n\n\n<p>This is why high-quality Tool names, descriptions, and parameter descriptions matter so much when building MCP Tools.<\/p>\n\n\n\n<p>Tool descriptions are not procedural instructions. They become <strong>semantic memories<\/strong> that the LLM embeds and can later compare against natural language.&nbsp;<\/p>\n\n\n\n<p>Without embeddings, the LLM\u2026<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>would not generalize to synonyms (\u201cremove identity\u201d \u2192 \u201cdelete identity\u201d).<\/li>\n\n\n\n<li>would not understand parameter semantics.<\/li>\n\n\n\n<li>could not decide when <em>not<\/em> to use a tool.<\/li>\n\n\n\n<li>wouldn\u2019t handle partially matching prompts.<\/li>\n<\/ul>\n\n\n\n<p>Embeddings make Tool utilization a <strong>meaning- or intent-matching <\/strong>task, not a <strong>keyword-matching<\/strong> task.<\/p>\n\n\n\n<p>LLMs store tool descriptions as dense semantic vectors, then compare the vectorized user prompt against these internal \u201ctool embeddings\u201d to decide <strong>if<\/strong> a tool should be invoked, <strong>which one<\/strong>, and <strong>how<\/strong> to populate its parameters.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-llm-maps-user-intent-candidate-tool-s\"><strong>The LLM maps user intent \u2192 candidate tool(s)<\/strong><\/h3>\n\n\n\n<p>Based on the user&#8217;s latest message, the LLM internally performs an intent classification step (not externally visible to the user). Essentially, the LLM asks itself:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cDoes the user want information that I can answer myself?\u201d<\/li>\n\n\n\n<li>\u201cIs the user requesting an operation that requires a tool?\u201d<\/li>\n\n\n\n<li>\u201cIs the user asking for data I don\u2019t know?\u201d<\/li>\n\n\n\n<li>\u201cIs the user asking for something explicitly mapped to a tool (e.g., search, sql.query, filesystem.readFile)?\u201d<br><\/li>\n<\/ul>\n\n\n\n<p>Tools are only chosen if:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The intent <em>requires<\/em> external action<\/li>\n\n\n\n<li>A tool <em>exists<\/em> whose schema\/description has a semantic match<\/li>\n\n\n\n<li>The Tool\u2019s input parameter constraints match the user\u2019s request<\/li>\n<\/ul>\n\n\n\n<p>The LLM tends to be conservative: if it can answer without a tool, it will.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-llm-evaluates-all-tools-against-the-current-query\"><strong>The LLM evaluates all tools against the current query<\/strong><\/h3>\n\n\n\n<p>Again, internally, it reasons out something like: \u201cGiven the user\u2019s intent, which available tools appear relevant?\u201d<\/p>\n\n\n\n<p>For each tool, it checks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>does the description mention relevant verbs\/nouns?<\/li>\n\n\n\n<li>does the schema accept the type of arguments the user is asking about?<\/li>\n\n\n\n<li>is it plausible that this tool can fulfill the request?<\/li>\n\n\n\n<li>do other tools overlap with this one?<\/li>\n<\/ul>\n\n\n\n<p>This amounts to semantic similarity search + heuristics, <strong><em>not code execution<\/em><\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-llm-predicts-the-tool-call-as-text-not-by-executing-logic\"><strong>The LLM predicts the tool call <\/strong><strong><em>as text<\/em><\/strong><strong>, not by executing logic<\/strong><\/h3>\n\n\n\n<p>This is an important subtlety.<\/p>\n\n\n\n<p>The LLM doesn\u2019t <em>run<\/em> the tool or simulate its output before choosing it. It <em>predicts the next token<\/em>, which happens to be a JSON object that the Agent framework interprets as a tool call.<\/p>\n\n\n\n<p>If the next-token probability distribution supports a tool invocation pattern, you will see a tool call.<\/p>\n\n\n\n<p>So the LLM isn\u2019t \u201cdeciding\u201d in the human sense \u2014 it\u2019s predicting tool-call tokens when they appear appropriate, given the prompt, chat history, tool descriptions, and system guidelines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-hosting-agent-may-also-influence-the-decision\"><strong>The hosting Agent may also influence the decision<\/strong><\/h2>\n\n\n\n<p>Depending on the agent framework (Anthropic\u2019s, OpenAI\u2019s, LangChain, or even your own custom MCP runner):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The \u201csystem prompt\u201d may strongly encourage tool usage<\/li>\n\n\n\n<li>Some frameworks inject \u201cuse a tool if\u2026 rules\u201d<\/li>\n\n\n\n<li>Some frameworks forbid the model from answering directly in certain domains<\/li>\n\n\n\n<li>Some attach safety rails (e.g., \u201cnever call X tool without explicit user confirmation\u201d)<\/li>\n<\/ul>\n\n\n\n<p>These meta-rules significantly affect tool selection.<\/p>\n\n\n\n<p>Note that the MCP server NEVER sends a system prompt. The MCP server only provides:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>tools \u2192 list of tool descriptions<\/li>\n\n\n\n<li>resources<\/li>\n\n\n\n<li>prompts<\/li>\n\n\n\n<li>executable operations when the model calls them<br><\/li>\n<\/ul>\n\n\n\n<p>But the MCP server <strong>never<\/strong> includes actual pre-instructions for the LLM.<\/p>\n\n\n\n<p>This is intentional.<\/p>\n\n\n\n<p>The system prompt must come from the <em>client<\/em> who is orchestrating the conversation. Let\u2019s use the Claude Desktop Agent as an example of an MCP client.&nbsp;<\/p>\n\n\n\n<p>When you add an MCP server to Claude Desktop, the sequence looks like:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Claude loads your MCP manifest<\/li>\n\n\n\n<li>Claude indexes your MCP tools<\/li>\n\n\n\n<li>Claude writes the system prompt internally (you never see it)<\/li>\n\n\n\n<li>Claude injects imported tool descriptions into the context<\/li>\n\n\n\n<li>Claude responds to user messages<\/li>\n<\/ol>\n\n\n\n<p>You cannot change the system prompt in Claude Desktop today. The client controls it, not the tool server.<\/p>\n\n\n\n<p>If you build your own agent using, say, the official Node SDK (@modelcontextprotocol\/sdk), you can certainly provide your own system prompt.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1019\" height=\"1024\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1019x1024.jpg\" alt=\"\" class=\"wp-image-45061\" style=\"width:488px;height:auto\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1019x1024.jpg 1019w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-300x300.jpg 300w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-150x150.jpg 150w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-768x772.jpg 768w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts.jpg 1194w\" sizes=\"auto, (max-width: 1019px) 100vw, 1019px\" \/><\/figure>\n\n\n\n<p>Here, you, as the developer, decide the system prompt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-the-system-prompt-and-tool-descriptions-merge\"><strong>How the System Prompt and Tool Descriptions Merge<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"936\" height=\"272\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1.jpg\" alt=\"\" class=\"wp-image-45062\" style=\"width:485px;height:auto\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1.jpg 936w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1-300x87.jpg 300w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-1-768x223.jpg 768w\" sizes=\"auto, (max-width: 936px) 100vw, 936px\" \/><\/figure>\n\n\n\n<p>This is exactly what Agents like ChatGPT and Claude Desktop do behind the scenes.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-when-the-model-decides-not-to-call-a-tool\"><strong>When the model decides <\/strong><strong><em>not<\/em><\/strong><strong> to call a tool<\/strong><\/h2>\n\n\n\n<p>The model avoids tools in these cases:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The user asks a conceptual question that the model can answer. For example: \u201cWhat\u2019s the difference between OAuth and OpenID Connect?\u201d<\/li>\n\n\n\n<li>The tool\u2019s description is unclear or mismatched. For example, if your tool says \u201cGetItem\u201d but the description doesn\u2019t explain what item, the model will most likely ignore the Tool.<\/li>\n\n\n\n<li>The tool appears risky or destructive. (\u201cdelete\u201d, \u201cmodify\u201d, etc. \u2014 unless explicitly instructed)<\/li>\n\n\n\n<li>The model isn\u2019t confident that it can satisfy the schema. For example, if the user gives incomplete parameters and the model can\u2019t infer them, it probably won\u2019t call the tool.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-models-also-learn-from-prior-tool-calls-in-the-conversation\"><strong>Models also learn from prior tool calls in the conversation<\/strong><\/h2>\n\n\n\n<p>The more carefully you write:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>tool names<\/li>\n\n\n\n<li>descriptions<\/li>\n\n\n\n<li>examples<\/li>\n\n\n\n<li>schema<\/li>\n<\/ul>\n\n\n\n<p>\u2026the more likely the model will correctly choose them.&nbsp;<\/p>\n\n\n\n<p>Good Tools feel like <em>natural language functions<\/em>.&nbsp;<\/p>\n\n\n\n<p>Bad Tools feel like weird API endpoints the model tries to avoid.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-designing-tools-the-llm-will-actually-use\"><strong>Designing Tools the LLM Will Actually Use<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-use-a-strong-unambiguous-action-oriented-tool-name\"><strong>Use a strong, unambiguous, action-oriented tool name<\/strong><\/h3>\n\n\n\n<p>Bad:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>process<\/li>\n\n\n\n<li>nf-tool<\/li>\n\n\n\n<li>ziti-op<\/li>\n<\/ul>\n\n\n\n<p>Good:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>listIdentities<\/li>\n\n\n\n<li>createTunnel<\/li>\n\n\n\n<li>generateJWT<br><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-description-should-be-one-short-paragraph-telling-the-model-exactly-when-to-use-it\"><strong>Description should be one short paragraph telling the model exactly when to use it<\/strong><\/h3>\n\n\n\n<p>Bad:<\/p>\n\n\n\n<p>\u201cThis tool queries the backend.\u201d<\/p>\n\n\n\n<p>Good:<\/p>\n\n\n\n<p>\u201cUse this tool whenever the user wants to look up the details of a specific identity in Ziti by ID or name.\u201d<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-include-natural-language-cues-that-the-model-will-remember\"><strong>Include natural-language cues that the model will remember<\/strong><\/h3>\n\n\n\n<p>Examples:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cUse <em>only when\u2026<\/em>\u201c<\/li>\n\n\n\n<li>\u201cCall this tool <em>if the user asks for\u2026<\/em>\u201d<\/li>\n\n\n\n<li>\u201cThis tool is used to <em>search<\/em>, <em>fetch<\/em>, <em>modify<\/em>, <em>calculate<\/em>, etc.\u201d<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-tool-descriptions-should-not-be-vague\"><strong>Tool descriptions should not be vague<\/strong><\/h3>\n\n\n\n<p>Don\u2019t use:<\/p>\n\n\n\n<p>\u201cDoes something with deployments.\u201d<\/p>\n\n\n\n<p>Do use:<\/p>\n\n\n\n<p>\u201cReturns full deployment metadata including version, manifest, dependencies, and status, for auditing or debugging.\u201d<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-parameter-names-should-be-obvious-and-self-explanatory\"><strong>Parameter names should be obvious and self-explanatory<\/strong><\/h3>\n\n\n\n<p>Bad:<\/p>\n\n\n\n<p>{ &#8220;id&#8221;: &#8220;string&#8221; }<\/p>\n\n\n\n<p>Good:<\/p>\n\n\n\n<p>{ &#8220;identity_id&#8221;: &#8220;The Ziti identity ID (uuid) to look up.&#8221; }<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-avoid-deeply-nested-schemas\"><strong>Avoid deeply nested schemas<\/strong><\/h3>\n\n\n\n<p>LLMs can struggle with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>huge nested objects<\/li>\n\n\n\n<li>recursive schemas<\/li>\n\n\n\n<li>8+ required parameters<br><\/li>\n<\/ul>\n\n\n\n<p>If possible:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>flatten fields<\/li>\n\n\n\n<li>group complex objects into \u201coptions\u201d or \u201cconfig\u201d fields<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-use-examples-when-possible\"><strong>Use examples when possible<\/strong><\/h3>\n\n\n\n<p>Example fields are <em>very<\/em> influential.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-examples-of-great-vs-bad-tool-descriptions\"><strong>Examples of GREAT vs. BAD tool descriptions<\/strong><\/h2>\n\n\n\n<p><strong>Great<\/strong><\/p>\n\n\n\n<p>&#8220;createUser&#8221;: {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&#8220;description&#8221;: &#8220;Create a new user record. Use this when the user asks to register, sign up, or create an account. Requires a unique email.&#8221;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&#8220;parameters&#8221;: { &#8230; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Why it works:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>clear trigger conditions<\/li>\n\n\n\n<li>specific verbs<\/li>\n\n\n\n<li>clear unique requirement<\/li>\n\n\n\n<li>simple schema<br><\/li>\n<\/ul>\n\n\n\n<p><strong>Bad<\/strong><\/p>\n\n\n\n<p>&#8220;createUser&#8221;: {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&#8220;description&#8221;: &#8220;User tool for accounts.&#8221;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&#8220;parameters&#8221;: { &#8230; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Why it fails:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The description does not match any user intent<\/li>\n\n\n\n<li>no triggers<\/li>\n\n\n\n<li>unclear purpose<br><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-demo\"><strong>DEMO<\/strong><\/h2>\n\n\n\n<p>I learned most of what is discussed above while building some MCP Server prototypes related to some AI functionality that NetFoundry will be rolling out soon.<\/p>\n\n\n\n<p>To illustrate what can go wrong if you haphazardly design your Tools, I will show you some real examples, using the Claude Desktop Agent as the client.&nbsp;<\/p>\n\n\n\n<p>I will demonstrate some internal Tool definitions used in an early prototype of an OpenZiti MCP Server, capable of being embedded within the Claude Desktop AI Agent.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>NOTE: <em>This OpenZiti MCP Server is intended to enable the use of natural language for managing a Ziti network. Yes, you heard that correctly&#8230; soon, you will be able to type ordinary human language queries or commands into Claude, and those operations will execute against your selected OpenZiti network. More on this below&#8230;<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>Here is an admittedly contrived, very badly written (and perhaps <em>tortured)<\/em> Tool definition:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"924\" height=\"664\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-2.jpg\" alt=\"\" class=\"wp-image-45063\" style=\"width:437px;height:auto\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-2.jpg 924w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-2-300x216.jpg 300w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-2-768x552.jpg 768w\" sizes=\"auto, (max-width: 924px) 100vw, 924px\" \/><\/figure>\n\n\n\n<p>This Tool has no mention of Ziti or any Ziti constructs (such as Identities).<\/p>\n\n\n\n<p>Let\u2019s find out what happens in Claude if I attempt to accomplish something related to a Ziti network, such as getting a list of existing Identities.&nbsp;<\/p>\n\n\n\n<p>By the way, it is worth noting that the <strong>my_tool<\/strong> Tool in this silly example is actually wired up with a function that can securely access the Ziti Controller\u2019s management API and fetch Identities (<em>the details of which are a topic I will discuss in an upcoming article<\/em>).&nbsp;So, if the Claude Desktop Agent somehow made the association between a user prompt and this&nbsp; <strong>my_tool <\/strong>Tool, then Identity information would indeed be fetched from the Ziti Controller\u2019s management API and returned to Claude.<\/p>\n\n\n\n<p>OK, once my MCP Server and its Tools are installed in Claude Desktop, I can enter the prompt:<\/p>\n\n\n\n<p><strong><em>&nbsp;\u201c<\/em><\/strong><strong><em>can you help me determine what identities exist in the network?<\/em><\/strong><strong><em>\u201d<\/em><\/strong><\/p>\n\n\n\n<p>Claude <em>ponders<\/em> for quite a while, then gives up and says this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"868\" height=\"934\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-3.jpg\" alt=\"\" class=\"wp-image-45064\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-3.jpg 868w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-3-279x300.jpg 279w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-3-768x826.jpg 768w\" sizes=\"auto, (max-width: 868px) 100vw, 868px\" \/><\/figure>\n\n\n\n<p>It is abundantly clear that the Claude Desktop Agent (the MCP client) did not have the necessary data (i.e., the proper vector embeddings) to associate the <strong><em>semantics<\/em><\/strong> contained in the prompt with a Tool capable of carrying out the task.<\/p>\n\n\n\n<p>Claude had no notion of Ziti networks at all, let alone how to obtain a list of Identities that exist in the network. This is not a surprise, given how poorly the contrived Tool definition was written.<\/p>\n\n\n\n<p>Now, let&#8217;s craft a good Tool definition.&nbsp;<\/p>\n\n\n\n<p>We\u2019ll replace the contrived example shown above with a proper one that adheres to best practices concerning Tool definition. We\u2019ll give it a very detailed description, and a name that makes it obvious to the LLM what the Tool is intended for:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"605\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-4-1024x605.jpg\" alt=\"\" class=\"wp-image-45065\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-4-1024x605.jpg 1024w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-4-300x177.jpg 300w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-4-768x454.jpg 768w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-4.jpg 1164w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now watch what happens in Claude after I reinstall my MCP server with this Tool definition, and I then attempt to accomplish the same task of listing existing Identities.<\/p>\n\n\n\n<p>When I re-enter the same prompt:&nbsp;<\/p>\n\n\n\n<p><strong><em>\u201c<\/em><\/strong><strong><em>can you help me determine what identities exist in the network?<\/em><\/strong><strong><em>\u201d<\/em><\/strong><\/p>\n\n\n\n<p>Claude now says this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"947\" height=\"1024\" src=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-5-947x1024.jpg\" alt=\"\" class=\"wp-image-45066\" srcset=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-5-947x1024.jpg 947w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-5-277x300.jpg 277w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-5-768x831.jpg 768w, https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/ts-5.jpg 1324w\" sizes=\"auto, (max-width: 947px) 100vw, 947px\" \/><\/figure>\n\n\n\n<p>Success!<\/p>\n\n\n\n<p>As you can see, since the Agent was provided a proper Tool definition, the LLM was allowed to generate proper embeddings for the Tool, then use the embeddings to understand the <strong>semantic meaning <\/strong>of the<strong> <\/strong>prompt, then associate that meaning with the appropriate Tool, and finally send a request to the Tool best suited to carry out the task.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>The OpenZiti MCP Server highlighted in the DEMO section above is capable of being embedded within Claude Desktop, so you can also use natural language to manage your Ziti network.<\/p>\n\n\n\n<p>What\u2019s also exciting is that this OpenZiti MCP Server is also capable of being embedded into the many AI Coding Agents available today (e.g., <a href=\"https:\/\/cursor.com\/\">Cursor<\/a>, <a href=\"https:\/\/windsurf.com\/\">Windsurf<\/a>, <a href=\"https:\/\/code.visualstudio.com\/\">VSCode<\/a>). This will allow developers to integrate OpenZiti SDKs into their applications much more quickly and easily (watch for upcoming articles on that).<\/p>\n\n\n\n<p>As an engineer at NetFoundry, I am involved in crafting OpenZiti and related technologies, such as the OpenZiti MCP Server you saw glimpses of above.<\/p>\n\n\n\n<p>If using natural language to manage your Ziti network sounds interesting to you, <a href=\"https:\/\/forms.gle\/HK6te9QugcKQwXmo7\"><strong>please use this form to express your interest.<\/strong><\/a>&nbsp; We are wrapping up the initial version of this MCP server, and you can be among the first to try out the beta\u2026so be sure to get on the list.<\/p>\n\n\n\n<p>Beyond this discussion of local, Agent-embedded MCP servers, if you run your own MCP servers that are accessed remotely over the internet, and you are curious about how to protect them with secure access, in a simplified manner, we can help. So <a href=\"https:\/\/netfoundry.io\/lets-talk\/\"><strong>reach out and talk to us<\/strong><\/a>.&nbsp;<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introducing an OpenZiti MCP Server<\/p>\n","protected":false},"author":116,"featured_media":45059,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[470],"tags":[],"class_list":["post-45058","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How an AI Agent Decides to Call MCP Tools - NetFoundry<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How an AI Agent Decides to Call MCP Tools\" \/>\n<meta property=\"og:description\" content=\"Introducing an OpenZiti MCP Server\" \/>\n<meta property=\"og:url\" content=\"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/\" \/>\n<meta property=\"og:site_name\" content=\"NetFoundry\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/netfoundry.io\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-20T20:44:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-20T21:17:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"708\" \/>\n\t<meta property=\"og:image:height\" content=\"264\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Curt Tudor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@netfoundry\" \/>\n<meta name=\"twitter:site\" content=\"@netfoundry\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Curt Tudor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/\"},\"author\":{\"name\":\"Curt Tudor\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#\\\/schema\\\/person\\\/3ffae2075a283a90dc02d2ee3f336b51\"},\"headline\":\"How an AI Agent Decides to Call MCP Tools\",\"datePublished\":\"2025-11-20T20:44:37+00:00\",\"dateModified\":\"2025-11-20T21:17:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/\"},\"wordCount\":2285,\"publisher\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2025\\\/11\\\/mcp-tools.jpg\",\"articleSection\":[\"AI\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/\",\"url\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/\",\"name\":\"How an AI Agent Decides to Call MCP Tools - NetFoundry\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2025\\\/11\\\/mcp-tools.jpg\",\"datePublished\":\"2025-11-20T20:44:37+00:00\",\"dateModified\":\"2025-11-20T21:17:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#primaryimage\",\"url\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2025\\\/11\\\/mcp-tools.jpg\",\"contentUrl\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2025\\\/11\\\/mcp-tools.jpg\",\"width\":708,\"height\":264,\"caption\":\"OpenZiti MCP Server\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/ai\\\/how-an-ai-agent-decides-to-call-mcp-tools\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/netfoundry.io\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How an AI Agent Decides to Call MCP Tools\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#website\",\"url\":\"https:\\\/\\\/netfoundry.io\\\/\",\"name\":\"NetFoundry\",\"description\":\"Identity-First\u2122 Networking\",\"publisher\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/netfoundry.io\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#organization\",\"name\":\"NetFoundry\",\"url\":\"https:\\\/\\\/netfoundry.io\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/netfoundry-icon-color.png\",\"contentUrl\":\"https:\\\/\\\/netfoundry.io\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/netfoundry-icon-color.png\",\"width\":512,\"height\":512,\"caption\":\"NetFoundry\"},\"image\":{\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/netfoundry.io\",\"https:\\\/\\\/x.com\\\/netfoundry\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/netfoundry\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCGN6PFj1rZu50yme9YsICmg\",\"https:\\\/\\\/www.instagram.com\\\/netfoundry.io\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/netfoundry.io\\\/#\\\/schema\\\/person\\\/3ffae2075a283a90dc02d2ee3f336b51\",\"name\":\"Curt Tudor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g\",\"caption\":\"Curt Tudor\"},\"url\":\"https:\\\/\\\/netfoundry.io\\\/author\\\/curt-tudor\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How an AI Agent Decides to Call MCP Tools - NetFoundry","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:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/","og_locale":"en_US","og_type":"article","og_title":"How an AI Agent Decides to Call MCP Tools","og_description":"Introducing an OpenZiti MCP Server","og_url":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/","og_site_name":"NetFoundry","article_publisher":"https:\/\/www.facebook.com\/netfoundry.io","article_published_time":"2025-11-20T20:44:37+00:00","article_modified_time":"2025-11-20T21:17:58+00:00","og_image":[{"width":708,"height":264,"url":"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg","type":"image\/jpeg"}],"author":"Curt Tudor","twitter_card":"summary_large_image","twitter_creator":"@netfoundry","twitter_site":"@netfoundry","twitter_misc":{"Written by":"Curt Tudor","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#article","isPartOf":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/"},"author":{"name":"Curt Tudor","@id":"https:\/\/netfoundry.io\/#\/schema\/person\/3ffae2075a283a90dc02d2ee3f336b51"},"headline":"How an AI Agent Decides to Call MCP Tools","datePublished":"2025-11-20T20:44:37+00:00","dateModified":"2025-11-20T21:17:58+00:00","mainEntityOfPage":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/"},"wordCount":2285,"publisher":{"@id":"https:\/\/netfoundry.io\/#organization"},"image":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#primaryimage"},"thumbnailUrl":"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg","articleSection":["AI"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/","url":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/","name":"How an AI Agent Decides to Call MCP Tools - NetFoundry","isPartOf":{"@id":"https:\/\/netfoundry.io\/#website"},"primaryImageOfPage":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#primaryimage"},"image":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#primaryimage"},"thumbnailUrl":"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg","datePublished":"2025-11-20T20:44:37+00:00","dateModified":"2025-11-20T21:17:58+00:00","breadcrumb":{"@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#primaryimage","url":"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg","contentUrl":"https:\/\/netfoundry.io\/wp-content\/uploads\/2025\/11\/mcp-tools.jpg","width":708,"height":264,"caption":"OpenZiti MCP Server"},{"@type":"BreadcrumbList","@id":"https:\/\/netfoundry.io\/ai\/how-an-ai-agent-decides-to-call-mcp-tools\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/netfoundry.io\/"},{"@type":"ListItem","position":2,"name":"How an AI Agent Decides to Call MCP Tools"}]},{"@type":"WebSite","@id":"https:\/\/netfoundry.io\/#website","url":"https:\/\/netfoundry.io\/","name":"NetFoundry","description":"Identity-First\u2122 Networking","publisher":{"@id":"https:\/\/netfoundry.io\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/netfoundry.io\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/netfoundry.io\/#organization","name":"NetFoundry","url":"https:\/\/netfoundry.io\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/netfoundry.io\/#\/schema\/logo\/image\/","url":"https:\/\/netfoundry.io\/wp-content\/uploads\/2024\/08\/netfoundry-icon-color.png","contentUrl":"https:\/\/netfoundry.io\/wp-content\/uploads\/2024\/08\/netfoundry-icon-color.png","width":512,"height":512,"caption":"NetFoundry"},"image":{"@id":"https:\/\/netfoundry.io\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/netfoundry.io","https:\/\/x.com\/netfoundry","https:\/\/www.linkedin.com\/company\/netfoundry\/","https:\/\/www.youtube.com\/channel\/UCGN6PFj1rZu50yme9YsICmg","https:\/\/www.instagram.com\/netfoundry.io"]},{"@type":"Person","@id":"https:\/\/netfoundry.io\/#\/schema\/person\/3ffae2075a283a90dc02d2ee3f336b51","name":"Curt Tudor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/18ee19a7ad900fbeac2921a2299c0a0458af7296c4d43eb3705639d18e9c9cb9?s=96&d=mm&r=g","caption":"Curt Tudor"},"url":"https:\/\/netfoundry.io\/author\/curt-tudor\/"}]}},"_links":{"self":[{"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/posts\/45058","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/users\/116"}],"replies":[{"embeddable":true,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/comments?post=45058"}],"version-history":[{"count":0,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/posts\/45058\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/media\/45059"}],"wp:attachment":[{"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/media?parent=45058"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/categories?post=45058"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/netfoundry.io\/wp-json\/wp\/v2\/tags?post=45058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}