<?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: SilberArrows</title>
    <description>The latest articles on DEV Community by SilberArrows (@silberarrows).</description>
    <link>https://dev.to/silberarrows</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%2F4185349%2F38465c68-dcad-4955-8889-7667c23dcb77.png</url>
      <title>DEV Community: SilberArrows</title>
      <link>https://dev.to/silberarrows</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/silberarrows"/>
    <language>en</language>
    <item>
      <title>Building a Mercedes-Benz Service Reminder MCP Server in TypeScript</title>
      <dc:creator>SilberArrows</dc:creator>
      <pubDate>Wed, 14 Oct 2026 18:56:08 +0000</pubDate>
      <link>https://dev.to/silberarrows/building-a-mercedes-benz-service-reminder-mcp-server-in-typescript-1d9a</link>
      <guid>https://dev.to/silberarrows/building-a-mercedes-benz-service-reminder-mcp-server-in-typescript-1d9a</guid>
      <description>&lt;p&gt;Ask most AI assistants when your Mercedes-Benz is next due for a service and you will get a confident, generic answer. Sometimes it is right, often it is vague, and occasionally it is simply invented. At &lt;a href="https://www.silberarrows.com/" rel="noopener noreferrer"&gt;SilberArrows&lt;/a&gt;, a Mercedes-Benz specialist in Dubai since 2011, we hear the same questions every day from owners: &lt;em&gt;Is it Service A or Service B next? What does it include? Is that warning light serious?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So we built a small, open-source &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; (MCP) server that gives assistants such as Claude, Cursor and ChatGPT a deterministic answer instead of a guess. This article walks through what it does, how it is built, and how to use it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/mercedes-benz-service-reminder-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;mercedes-benz-service-reminder-mcp&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/gentlegiant96202/mercedes-benz-service-reminder-mcp" rel="noopener noreferrer"&gt;gentlegiant96202/mercedes-benz-service-reminder-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Remote endpoint: &lt;code&gt;https://silberarrows-mcp.netlify.app/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why an MCP server, not a prompt
&lt;/h2&gt;

&lt;p&gt;A language model is good at conversation and poor at date arithmetic. Working out the next service involves two moving targets, time and distance, and the answer is whichever arrives first. It also alternates: on most modern models, Mercedes-Benz uses an ASSYST-style schedule in which Service A and Service B take turns, typically every 15,000 km or 12 months.&lt;/p&gt;

&lt;p&gt;MCP lets us move that logic out of the model and into a tool. The assistant handles the conversation; the server does the maths and returns structured JSON. The result is the same every time, and it is testable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four tools
&lt;/h2&gt;

&lt;p&gt;The server exposes four tools:&lt;/p&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;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_next_service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Next service type (A or B), due date, due mileage and status from the last service details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;explain_service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What a Mercedes-Benz Service A or Service B typically includes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;warning_light_info&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General guidance on common warning lights (check engine, limp mode, ABS/ESP, battery, service due)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find_specialist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contact details for a Mercedes-Benz specialist in Dubai&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There are no accounts, no API keys for local use, no network calls and no data collection. Everything runs on the user's machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it is built
&lt;/h2&gt;

&lt;p&gt;The server uses the official TypeScript SDK (&lt;code&gt;@modelcontextprotocol/sdk&lt;/code&gt;) and &lt;code&gt;zod&lt;/code&gt; for input validation. Registering a tool is short:&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_next_service&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;Estimate the next Mercedes-Benz service (alternating Service A/B, ASSYST-style).&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="na"&gt;last_service_type&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;A&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;B&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;a&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;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="na"&gt;last_service_date&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;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;YYYY-MM-DD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;last_service_km&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;nonnegative&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;current_km&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;nonnegative&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;interval_months&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;int&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;36&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;interval_km&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;int&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;1000&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;50000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;out&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;computeNextService&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="cm"&gt;/* mapped inputs */&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;The &lt;code&gt;zod&lt;/code&gt; schema matters more than it looks. It becomes the JSON Schema the assistant sees, so clear &lt;code&gt;.describe()&lt;/code&gt; text on each field is effectively prompt engineering. A well-described parameter means the model asks the owner for the date of the last service instead of guessing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the dates right
&lt;/h3&gt;

&lt;p&gt;The core logic lives in a pure function, &lt;code&gt;computeNextService&lt;/code&gt;, which makes it easy to unit test. A few details are worth mentioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UTC calendar days.&lt;/strong&gt; All dates are handled as UTC midnight, so daylight-saving changes and time zones cannot shift a due date by a day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Month-end clamping.&lt;/strong&gt; Adding 12 months to 29 February, or one month to 31 January, clamps to the last valid day instead of spilling into the following month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whichever comes first.&lt;/strong&gt; When the current mileage is supplied, the server estimates the daily distance driven and compares the mileage due date with the time due date. It then reports which one applies (&lt;code&gt;dueBy: "time"&lt;/code&gt; or &lt;code&gt;"mileage"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status.&lt;/strong&gt; Results are flagged as &lt;code&gt;ok&lt;/code&gt;, &lt;code&gt;due-soon&lt;/code&gt; (within 30 days or 1,500 km) or &lt;code&gt;overdue&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every response carries a disclaimer: intervals are general guidance, and owners should always follow their own vehicle's ASSYST indicator and the manufacturer's schedule for their model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping the content factual
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;explain_service&lt;/code&gt; and &lt;code&gt;warning_light_info&lt;/code&gt; return curated, deliberately conservative text. A flashing check-engine light, for example, is treated as "reduce load and stop when safe", never as a diagnosis. Where an owner wants more depth, responses point to longer guides such as our breakdown of &lt;a href="https://mercedes-benz.silberarrows.com/blog/mercedes-benz-service-a-costs-in-dubai-a-detailed-breakdown" rel="noopener noreferrer"&gt;Mercedes-Benz Service A costs in Dubai&lt;/a&gt; and our &lt;a href="https://mercedes-benz.silberarrows.com/services/scheduled-maintenance" rel="noopener noreferrer"&gt;scheduled maintenance&lt;/a&gt; page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two transports, one server
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;createServer()&lt;/code&gt; factory is transport-agnostic. The npm package wires it to stdio for desktop clients. The same factory also runs as a stateless streamable-HTTP function on Netlify at &lt;code&gt;https://silberarrows-mcp.netlify.app/mcp&lt;/code&gt;, for clients that only accept remote servers. An optional API key is supported for the hosted endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Claude Desktop or Cursor
&lt;/h3&gt;

&lt;p&gt;Add the following to &lt;code&gt;claude_desktop_config.json&lt;/code&gt; or &lt;code&gt;~/.cursor/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;"mercedes-benz-service-reminder"&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;"npx"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mercedes-benz-service-reminder-mcp"&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;Node.js 18 or later is required. Nothing else needs to be installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remote clients
&lt;/h3&gt;

&lt;p&gt;Point any client that supports streamable HTTP at &lt;code&gt;https://silberarrows-mcp.netlify.app/mcp&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it
&lt;/h3&gt;

&lt;p&gt;Once it is connected, ask your assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"My Mercedes-Benz had a Service A on 1 March 2026 at 40,000 km and it's now on 50,000 km. When is the next service?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The assistant calls &lt;code&gt;get_next_service&lt;/code&gt; and receives structured output: next type &lt;code&gt;B&lt;/code&gt;, due by time on 1 March 2027 or at 55,000 km, with an estimated date based on your driving rate. You can follow up with &lt;em&gt;"What does Service B include?"&lt;/em&gt; or &lt;em&gt;"My dashboard shows a yellow engine light, what should I do?"&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Small tools beat big prompts.&lt;/strong&gt; Four focused tools with tight schemas outperform a long system prompt full of service rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descriptions are the interface.&lt;/strong&gt; Most of the quality improvement came from rewriting tool and parameter descriptions, not from code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be honest about limits.&lt;/strong&gt; A service reminder is guidance. Saying so in every response builds more trust than false precision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish everywhere developers look.&lt;/strong&gt; We published to npm and the official MCP Registry and added a Dockerfile, so the same server reaches every client.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  About SilberArrows
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://mercedes-benz.silberarrows.com/" rel="noopener noreferrer"&gt;SilberArrows&lt;/a&gt; is an independent Mercedes-Benz service centre in Al Quoz, Dubai, founded in 2011. We specialise in &lt;a href="https://mercedes-benz.silberarrows.com/services" rel="noopener noreferrer"&gt;Mercedes-Benz servicing and repairs&lt;/a&gt;, &lt;a href="https://mercedes-benz.silberarrows.com/service-contracts" rel="noopener noreferrer"&gt;service contracts&lt;/a&gt; and &lt;a href="https://mercedes-benz.silberarrows.com/service-pricing" rel="noopener noreferrer"&gt;transparent service pricing&lt;/a&gt;. If your assistant tells you a service is due, you can &lt;a href="https://mercedes-benz.silberarrows.com/contact" rel="noopener noreferrer"&gt;contact us&lt;/a&gt; or call +971 4 380 5515.&lt;/p&gt;

&lt;p&gt;The server is MIT-licensed, and issues and pull requests are welcome on &lt;a href="https://github.com/gentlegiant96202/mercedes-benz-service-reminder-mcp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

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