<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ToolMesh | Blog</title><description/><link>https://toolmesh.io/</link><language>de</language><item><title>Populating NetBox from Real Infrastructure with ToolMesh</title><link>https://toolmesh.io/de/blog/populating-netbox-from-real-infrastructure/</link><guid isPermaLink="true">https://toolmesh.io/de/blog/populating-netbox-from-real-infrastructure/</guid><description>How to use ToolMesh connectors to populate a fresh NetBox instance from Linode, Hetzner Cloud, Xen Orchestra and other sources — with a trust-building approach from import to autopilot.

</description><pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A typical scenario: three cloud providers, two hypervisors, a handful of edge sites. Somewhere around 200 devices and VMs, give or take. You spin up NetBox, stare at the empty dashboard, and realize the real work hasn’t started. Writing import scripts for five different APIs is a week of work you don’t want to do — so NetBox sits empty, and the spreadsheet wins again.&lt;/p&gt;
&lt;p&gt;This post shows how to skip that week. We walk through using ToolMesh to pull live infrastructure data from multiple sources and push it into NetBox via the NetBox DADL connector. For the business case and broader “why,” read the companion post on &lt;a href=&quot;https://dunkel.cloud/blog/populating-netbox-from-real-infrastructure&quot;&gt;dunkel.cloud&lt;/a&gt;. Here we focus on the how.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;architecture-overview&quot;&gt;Architecture Overview&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The data flow:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Hetzner Cloud ───┐&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Linode        ───┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Xen Orchestra ───┼── ToolMesh ── NetBox DADL ── NetBox API&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Unifi         ───┤&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Tailscale     ───┘&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each source system has its own API, its own authentication, and its own data model. ToolMesh acts as the gateway: it authenticates against each source using stored credentials, normalizes the responses, and writes the results into NetBox through the NetBox DADL definition.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://toolmesh.io/en/dadl&quot;&gt;DADL&lt;/a&gt; (Declarative API Definition Language) is a YAML-based format that describes REST APIs as tool definitions. Instead of writing a custom MCP server wrapper for each API, you describe the endpoints, parameters, and authentication in one file. ToolMesh turns that description into callable tools at runtime — handling credential injection, authorization, and audit logging automatically. The NetBox DADL covers most of the NetBox REST API; each source DADL covers one cloud or appliance. No custom glue code sits between them.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;mapping-source-objects-to-netbox-objects&quot;&gt;Mapping: Source Objects to NetBox Objects&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The core challenge is translating between data models. A Hetzner “server” becomes a NetBox “device.” A Linode “instance” also becomes a device, but the field names differ. Here is how the main objects map:&lt;/p&gt;



























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Source&lt;/th&gt;&lt;th&gt;Source Object&lt;/th&gt;&lt;th&gt;NetBox Object&lt;/th&gt;&lt;th&gt;Key Fields&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Hetzner Cloud&lt;/td&gt;&lt;td&gt;Server&lt;/td&gt;&lt;td&gt;Device&lt;/td&gt;&lt;td&gt;name, server_type → device_type, datacenter → site&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Hetzner Cloud&lt;/td&gt;&lt;td&gt;Network&lt;/td&gt;&lt;td&gt;Prefix&lt;/td&gt;&lt;td&gt;ip_range → prefix, name → description&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Linode&lt;/td&gt;&lt;td&gt;Instance&lt;/td&gt;&lt;td&gt;Device&lt;/td&gt;&lt;td&gt;label → name, type → device_type, region → site&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Linode&lt;/td&gt;&lt;td&gt;IPv4/IPv6&lt;/td&gt;&lt;td&gt;IP Address&lt;/td&gt;&lt;td&gt;address → address, linode_id → assigned device&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Xen Orchestra&lt;/td&gt;&lt;td&gt;VM&lt;/td&gt;&lt;td&gt;Virtual Machine&lt;/td&gt;&lt;td&gt;name_label → name, power_state → status&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Xen Orchestra&lt;/td&gt;&lt;td&gt;Network&lt;/td&gt;&lt;td&gt;VLAN&lt;/td&gt;&lt;td&gt;name_label → name, MTU&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Unifi&lt;/td&gt;&lt;td&gt;Device&lt;/td&gt;&lt;td&gt;Device&lt;/td&gt;&lt;td&gt;name, model → device_type, site → site&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tailscale&lt;/td&gt;&lt;td&gt;Node&lt;/td&gt;&lt;td&gt;Device&lt;/td&gt;&lt;td&gt;hostname → name, addresses → IP Addresses&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Concretely, a single Hetzner server comes back looking like this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;42891337&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;web-fra-01&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;server_type&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;cx22&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;cores&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;memory&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;datacenter&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;fsn1-dc14&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;location&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;name&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;fsn1&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; } },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;public_net&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;ipv4&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;ip&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;95.217.xx.xx&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; } },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;status&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;running&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;After ToolMesh runs it through the NetBox DADL, that single source object produces three linked NetBox records: a &lt;code dir=&quot;auto&quot;&gt;Site&lt;/code&gt; (&lt;code dir=&quot;auto&quot;&gt;fsn1&lt;/code&gt;), a &lt;code dir=&quot;auto&quot;&gt;DeviceType&lt;/code&gt; (&lt;code dir=&quot;auto&quot;&gt;cx22&lt;/code&gt;, 2 cores, 4 GB), and a &lt;code dir=&quot;auto&quot;&gt;Device&lt;/code&gt; (&lt;code dir=&quot;auto&quot;&gt;web-fra-01&lt;/code&gt;) with a primary IP attached. The &lt;code dir=&quot;auto&quot;&gt;Site&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;DeviceType&lt;/code&gt; are created once and reused on every subsequent Hetzner server in the same datacenter.&lt;/p&gt;
&lt;p&gt;Mappings are not hardcoded. The field translation logic lives in the orchestration layer between the source DADL and the NetBox DADL. You can override mappings, add custom fields, or skip objects entirely — if your servers encode a role in the hostname (&lt;code dir=&quot;auto&quot;&gt;web-fra-01&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;db-fra-02&lt;/code&gt;), a small transform sets &lt;code dir=&quot;auto&quot;&gt;device_role&lt;/code&gt; accordingly. Dependencies are resolved automatically: prerequisite objects get created before the main record.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-trust-escalation-model&quot;&gt;The Trust Escalation Model&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Blindly syncing cloud inventory into a production NetBox is a reasonable thing to be nervous about. The approach we recommend is graduated trust — start with zero risk and escalate as confidence grows. None of this is a bespoke CLI; it all runs as natural-language prompts to Claude (or any agent) with ToolMesh connected. The examples below are the actual prompts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 1: Initial Import (empty database).&lt;/strong&gt; Before any devices can be created, NetBox needs a minimal scaffold: at least one Site (devices must belong to one), a Manufacturer for device types, and ideally a Tenant for organizational grouping. Give Claude the facts about your infrastructure and let it set things up:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Set up NetBox for my company. Our tenant is “Acme GmbH”. I run infrastructure in two regions: Linode Frankfurt (&lt;code dir=&quot;auto&quot;&gt;eu-central&lt;/code&gt;) and Linode Amsterdam (&lt;code dir=&quot;auto&quot;&gt;nl-ams&lt;/code&gt;) — create those as Sites under a region called “Europe”. The Manufacturer for all Linode instances is “Akamai/Linode”. Once that’s in place, import all my Linode instances as Devices, create the matching Device Types (g6-standard-2, g6-standard-4, etc.) on the fly, and attach their public IPv4 and IPv6 addresses. NetBox is empty, so no dry-run needed — just do it and show me a summary when done.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude calls the Linode tools to list instances, the NetBox tools to create sites, tenant, manufacturer, device types, devices, and IPs in the right order. The summary at the end tells you how many of each were created.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 2: Read-only Diff.&lt;/strong&gt; Once NetBox has data, the next check asks what would change without touching anything:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Compare my current Linode instances with what’s in NetBox. Don’t change anything — just tell me the differences in plain English.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The response is prose, not a machine diff:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I compared 23 Linode instances against the 22 devices in NetBox tagged &lt;code dir=&quot;auto&quot;&gt;source=linode&lt;/code&gt;. Four differences:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;New instance&lt;/strong&gt;: &lt;code dir=&quot;auto&quot;&gt;db-ams-04&lt;/code&gt; exists at Linode (region &lt;code dir=&quot;auto&quot;&gt;nl-ams&lt;/code&gt;, type &lt;code dir=&quot;auto&quot;&gt;g6-standard-4&lt;/code&gt;, created yesterday) but isn’t in NetBox yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IP change&lt;/strong&gt;: &lt;code dir=&quot;auto&quot;&gt;web-ams-01&lt;/code&gt; has a new primary IPv4 in NetBox (&lt;code dir=&quot;auto&quot;&gt;172.104.x.12&lt;/code&gt;) but Linode now reports &lt;code dir=&quot;auto&quot;&gt;172.104.x.47&lt;/code&gt;. Looks like it was rebuilt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Status drift&lt;/strong&gt;: &lt;code dir=&quot;auto&quot;&gt;worker-ams-03&lt;/code&gt; is marked &lt;code dir=&quot;auto&quot;&gt;active&lt;/code&gt; in NetBox, but Linode reports it as &lt;code dir=&quot;auto&quot;&gt;offline&lt;/code&gt; (powered off 6 days ago).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Missing at source&lt;/strong&gt;: &lt;code dir=&quot;auto&quot;&gt;legacy-bastion-ams&lt;/code&gt; exists in NetBox but is no longer at Linode. Probably decommissioned — worth confirming before I touch it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Want me to apply 1–3 and flag 4 for your review?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is where most of the trust gets built. You see exactly what would happen, in language you can audit at a glance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 3: Reconcile with Confirmation.&lt;/strong&gt; Apply the changes with a human in the loop on anything destructive:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Go ahead with 1, 2, and 3. For anything that deletes or marks a device as decommissioned, ask me first.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Creates and updates happen straight away; the legacy bastion triggers a confirmation prompt (“Delete &lt;code dir=&quot;auto&quot;&gt;legacy-bastion-ams&lt;/code&gt; from NetBox, or mark it &lt;code dir=&quot;auto&quot;&gt;decommissioning&lt;/code&gt; and keep the record? [delete / decommission / skip]”) before anything irreversible happens. Destructive operations always require explicit confirmation, even once the workflow is automated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 4: Scheduled Sync.&lt;/strong&gt; Once the mapping is trustworthy, hand the workflow to a scheduled agent:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every hour, pull the current Linode state and reconcile it with NetBox. Apply additions and field updates automatically. For anything that would delete a device or change its status to decommissioned, open a ticket in our tracker instead of acting — I’ll review those manually.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ToolMesh runs the prompt on the schedule, the agent does the same work it did interactively, and destructive actions stay gated on human review. New servers appear in NetBox minutes after provisioning. Every tool call lands in the audit log, so you can always ask later &lt;em&gt;what&lt;/em&gt; got changed, &lt;em&gt;when&lt;/em&gt;, and &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The NetBox DADL connector covers most of the NetBox 4.x REST API. Source connectors for Hetzner Cloud, Linode, Xen Orchestra, Unifi, and Tailscale are available today. If you run infrastructure that is not covered yet, a new DADL file takes minutes, not days — check the &lt;a href=&quot;https://dadl.ai&quot;&gt;DADL registry&lt;/a&gt; for existing definitions or contribute on &lt;a href=&quot;https://github.com/ToolMesh&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The real payoff lands after the import. A populated NetBox is not just documentation — it becomes the substrate an AI agent can reason over. “Which servers in Falkenstein are running kernel 5.x and need a reboot window next Tuesday?” is a NetBox query plus a ToolMesh tool call, not a week of shell scripts. That is why we started here: NetBox is the map, ToolMesh is how agents read and redraw it safely.&lt;/p&gt;
&lt;p&gt;For the strategic angle, read the full analysis on &lt;a href=&quot;https://dunkel.cloud/blog/populating-netbox-from-real-infrastructure&quot;&gt;dunkel.cloud&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>NetBox</category><category>DADL</category><category>Tutorial</category><category>Infrastructure</category></item><item><title>Introducing ToolMesh — The Missing Control Layer for AI Agents</title><link>https://toolmesh.io/de/blog/introducing-toolmesh/</link><guid isPermaLink="true">https://toolmesh.io/de/blog/introducing-toolmesh/</guid><description>AI agents are reaching production faster than governance can keep up. ToolMesh is the missing control layer between AI agents and enterprise systems — governing tool calls and connecting any API in minutes.

</description><pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI agents are reaching production systems faster than security and governance can keep up. Teams connect agents to CRMs, cloud APIs, internal databases, ticketing systems, and IoT devices — but the infrastructure between the agent and those systems is still held together with environment variables and good intentions.&lt;/p&gt;
&lt;p&gt;The typical setup looks like this: an MCP server has direct access to API keys, every connected agent gets full access to every tool, and there is no record of what was called, when, or by whom. That works for a prototype. It does not work when the agent talks to Stripe, your HR system, and your cloud provider in the same session.&lt;/p&gt;
&lt;p&gt;The problem compounds in enterprises. Organizations run dozens of backend systems across teams and departments. Each one needs its own integration, its own credentials, its own access policy. Without a central control layer, every new agent connection is a new unaudited trust relationship — and the attack surface grows with each one.&lt;/p&gt;
&lt;p&gt;ToolMesh is our answer to that gap.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;what-toolmesh-is&quot;&gt;What ToolMesh is&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;ToolMesh is the missing control layer between AI agents and enterprise systems. It sits between AI agents and backend systems, turning uncontrolled tool calls into a governed, auditable process — and connecting any REST API or MCP server in minutes, not months.&lt;/p&gt;
&lt;p&gt;Every tool call flows through a strict pipeline: &lt;strong&gt;Auth → AuthZ → Credential Injection → Execution → Output Gate → Audit.&lt;/strong&gt; If any step does not explicitly allow the request, nothing happens. The model never sees raw secrets. Every call is logged. Output can be filtered before it reaches the agent.&lt;/p&gt;
&lt;p&gt;It runs as a single binary or Docker container. It is Apache 2.0 licensed. There is no SaaS dependency.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-six-pillars&quot;&gt;The six pillars&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;ToolMesh is built around six concerns that most agent setups handle inconsistently or not at all.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-authentication&quot;&gt;1. Authentication&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;ToolMesh supports OAuth 2.1 with PKCE for interactive clients like Claude Desktop, API keys for programmatic access, and multi-user setups via a &lt;code dir=&quot;auto&quot;&gt;users.yaml&lt;/code&gt; configuration. Every request is authenticated before it enters the pipeline.&lt;/p&gt;
&lt;p&gt;For quick starts, a single environment variable is enough. For production, you get per-user identity with roles, plans, and company context — without changing the architecture.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2-authorization&quot;&gt;2. Authorization&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Access control is per-tool and per-user, powered by OpenFGA. DADL tools declare an &lt;code dir=&quot;auto&quot;&gt;access&lt;/code&gt; level — &lt;code dir=&quot;auto&quot;&gt;read&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;write&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;admin&lt;/code&gt;, or &lt;code dir=&quot;auto&quot;&gt;dangerous&lt;/code&gt; — and policy files map those levels to roles. If the caller is not authorized for that specific tool, the request is denied before execution.&lt;/p&gt;
&lt;p&gt;ToolMesh also tracks CallerClass: which AI client triggered the request. A local Claude Code session can have different permissions than a hosted agent or a CI bot hitting the same API. Same backend, different trust levels, enforced automatically.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;3-credential-store&quot;&gt;3. Credential Store&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;This is the concern most setups quietly ignore. In a typical MCP configuration, API keys sit in client configs or environment variables — visible to the model, scattered across machines, impossible to rotate centrally.&lt;/p&gt;
&lt;p&gt;ToolMesh injects credentials at runtime, server-side. The model sees the tool interface and the filtered result. It never sees the token, the key, or the session cookie. Credentials are referenced by name in the DADL file and resolved from the credential store at execution time.&lt;/p&gt;
&lt;p&gt;The default store reads from environment variables. The architecture supports pluggable backends for centralized secret management (planned: Infisical, HashiCorp Vault).&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;4-output-gate&quot;&gt;4. Output Gate&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Not every API response should reach the model unchanged. Customer records may contain PII. Internal systems may return metadata that is irrelevant or sensitive. Error messages may leak infrastructure details.&lt;/p&gt;
&lt;p&gt;The Output Gate runs JavaScript policies (via the goja engine) that can validate inputs before execution and filter outputs afterward. Use cases range from PII redaction to compliance filtering to rejecting dangerous inputs entirely. Policies are reviewable code, not black boxes.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;5-execution&quot;&gt;5. Execution&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;ToolMesh connects two types of backends:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DADL backends&lt;/strong&gt; describe REST APIs declaratively in YAML. A &lt;code dir=&quot;auto&quot;&gt;.dadl&lt;/code&gt; file defines endpoints, parameters, authentication, error handling, pagination, and retry logic. ToolMesh turns that description into MCP tools at runtime — no custom server code needed. The public &lt;a href=&quot;https://dadl.ai&quot;&gt;DADL registry&lt;/a&gt; currently includes definitions for 14 APIs covering 1,100+ tools across providers like GitHub, Cloudflare, GitLab, Stripe, DeepL, Hetzner Cloud, and others.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MCP server backends&lt;/strong&gt; connect existing MCP servers via HTTP or STDIO transport. If you already have a working MCP server, ToolMesh wraps it with the same authorization, credential, and audit pipeline.&lt;/p&gt;
&lt;p&gt;Both types go through the same fail-closed pipeline. The backend type is an implementation detail — the security guarantees are the same.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;6-audit-trail&quot;&gt;6. Audit Trail&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Every tool call is recorded: who called it, which tool, with what parameters, what the result was, how long it took, and whether it succeeded. ToolMesh ships with two audit backends — structured logging via &lt;code dir=&quot;auto&quot;&gt;slog&lt;/code&gt; for simple setups, and an append-only SQLite store for queryable compliance audits.&lt;/p&gt;
&lt;p&gt;When someone asks “what did that agent do last Tuesday,” you can answer with a SQL query instead of a shrug.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;dadl-declare-instead-of-code&quot;&gt;DADL: declare instead of code&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The integration problem in agent tooling is not the protocol. MCP solved that. The problem is that every new API still requires a new MCP server — a new codebase, a new runtime, a new maintenance burden. Most teams stop after a handful of integrations because the per-API cost is too high.&lt;/p&gt;
&lt;p&gt;DADL (Declarative API Description Language) takes a different approach. Instead of writing a custom server for each API, you describe the API in YAML:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;deepl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;rest&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;base_url&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;https://api.deepl.com/v2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;auth&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;bearer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;credential&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;deepl_auth_key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;tools&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;method&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;POST&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/translate&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;access&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Translate text into a target language&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;target_lang&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That is a complete tool definition. ToolMesh handles authentication, parameter mapping, error handling, retries, and credential injection at runtime.&lt;/p&gt;
&lt;p&gt;Because DADL is compact and declarative, LLMs can generate working definitions from existing API documentation. Most of the 14 definitions in the registry were produced by Claude from API docs in under a minute, then reviewed and tuned. The format is designed to be AI-native: easy for machines to produce, easy for humans to review.&lt;/p&gt;
&lt;p&gt;We wrote a separate deep-dive on this: &lt;a href=&quot;https://toolmesh.io/blog/dadl-the-end-of-mcp-server-boilerplate/&quot;&gt;Stop Rebuilding REST API Wrappers for MCP&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;code-mode-scaling-that-otherwise-doesnt-work&quot;&gt;Code Mode: scaling that otherwise doesn’t work&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Connect 15 MCP servers to a single AI agent? Without ToolMesh, that simply does not work — the context window fills up, the client chokes. With ToolMesh, it is not a problem.&lt;/p&gt;
&lt;p&gt;Instead of exposing hundreds of individual MCP tools, ToolMesh exposes two meta-tools: &lt;code dir=&quot;auto&quot;&gt;list_tools&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;execute_code&lt;/code&gt;. The model gets a compact TypeScript interface description (~1,000 tokens instead of 50,000+) and writes JavaScript against it. One code block can chain multiple API calls in a single round-trip.&lt;/p&gt;
&lt;p&gt;That is the difference between “doesn’t work” and “just runs.”&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;self-hosted-open-source&quot;&gt;Self-hosted, open source&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;ToolMesh is Apache 2.0 licensed. The binary is self-contained — no external dependencies for the core feature set. &lt;code dir=&quot;auto&quot;&gt;docker compose up&lt;/code&gt; gets you a running instance with OAuth, audit logging, and a set of DADL backends.&lt;/p&gt;
&lt;p&gt;There is no cloud dependency. Your credentials, your audit logs, your policies — all on your infrastructure. The core is and will remain open source.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The fastest path from zero to a working setup:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone the repo and run &lt;code dir=&quot;auto&quot;&gt;docker compose up&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configure your MCP client to point at ToolMesh&lt;/li&gt;
&lt;li&gt;Make your first tool call&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&quot;https://toolmesh.io/getting-started&quot;&gt;Getting Started guide&lt;/a&gt; walks through this in detail. The &lt;a href=&quot;https://toolmesh.io/architecture&quot;&gt;Architecture overview&lt;/a&gt; explains how the pipeline works. The &lt;a href=&quot;https://dadl.ai&quot;&gt;DADL registry&lt;/a&gt; has ready-to-use definitions for 14 APIs.&lt;/p&gt;
&lt;p&gt;ToolMesh is on &lt;a href=&quot;https://github.com/DunkelCloud/ToolMesh&quot;&gt;GitHub&lt;/a&gt;. Issues, feedback, and DADL contributions are welcome.&lt;/p&gt;</content:encoded><category>announcement</category><category>ToolMesh</category><category>MCP</category><category>Security</category></item><item><title>Stop Rebuilding REST API Wrappers for MCP</title><link>https://toolmesh.io/de/blog/dadl-the-end-of-mcp-server-boilerplate/</link><guid isPermaLink="true">https://toolmesh.io/de/blog/dadl-the-end-of-mcp-server-boilerplate/</guid><description>Even a stripped-down MCP wrapper is 90 lines of TypeScript. Production wrappers grow past 200. The same integration in DADL takes 40 lines of YAML — and the real gain is not the line count.

</description><pubDate>Fri, 03 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every REST-to-MCP wrapper starts the same way. You pick an API, open the docs, and begin writing glue code. Authentication, parameter mapping, error handling, pagination, retries, response shaping. Two hundred lines later, you have one integration. Then you do it again for the next API.&lt;/p&gt;
&lt;p&gt;The real cost is not the 200 lines. It is reimplementing execution policy — credential handling, access control, audit logging — around every single wrapper. That work is expensive, repetitive, and difficult to scale.&lt;/p&gt;
&lt;p&gt;DADL takes a different approach: instead of writing a custom wrapper for every REST API, you describe the API declaratively. ToolMesh turns that description into tools and handles runtime concerns — including the ones most wrappers quietly ignore: credential isolation, authorization, and audit logging.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-wrapper-you-keep-rebuilding&quot;&gt;The wrapper you keep rebuilding&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here is a minimal MCP server for a single DeepL translation endpoint in TypeScript. Stripped down — no tests, no retries, no pagination, no rate limiting:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { Server } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;@modelcontextprotocol/sdk/server/index.js&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { StdioServerTransport } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;@modelcontextprotocol/sdk/server/stdio.js&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;CallToolRequestSchema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ListToolsRequestSchema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;@modelcontextprotocol/sdk/types.js&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;API_KEY&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DEEPL_API_KEY&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;API_KEY&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;DEEPL_API_KEY required&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Server&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ name: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;deepl-mcp&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, version: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;1.0.0&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ capabilities: { tools: {} } }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setRequestHandler&lt;/span&gt;&lt;span&gt;(ListToolsRequestSchema, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tools: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Translate text into a target language. &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Supports up to 50 texts per request.&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputSchema: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;properties: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;items: { type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Array of texts to translate&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;target_lang: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Target language code (EN-US, DE, FR ...)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;source_lang: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Source language code. Omit for auto-detect&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;formality: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;enum: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;more&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;less&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;prefer_more&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;prefer_less&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;required: [&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;target_lang&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;setRequestHandler&lt;/span&gt;&lt;span&gt;(CallToolRequestSchema, &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;Unknown tool: &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const { &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;target_lang&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;source_lang&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;formality&lt;/span&gt;&lt;span&gt; } =&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arguments&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt; = { &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;target_lang&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (source_lang) body&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;source_lang&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; source_lang;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (formality) body&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;formality&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; formality;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt; = await &lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;https://api.deepl.com/v2/translate&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;method: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;POST&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;headers: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Authorization: &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;DeepL-Auth-Key &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;API_KEY&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Content-Type&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;application/json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;body: &lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;(body)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ok&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt; = await &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;content: [{ type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, text: &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;DeepL error &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;status&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt; }],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;isError: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt; = await &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;content: [{ type: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, text: &lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;(data, &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;) }],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;transport&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StdioServerTransport&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; server&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;connect&lt;/span&gt;&lt;span&gt;(transport);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That is &lt;strong&gt;90 lines&lt;/strong&gt; for a single endpoint — already stripped to the minimum. No retries. No rate limit handling. No pagination. No structured error mapping. And the API key lives in an environment variable, where credentials are often distributed across client and server configs without centralized governance.&lt;/p&gt;
&lt;p&gt;A production-grade wrapper with multiple endpoints, proper error handling, retry logic, and rate limiting easily grows past &lt;strong&gt;200 lines&lt;/strong&gt; — plus a &lt;code dir=&quot;auto&quot;&gt;package.json&lt;/code&gt;, a build step, and a process to keep running.&lt;/p&gt;
&lt;p&gt;Now multiply that by every API you want to connect.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-same-integration-in-dadl&quot;&gt;The same integration in DADL&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here is the same DeepL translation tool described in DADL:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;deepl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;rest&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;base_url&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;https://api.deepl.com/v2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;DeepL translation API&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;auth&lt;/span&gt;&lt;span&gt;:                              &lt;/span&gt;&lt;span&gt;# ← credential injection handled by ToolMesh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;bearer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;credential&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;deepl_auth_key&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;#   references a server-side secret, never exposed to the model&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;DeepL-Auth-Key &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;defaults&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;errors&lt;/span&gt;&lt;span&gt;:                          &lt;/span&gt;&lt;span&gt;# ← retry and error handling for all tools&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;retry_on&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;429&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;502&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;503&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;529&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;retry_strategy&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;max_retries&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;backoff&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;exponential&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;initial_delay&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;tools&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;translate&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;method&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;POST&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/translate&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;access&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;                  &lt;/span&gt;&lt;span&gt;# ← access classification for authorization&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Translate text into a target language&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;params&lt;/span&gt;&lt;span&gt;:                        &lt;/span&gt;&lt;span&gt;# ← parameter mapping: type, location, validation&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Array of texts to translate&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;target_lang&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Target language code (EN-US, DE, FR)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;source_lang&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Source language. Omit for auto-detect&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;formality&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;default, more, less, prefer_more, prefer_less&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;40 lines of YAML.&lt;/strong&gt; No code. No build step. No custom server runtime to build and operate.&lt;/p&gt;
&lt;p&gt;But shorter is not the point. The point is what happens at runtime.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-control-layer-you-are-not-building&quot;&gt;The control layer you are not building&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Most hand-rolled wrappers focus on one thing: making an API callable. They get the request out the door and the response back. That is necessary, but it is not sufficient for production.&lt;/p&gt;
&lt;p&gt;The harder questions are: Who is allowed to call this tool? Where do the credentials live? What happens to sensitive data in the response? Is there an audit trail?&lt;/p&gt;
&lt;p&gt;With a custom wrapper, those concerns either get bolted on after the fact or quietly ignored. With DADL and ToolMesh, they are the default:&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Concern&lt;/th&gt;&lt;th&gt;Custom MCP wrapper&lt;/th&gt;&lt;th&gt;DADL + ToolMesh&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Credentials&lt;/td&gt;&lt;td&gt;In client config, visible to the model&lt;/td&gt;&lt;td&gt;Injected server-side at runtime, never exposed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Authorization&lt;/td&gt;&lt;td&gt;Typically none — full access for everyone&lt;/td&gt;&lt;td&gt;Per-tool, per-user access control&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Audit logging&lt;/td&gt;&lt;td&gt;Not built in&lt;/td&gt;&lt;td&gt;Every call logged and queryable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Output filtering&lt;/td&gt;&lt;td&gt;Not built in&lt;/td&gt;&lt;td&gt;Policies can redact sensitive data before it reaches the model&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Retries&lt;/td&gt;&lt;td&gt;You implement backoff logic&lt;/td&gt;&lt;td&gt;Declared in &lt;code dir=&quot;auto&quot;&gt;retry_strategy&lt;/code&gt;, handled by runtime&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pagination&lt;/td&gt;&lt;td&gt;You build cursor/offset logic&lt;/td&gt;&lt;td&gt;Configured via &lt;code dir=&quot;auto&quot;&gt;pagination.strategy&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Error handling&lt;/td&gt;&lt;td&gt;You parse responses manually&lt;/td&gt;&lt;td&gt;Structured via &lt;code dir=&quot;auto&quot;&gt;errors.message_path&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Deployment&lt;/td&gt;&lt;td&gt;Build, package, run a process&lt;/td&gt;&lt;td&gt;Drop a &lt;code dir=&quot;auto&quot;&gt;.dadl&lt;/code&gt; file into ToolMesh&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;DADL describes what this API is. ToolMesh handles how calls to it are executed and controlled. That separation is the architectural shift that matters — not just the line count.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;you-do-not-write-it--your-llm-does&quot;&gt;You do not write it — your LLM does&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;DADL was designed to be AI-native. The format is compact, declarative, and close to the structure of existing API specifications.&lt;/p&gt;
&lt;p&gt;That means you can hand your LLM an OpenAPI spec, a Swagger definition, or even raw API documentation and ask it to produce a DADL file. In most cases, the result is usable on the first pass. Review it, adjust edge cases, deploy.&lt;/p&gt;
&lt;p&gt;Compare that to asking an LLM to generate a complete MCP server. The model has to produce working code — imports, type definitions, error handling, transport setup, build configuration. Every line is a potential bug. The output needs testing, debugging, and manual validation before it goes anywhere near production.&lt;/p&gt;
&lt;p&gt;With DADL, the LLM produces a data structure. If a field is wrong, you fix one line of YAML. If a parameter is missing, you add three lines. When something breaks, it is more often a reviewable spec issue than an opaque runtime exception buried in generated integration code.&lt;/p&gt;
&lt;p&gt;That is the real unlock. DADL is not just easier for humans to write. It is dramatically easier for AI to produce correctly.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;how-this-scales&quot;&gt;How this scales&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The DeepL example above covers a single endpoint. Real APIs have dozens.&lt;/p&gt;
&lt;p&gt;The full &lt;a href=&quot;https://dadl.ai&quot;&gt;DeepL DADL definition&lt;/a&gt; covers 13 tools — translate, document upload, document status, glossaries, text improvement, language lists, usage tracking — in under 500 lines of YAML. The &lt;a href=&quot;https://dadl.ai&quot;&gt;GitHub definition&lt;/a&gt; covers 202 tools: repositories, issues, pull requests, commits, code search, and more. Building that as a hand-coded MCP server is not a weekend project. It is a product.&lt;/p&gt;
&lt;p&gt;As of today, the &lt;a href=&quot;https://dadl.ai&quot;&gt;DADL registry&lt;/a&gt; contains 11 backend definitions with 985 tools across APIs like GitHub, Cloudflare, Hetzner Cloud, Linode, GitLab, and others. Each one is a single reviewable YAML file.&lt;/p&gt;
&lt;p&gt;As the number of tools grows, there is another scaling concern: context window overhead. ToolMesh addresses this with Code Mode, where the model works through two meta-tools — &lt;code dir=&quot;auto&quot;&gt;list_tools&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;execute_code&lt;/code&gt; — instead of carrying hundreds of tool definitions directly in context. That keeps tool discovery efficient regardless of how many backends are connected.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;what-dadl-does-not-do&quot;&gt;What DADL does not do&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;DADL is a declarative format for describing REST APIs. It is not a workflow engine, not a general-purpose programming language, and not a replacement for every kind of MCP server.&lt;/p&gt;
&lt;p&gt;If your integration needs custom business logic, complex multi-step orchestration, or non-REST protocols, a custom server is still the right choice. ToolMesh can work with those too — it connects both DADL-described backends and existing MCP servers.&lt;/p&gt;
&lt;p&gt;But for the large class of integrations that are fundamentally “call a REST API with the right auth and parameters” — and that is most of them — a custom wrapper is a poor default. It duplicates infrastructure concerns, spreads control logic across codebases, and creates maintenance work that adds no unique value.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-shift&quot;&gt;The shift&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The MCP ecosystem solved the protocol problem. Clients and hosts speak the same language.&lt;/p&gt;
&lt;p&gt;But protocol standardization did not make backend integration cheap. Every new API still meant a new server, a new codebase, a new runtime, a new maintenance burden. That is why most teams stop after a handful of integrations and the long tail of useful APIs stays disconnected.&lt;/p&gt;
&lt;p&gt;DADL changes the unit of work. Instead of “build a server,” the task becomes “describe the API.” Instead of a software project per integration, you get a reviewable YAML file per backend — executed through a runtime that handles security, credentials, and governance centrally.&lt;/p&gt;
&lt;p&gt;That is not just less code. It is less variance, less risk, and a fundamentally better default for connecting AI agents to real systems.&lt;/p&gt;
&lt;p&gt;Explore the &lt;a href=&quot;https://dadl.ai&quot;&gt;DADL registry&lt;/a&gt;, check out the &lt;a href=&quot;https://toolmesh.io/getting-started&quot;&gt;ToolMesh documentation&lt;/a&gt;, or browse the source on &lt;a href=&quot;https://github.com/DunkelCloud/ToolMesh&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>DADL</category><category>MCP</category><category>Developer Experience</category></item><item><title>Why MCP Gateways Alone Don&apos;t Solve the Real Problem</title><link>https://toolmesh.io/de/blog/why-mcp-gateways-alone-dont-solve-the-real-problem/</link><guid isPermaLink="true">https://toolmesh.io/de/blog/why-mcp-gateways-alone-dont-solve-the-real-problem/</guid><description>Gateways are necessary for secure agent execution, but they do not solve the real scaling problem. The MCP era needs a description layer that makes backend creation trivial.

</description><pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI agents touching production systems need two things.&lt;/p&gt;
&lt;p&gt;First, they need a &lt;strong&gt;secure execution layer&lt;/strong&gt;: authentication, authorization, credential isolation, audit logging, output controls, and a runtime that fails closed when something is wrong.&lt;/p&gt;
&lt;p&gt;Second, they need a &lt;strong&gt;cheap way to expose backends&lt;/strong&gt;: not just one or two hand-built integrations, but dozens or hundreds of real systems that can become usable tools without turning every API into a miniature software project.&lt;/p&gt;
&lt;p&gt;Most current MCP discussions focus almost entirely on the first problem.&lt;/p&gt;
&lt;p&gt;That is understandable. The first problem is scary. If an agent can call production tools, the blast radius is real. Credentials leak. PII slips through. Audit trails go missing. One hallucinated call can become an actual incident.&lt;/p&gt;
&lt;p&gt;So yes, gateways matter.&lt;/p&gt;
&lt;p&gt;They are the missing control plane between the model and the systems that matter.&lt;/p&gt;
&lt;p&gt;But they do &lt;strong&gt;not&lt;/strong&gt; solve the deeper scaling problem.&lt;/p&gt;
&lt;p&gt;That problem sits one layer earlier.&lt;/p&gt;
&lt;p&gt;The real bottleneck is not how we proxy tool calls.&lt;/p&gt;
&lt;p&gt;The real bottleneck is that we still make backend creation far too expensive.&lt;/p&gt;
&lt;p&gt;That is why MCP gateways alone do not solve the real problem.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;mcp-solved-the-interface-problem&quot;&gt;MCP solved the interface problem&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;MCP matters because it gives the ecosystem a common way to discover and invoke tools. That is already a major step forward. It reduces one class of integration pain immediately: clients and hosts no longer need a custom protocol for every tool provider.&lt;/p&gt;
&lt;p&gt;That is real progress.&lt;/p&gt;
&lt;p&gt;But it is only one part of the stack.&lt;/p&gt;
&lt;p&gt;A protocol standard is not the same thing as a scalable integration model.&lt;/p&gt;
&lt;p&gt;HTTP did not eliminate the need to design APIs.
OpenAPI did not eliminate the need to build services.
Kubernetes did not eliminate the need to write good applications.&lt;/p&gt;
&lt;p&gt;In the same way, MCP does not eliminate the work required to expose real systems as useful, safe, maintainable tools.&lt;/p&gt;
&lt;p&gt;It standardizes invocation.
It does not make integrations cheap.&lt;/p&gt;
&lt;p&gt;That distinction is easy to miss in early demos because the first few tools are always the easiest ones. A simple GitHub wrapper. A lightweight Stripe example. One internal endpoint turned into a proof of concept.&lt;/p&gt;
&lt;p&gt;That is enough to make the protocol look like the whole story.&lt;/p&gt;
&lt;p&gt;It is not.&lt;/p&gt;
&lt;p&gt;The hard part begins when the question changes from &lt;em&gt;“Can we expose a tool?”&lt;/em&gt; to &lt;em&gt;“Can we expose fifty backends without building fifty small software products?”&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;gateways-solve-runtime-control-not-integration-economics&quot;&gt;Gateways solve runtime control, not integration economics&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;A serious MCP deployment needs a runtime that sits between agents and backends.&lt;/p&gt;
&lt;p&gt;That runtime should verify the caller, enforce authorization, inject credentials at execution time, log every call, and apply output controls before sensitive data reaches the model or the user. It should fail closed. If a check fails, nothing runs.&lt;/p&gt;
&lt;p&gt;That is exactly what a gateway is for.&lt;/p&gt;
&lt;p&gt;And this is where ToolMesh fits: a self-hosted execution layer between agents and infrastructure, enforcing authorization, secret injection, audit logging, and output policies on every tool call. That layer is not optional if your agent touches production systems. It is the difference between a neat demo and a production architecture.&lt;/p&gt;
&lt;p&gt;But a gateway only governs what already exists.&lt;/p&gt;
&lt;p&gt;It can secure tool calls.
It can centralize policy.
It can make execution observable.&lt;/p&gt;
&lt;p&gt;What it cannot do, by itself, is change the cost structure of building the tools in the first place.&lt;/p&gt;
&lt;p&gt;That is the trap many teams are walking into right now.&lt;/p&gt;
&lt;p&gt;They improve the control layer and assume the scalability problem is solved.&lt;/p&gt;
&lt;p&gt;In reality, they have secured the top of the funnel while leaving the creation bottleneck untouched.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-real-nm-problem-is-upstream&quot;&gt;The real N×M problem is upstream&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;People often describe the N×M problem in MCP as a compatibility issue: many clients, many backends, too many custom pairings.&lt;/p&gt;
&lt;p&gt;MCP reduces part of that, which is good.&lt;/p&gt;
&lt;p&gt;But the more painful N×M problem lives upstream.&lt;/p&gt;
&lt;p&gt;It lives in the repeated work required to expose backend after backend after backend.&lt;/p&gt;
&lt;p&gt;For every API, teams end up rebuilding the same bundle of concerns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;auth handling&lt;/li&gt;
&lt;li&gt;parameter mapping&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;retries&lt;/li&gt;
&lt;li&gt;error normalization&lt;/li&gt;
&lt;li&gt;schema shaping&lt;/li&gt;
&lt;li&gt;deployment packaging&lt;/li&gt;
&lt;li&gt;runtime ownership&lt;/li&gt;
&lt;li&gt;maintenance when the API changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sometimes that work is wrapped in a custom MCP server.
Sometimes it becomes a thin adapter.
Sometimes it is disguised as a “small integration.”&lt;/p&gt;
&lt;p&gt;But it is the same pattern every time.&lt;/p&gt;
&lt;p&gt;That is why wrapper-heavy approaches feel fine at the beginning and terrible at scale.&lt;/p&gt;
&lt;p&gt;The first integration is exciting.
The fifth is manageable.
The twelfth is a prioritization problem.
By the twentieth, teams start exposing only the endpoints they absolutely need.&lt;/p&gt;
&lt;p&gt;Everything else falls into the backlog.&lt;/p&gt;
&lt;p&gt;The result is familiar: a landscape of partial wrappers, incomplete coverage, duplicated boilerplate, multiple runtimes, and a long tail of APIs that never become available to agents at all.&lt;/p&gt;
&lt;p&gt;That is not a gateway failure.
It is a backend creation failure.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;better-proxies-do-not-make-backend-creation-trivial&quot;&gt;Better proxies do not make backend creation trivial&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This is the core point.&lt;/p&gt;
&lt;p&gt;A better proxy can improve security, consistency, and observability.&lt;/p&gt;
&lt;p&gt;It cannot make a wrapper stop being a wrapper.&lt;/p&gt;
&lt;p&gt;If every new backend still begins with &lt;em&gt;“someone has to build and operate a custom MCP server”&lt;/em&gt;, the economics are still broken.&lt;/p&gt;
&lt;p&gt;You can put a beautifully engineered gateway in front of that world and it will absolutely improve production readiness.&lt;/p&gt;
&lt;p&gt;But the system will still scale badly because the unit of work is still too expensive.&lt;/p&gt;
&lt;p&gt;Each additional backend still means more code, more packaging, more deployment, more ownership, and more surface area to maintain.&lt;/p&gt;
&lt;p&gt;So the real question is not:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“How do we put a better proxy in front of MCP servers?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The real question is:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“How do we make exposing a backend so cheap that the long tail of useful systems actually gets connected?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That is the point where the conversation needs to shift.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-mcp-stack-is-missing-a-description-layer&quot;&gt;The MCP stack is missing a description layer&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Once you separate the problem cleanly, the architecture becomes obvious.&lt;/p&gt;
&lt;p&gt;The MCP era needs three layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;protocol layer&lt;/strong&gt; for discovery and invocation&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;execution layer&lt;/strong&gt; for governance and runtime control&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;description layer&lt;/strong&gt; that makes backends cheap to expose&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first layer is MCP.
The second layer is the gateway.
The missing third layer is where most ecosystems are still immature.&lt;/p&gt;
&lt;p&gt;Without that third layer, every backend remains a custom engineering exercise.
With it, backend exposure becomes a declarative problem.&lt;/p&gt;
&lt;p&gt;And that changes everything.&lt;/p&gt;
&lt;p&gt;Because descriptions scale differently from code.&lt;/p&gt;
&lt;p&gt;A good description layer moves repeated logic out of bespoke wrappers and into shared runtime behavior. It turns backend exposure from a hand-built server into a compact, reviewable, declarative artifact.&lt;/p&gt;
&lt;p&gt;That is the architectural shift the MCP ecosystem needs if it wants to move beyond a handful of polished demos.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;dadl-is-the-missing-piece&quot;&gt;DADL is the missing piece&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This is exactly where DADL matters.&lt;/p&gt;
&lt;p&gt;DADL, the Dunkel API Description Language, takes a different approach from wrapper-first integration. Instead of writing a custom MCP server for each REST API, the backend is described declaratively in YAML, while the runtime handles the standard mechanics that would otherwise be rebuilt again and again: authentication, pagination, retries, and error mapping.&lt;/p&gt;
&lt;p&gt;That is not just a nicer developer experience.
It is a different cost model.&lt;/p&gt;
&lt;p&gt;Without a description layer, the default unit of work is: &lt;strong&gt;build a server&lt;/strong&gt;.
With a description layer, the unit of work becomes: &lt;strong&gt;describe the backend, review it, and let the runtime execute it safely&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;That is a radically better scaling curve.&lt;/p&gt;
&lt;p&gt;It means teams can expose more of the real API surface instead of stopping after a narrow “good enough” subset.
It means they do not need a separate runtime, dependency tree, Docker image, and maintenance burden for every integration.
It means common integration logic lives where it belongs: in one shared execution environment.&lt;/p&gt;
&lt;p&gt;And because DADL is intentionally compact and close to the structure of existing API specs, it also opens the door to something even more important: modern LLMs can often generate a usable first version from an existing API definition.&lt;/p&gt;
&lt;p&gt;That is where the category really changes.&lt;/p&gt;
&lt;p&gt;Because once the model can help generate the description, and the runtime can safely execute it, the cost of connecting a new backend drops by an order of magnitude.&lt;/p&gt;
&lt;p&gt;That is how you start to unlock the long tail.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-this-is-the-openapi-moment-for-mcp&quot;&gt;Why this is the OpenAPI moment for MCP&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The best analogy here is not “another gateway” or “another wrapper framework.”&lt;/p&gt;
&lt;p&gt;It is OpenAPI.&lt;/p&gt;
&lt;p&gt;OpenAPI did not replace HTTP. It made HTTP ecosystems programmable. It made APIs describable in a way that tools, docs, code generators, and platforms could all understand.&lt;/p&gt;
&lt;p&gt;That shift was not glamorous, but it changed the economics of API work.&lt;/p&gt;
&lt;p&gt;The MCP ecosystem needs the same kind of shift now.&lt;/p&gt;
&lt;p&gt;MCP already standardizes how tools are called.
What it still lacks, in many architectures, is a standard way to describe real backends so that tooling and runtime layers can do the boring work once instead of forcing teams to reimplement it forever.&lt;/p&gt;
&lt;p&gt;That is why DADL is best understood as &lt;strong&gt;OpenAPI for the MCP era&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Not because it replaces MCP.
Not because it replaces a gateway.
But because it fills the missing abstraction layer between raw backend APIs and secure, governable tool execution.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-developers-should-care&quot;&gt;Why developers should care&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;For developers, this is mostly about escaping integration drudgery.&lt;/p&gt;
&lt;p&gt;Most wrapper code is not differentiated engineering. It is repetitive adaptation work that absorbs time, expands maintenance burden, and creates more runtime sprawl than value.&lt;/p&gt;
&lt;p&gt;A declarative backend layer changes that.&lt;/p&gt;
&lt;p&gt;Instead of spending engineering time on the same auth and pagination logic for the tenth time, teams can focus on what actually matters: domain behavior, workflows, guardrails, and the product logic built on top of those tools.&lt;/p&gt;
&lt;p&gt;Just as importantly, lower integration cost increases API coverage.&lt;/p&gt;
&lt;p&gt;That matters a lot.&lt;/p&gt;
&lt;p&gt;Agent systems often underperform not because the model is weak, but because the available tool surface is too thin. The backend may support fifty useful operations, but only six are exposed because wrapping the rest is too expensive.&lt;/p&gt;
&lt;p&gt;When backend creation becomes cheap, the tool layer can start to resemble the actual system instead of the budget constraints of the integration team.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-architects-should-care&quot;&gt;Why architects should care&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;For architects, the value is even clearer.&lt;/p&gt;
&lt;p&gt;A three-layer model separates concerns in the right way.&lt;/p&gt;
&lt;p&gt;MCP handles communication.
The gateway handles trust, control, and auditability.
The description layer handles backend scale.&lt;/p&gt;
&lt;p&gt;That means policy stops depending on how a particular wrapper was written.
Credentials stay outside model context.
Audit becomes consistent.
Security becomes systemic instead of accidental.&lt;/p&gt;
&lt;p&gt;And new integrations can be added without creating a new snowflake service every time.&lt;/p&gt;
&lt;p&gt;That is the kind of architecture enterprises actually want.&lt;/p&gt;
&lt;p&gt;Not a zoo of semi-maintained MCP servers.
Not a future where every new backend implies another runtime to patch and observe.&lt;/p&gt;
&lt;p&gt;They want a stable execution layer and a cheap path for bringing more systems under that layer.&lt;/p&gt;
&lt;p&gt;That is exactly why gateways alone are not enough.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-future-is-not-gateway-versus-description-layer&quot;&gt;The future is not gateway versus description layer&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;It is gateway &lt;strong&gt;plus&lt;/strong&gt; description layer.&lt;/p&gt;
&lt;p&gt;This is not an either-or choice.&lt;/p&gt;
&lt;p&gt;You need MCP because the ecosystem needs a common protocol.
You need a gateway because production tool calls need governance.
And you need a description layer because no organization can afford to scale backend exposure through endless hand-built wrappers.&lt;/p&gt;
&lt;p&gt;That is the stack.&lt;/p&gt;
&lt;p&gt;MCP standardizes invocation.
ToolMesh secures execution.
DADL makes backend creation cheap enough to scale.&lt;/p&gt;
&lt;p&gt;Once you see the problem this way, the market noise gets easier to ignore.&lt;/p&gt;
&lt;p&gt;The winners in this space will not be the teams with the prettiest proxy story.
They will be the teams that solve both sides of the equation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;secure execution for real systems&lt;/li&gt;
&lt;li&gt;trivial creation for real backends&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;the-real-problem&quot;&gt;The real problem&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;So yes, build the gateway.
You need it.&lt;/p&gt;
&lt;p&gt;But do not mistake runtime control for integration scale.&lt;/p&gt;
&lt;p&gt;The real problem is not that MCP needs better proxies.
The real problem is that the ecosystem still treats backend exposure as custom software work when it should be a declarative operation.&lt;/p&gt;
&lt;p&gt;As long as that remains true, the long tail of useful systems will stay disconnected, and agent infrastructure will keep hitting the same ceiling.&lt;/p&gt;
&lt;p&gt;That ceiling does not break when we proxy harder.&lt;/p&gt;
&lt;p&gt;It breaks when backend creation becomes trivial.&lt;/p&gt;
&lt;p&gt;That is why MCP gateways alone do not solve the real problem.&lt;/p&gt;
&lt;p&gt;And that is why DADL matters.&lt;/p&gt;
&lt;p&gt;Not as a convenience feature.
Not as a sidecar format.
But as the missing description layer that turns secure agent tooling from a handcrafted practice into a scalable system.&lt;/p&gt;
&lt;p&gt;In that sense, the real breakthrough is not just safer tool calls.&lt;/p&gt;
&lt;p&gt;It is finally making backend creation cheap enough for the MCP era to scale.&lt;/p&gt;</content:encoded><category>AI</category><category>MCP</category><category>Architecture</category></item></channel></rss>