<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OLI Untangled</title>
    <description>The latest articles on DEV Community by OLI Untangled (@oliuntangled).</description>
    <link>https://dev.to/oliuntangled</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4005413%2F3078c740-28a0-4820-99b2-f4b3464521f4.png</url>
      <title>DEV Community: OLI Untangled</title>
      <link>https://dev.to/oliuntangled</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oliuntangled"/>
    <language>en</language>
    <item>
      <title>webmcp-gen: Generate Chrome WebMCP Tool Definitions from TypeScript</title>
      <dc:creator>OLI Untangled</dc:creator>
      <pubDate>Sun, 28 Jun 2026 08:52:48 +0000</pubDate>
      <link>https://dev.to/oliuntangled/webmcp-gen-generate-chrome-webmcp-tool-definitions-from-typescript-17ag</link>
      <guid>https://dev.to/oliuntangled/webmcp-gen-generate-chrome-webmcp-tool-definitions-from-typescript-17ag</guid>
      <description>&lt;p&gt;Chrome 149 shipped WebMCP — a browser-native API that lets web pages expose structured tools to AI agents via &lt;code&gt;navigator.modelContext&lt;/code&gt;. The ecosystem is forming fast: &lt;a href="https://github.com/keak-ai/webmcp-core" rel="noopener noreferrer"&gt;webmcp-core&lt;/a&gt; crawls live sites to auto-generate tool definitions, and &lt;a href="https://github.com/WebMCP-Registry/kit" rel="noopener noreferrer"&gt;@webmcp-registry/kit&lt;/a&gt; provides a runtime SDK with Zod-based &lt;code&gt;defineTool()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What's missing is &lt;strong&gt;build-time codegen from your existing TypeScript&lt;/strong&gt;. If you already have typed interfaces for your API, you shouldn't have to rewrite them as Zod schemas or wait for a crawler to discover them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;webmcp-gen&lt;/strong&gt; fills that gap. Write your API as TypeScript interfaces, run one command, get spec-compliant WebMCP tool definitions + handler stubs with security best practices baked in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fits
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;webmcp-core&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Crawl a live URL&lt;/td&gt;
&lt;td&gt;You have a site, want tools auto-discovered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;@webmcp-registry/kit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zod schemas at runtime&lt;/td&gt;
&lt;td&gt;You want runtime registration + React hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;webmcp-gen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TypeScript interfaces at build time&lt;/td&gt;
&lt;td&gt;You have typed TS, want static JSON + stubs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They're complementary — different layers for different workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api.ts&lt;/span&gt;

&lt;span class="cm"&gt;/** Search products by keyword. */&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SearchProducts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;category&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electronics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clothing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx webmcp-gen &lt;span class="nt"&gt;--api&lt;/span&gt; api.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output: a &lt;code&gt;.webmcp.json&lt;/code&gt; definition + a &lt;code&gt;.handler.ts&lt;/code&gt; stub with &lt;code&gt;navigator.modelContext.registerTool()&lt;/code&gt; wired up and ready to implement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Parses TypeScript interfaces and type aliases via ts-morph&lt;/li&gt;
&lt;li&gt;Maps TS types to JSON Schema (strings, numbers, enums, arrays, nested objects, optionals)&lt;/li&gt;
&lt;li&gt;Pulls descriptions from JSDoc comments&lt;/li&gt;
&lt;li&gt;Validates output against the WebMCP spec&lt;/li&gt;
&lt;li&gt;Generates handler stubs with Google's security guidance built in:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;requestUserInteraction()&lt;/code&gt; reminders for mutating tools&lt;/li&gt;
&lt;li&gt;Input sanitisation warnings for freeform string inputs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;readOnlyHint&lt;/code&gt; annotations for query-only tools&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security by default
&lt;/h2&gt;

&lt;p&gt;WebMCP allows AI agents to execute tools that affect live web applications. Google advises using human-in-the-loop hooks and protecting against indirect prompt injection. webmcp-gen bakes this into every generated handler stub — mutating tools get &lt;code&gt;requestUserInteraction()&lt;/code&gt; reminders, freeform inputs get sanitisation warnings. Safe defaults, not afterthoughts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; webmcp-gen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Includes 4 starter templates (CRUD, search, form handler, data transformer) to get you going:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;webmcp-gen &lt;span class="nt"&gt;--template&lt;/span&gt; crud-api
webmcp-gen &lt;span class="nt"&gt;--api&lt;/span&gt; crud-api.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MIT licensed. Contributions welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  v1.2.0 — security-hardened release
&lt;/h2&gt;

&lt;p&gt;The current npm version (v1.2.0) has been through a 4-agent security audit covering line-by-line diff scanning, cross-file tracing, removed-behavior analysis, and dedicated security review. 10 findings were fixed before public announcement, including injection hardening in generated code, path traversal protection, and Chrome 150 compatibility (the origin trial API moved from &lt;code&gt;navigator.modelContext&lt;/code&gt; to &lt;code&gt;document.modelContext&lt;/code&gt;). Full changelog in the &lt;a href="https://github.com/oliuntangled/webmcp-gen#changelog" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/oliuntangled/webmcp-gen" rel="noopener noreferrer"&gt;oliuntangled/webmcp-gen&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/webmcp-gen" rel="noopener noreferrer"&gt;webmcp-gen&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Not affiliated with or endorsed by Google or the W3C. Built with AI assistance.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>chrome</category>
      <category>typescript</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
