<?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>Forem: KJ Labs</title>
    <description>The latest articles on Forem by KJ Labs (@kjlabs_dev).</description>
    <link>https://forem.com/kjlabs_dev</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3811486%2Ff7491ae1-8716-4ba1-b1c0-605009051908.png</url>
      <title>Forem: KJ Labs</title>
      <link>https://forem.com/kjlabs_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kjlabs_dev"/>
    <language>en</language>
    <item>
      <title>How to Ship a Production-Ready MCP Server in 15 Minutes (Not Another Toy Example)</title>
      <dc:creator>KJ Labs</dc:creator>
      <pubDate>Sat, 07 Mar 2026 11:39:41 +0000</pubDate>
      <link>https://forem.com/kjlabs_dev/how-to-ship-a-production-ready-mcp-server-in-15-minutes-not-another-toy-example-1n06</link>
      <guid>https://forem.com/kjlabs_dev/how-to-ship-a-production-ready-mcp-server-in-15-minutes-not-another-toy-example-1n06</guid>
      <description>&lt;p&gt;If you've built an MCP server before, you know the drill. You follow a tutorial, get a working "hello world," and then spend the next two weeks bolting on authentication, input validation, error handling, logging, and security hardening before it's anywhere close to deployable.&lt;/p&gt;

&lt;p&gt;This post walks through a TypeScript starter kit that handles all of that out of the box, so you can skip straight to writing your tool's actual logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol is an open standard that lets AI assistants (Claude, Cursor, Windsurf, etc.) call your code as tools. Think of it as a structured API layer between an LLM and your services. You define tools, the assistant discovers them, and calls them with validated inputs. &lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;Spec here.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with most MCP tutorials
&lt;/h2&gt;

&lt;p&gt;Every "Build Your First MCP Server" post gets you to a working stdio server in 10 minutes. Great. But then you need to actually ship it, and you're staring at a checklist like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input validation (not just "trust the LLM")&lt;/li&gt;
&lt;li&gt;Authentication (API keys? JWT?)&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;SSRF protection (your server can make HTTP requests -- can it be tricked into hitting &lt;code&gt;169.254.169.254&lt;/code&gt;?)&lt;/li&gt;
&lt;li&gt;Sandboxed file access (the AI asked to read a file -- should it read &lt;code&gt;/etc/passwd&lt;/code&gt;?)&lt;/li&gt;
&lt;li&gt;Structured logging (not &lt;code&gt;console.log&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Error handling that doesn't crash the process&lt;/li&gt;
&lt;li&gt;Tests. Any tests at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of us end up copy-pasting from three different repos, Googling "node.js SSRF prevention," and hoping we didn't miss anything. I got tired of this, so I built a starter kit that solves the boring parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The starter kit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/junna-legal/mcp-starter-kit" rel="noopener noreferrer"&gt;github.com/junna-legal/mcp-starter-kit&lt;/a&gt; (MIT license, free forever)&lt;/p&gt;

&lt;p&gt;It's a TypeScript project with strict mode, ESM, and 250 tests (including 30+ security-focused cases). It supports both stdio and HTTP (SSE) transports, and works with Claude Code, Claude Desktop, Cursor, and Windsurf.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/junna-legal/mcp-starter-kit.git my-mcp-server
&lt;span class="nb"&gt;cd &lt;/span&gt;my-mcp-server
npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env
npm run db:seed    &lt;span class="c"&gt;# seeds a sample SQLite database&lt;/span&gt;
npm run build
npm run dev        &lt;span class="c"&gt;# starts with hot-reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify everything works, open the MCP Inspector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run inspector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This launches an interactive debugger in your browser where you can call every tool and see the responses. If you see results from &lt;code&gt;database-query&lt;/code&gt;, you're good.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's included
&lt;/h2&gt;

&lt;p&gt;The kit ships with 6 reference tool implementations you can study, copy, or delete:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;database-query&lt;/strong&gt; -- SQLite CRUD with parameterized queries (no injection)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;api-connector&lt;/strong&gt; -- fetch from external REST APIs with SSRF protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;file-manager&lt;/strong&gt; -- sandboxed file operations with symlink escape detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cache-store&lt;/strong&gt; -- TTL-based key-value cache with namespaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;semantic-search&lt;/strong&gt; -- local RAG with embeddings (3 tools + 2 resources + 1 prompt)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;webhook-notifier&lt;/strong&gt; -- async webhook delivery with HMAC-SHA256 signatures&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Beyond the reference tools, here's what the kit handles for you versus what you'd get from a typical tutorial:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Starter Kit&lt;/th&gt;
&lt;th&gt;Typical Tutorial&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transport&lt;/td&gt;
&lt;td&gt;HTTP (SSE) + Stdio&lt;/td&gt;
&lt;td&gt;Stdio only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Zod schemas&lt;/td&gt;
&lt;td&gt;Manual or none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Structured JSON (pino)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;console.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;Graceful + MCP error codes&lt;/td&gt;
&lt;td&gt;Process crash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;API Key + JWT strategies&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limiting&lt;/td&gt;
&lt;td&gt;Token bucket&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Security, specifically
&lt;/h3&gt;

&lt;p&gt;This is where most hand-rolled servers fall short. The kit includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSRF protection&lt;/strong&gt; that blocks private/internal networks (IPv4 + IPv6), including cloud metadata endpoints. DNS resolution is validated to prevent rebinding attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT validation&lt;/strong&gt; that rejects &lt;code&gt;alg:none&lt;/code&gt; and algorithm downgrade attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandboxed file access&lt;/strong&gt; that prevents path traversal and symlink escapes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQL injection prevention&lt;/strong&gt; via strict parameter binding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30+ security test cases&lt;/strong&gt; covering OWASP top threats.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't have to think about any of this. It's already tested and wired in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding your own tool
&lt;/h2&gt;

&lt;p&gt;The kit includes a scaffolding script. Say you want to build a &lt;code&gt;send-email&lt;/code&gt; tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run create-tool send-email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a directory with three files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/tools/send-email/
  index.ts          # registration
  schema.ts         # Zod input schema
  handler.ts        # your business logic
  __tests__/
    handler.test.ts # unit test scaffold
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define your input schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/tools/send-email/schema.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendEmailShape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Must be a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email subject line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Plain-text email body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;low&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;normal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;normal&lt;/span&gt;&lt;span class="dl"&gt;"&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;p&gt;Write your handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/tools/send-email/handler.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../lib/logger.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ToolError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../lib/errors.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SendEmailInput&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schema.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSendEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SendEmailInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sending email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SMTP_HOST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToolError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SMTP_HOST environment variable is not configured&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Your actual email logic here (nodemailer, SendGrid, Resend, etc.)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&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;p&gt;That's it. The framework handles validation, error serialization, and registration with the MCP server automatically. Throw &lt;code&gt;ToolError&lt;/code&gt; for expected failures; unexpected exceptions are caught and returned as structured MCP error responses.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;npm test&lt;/code&gt; to make sure nothing broke, and you're shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to your client
&lt;/h2&gt;

&lt;p&gt;For Claude Code, drop this in your project's &lt;code&gt;.mcp.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"my-server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dist/index.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"LOG_LEVEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"DB_PATH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./data/sample.db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SANDBOX_ROOT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./data/sandbox"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor, Windsurf, and Claude Desktop all work too -- see the &lt;a href="https://github.com/junna-legal/mcp-starter-kit/blob/main/docs/SETUP.md" rel="noopener noreferrer"&gt;setup docs&lt;/a&gt; for their config formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The repo is MIT-licensed. Clone it, delete the reference tools you don't need, add your own, and ship. If you run into issues, the &lt;a href="https://github.com/junna-legal/mcp-starter-kit/blob/main/docs/TROUBLESHOOTING.md" rel="noopener noreferrer"&gt;troubleshooting guide&lt;/a&gt; covers the common ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/junna-legal/mcp-starter-kit" rel="noopener noreferrer"&gt;github.com/junna-legal/mcp-starter-kit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, a star on the repo would be appreciated. If you find a bug, open an issue -- or better yet, a PR.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>typescript</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
