Building a Weather MCP Tool: Complete Walkthrough
Build a real, working weather MCP tool — from API key to mcpm publish.
What You'll Build
A weather MCP server with:
get_current_weather — current conditions for any city
get_forecast — 5-day forecast
- Proper error handling
- Unit conversion (celsius/fahrenheit)
Step 1: Get an API Key
Sign up for a free OpenWeatherMap API key at https://openweathermap.org/api.
Free tier: 60 calls/minute, plenty for personal use.
Step 2: Initialize
<span class="hljs-built_in">mkdir</span> weather-mcp && <span class="hljs-built_in">cd</span> weather-mcp
npm init -y
npm install @modelcontextprotocol/sdk
Step 3: Write the Server
Create index.js:
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Server</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/index.js"</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">StdioServerTransport</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/stdio.js"</span>;
<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">API_KEY</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">OPENWEATHER_API_KEY</span>;
<span class="hljs-keyword">if</span> (!<span class="hljs-variable constant_">API_KEY</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">"OPENWEATHER_API_KEY environment variable is required"</span>);
process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>);
}
<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Server</span>({
<span class="hljs-attr">name</span>: <span class="hljs-string">"weather-mcp"</span>,
<span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span>,
}, {
<span class="hljs-attr">capabilities</span>: { <span class="hljs-attr">tools</span>: {} }
});
server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/list"</span>, <span class="hljs-title function_">async</span> () => ({
<span class="hljs-attr">tools</span>: [
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"get_current_weather"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Get current weather conditions for any city"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">city</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"City name (e.g., 'London', 'Tokyo', 'San Francisco')"</span>
},
<span class="hljs-attr">units</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">enum</span>: [<span class="hljs-string">"celsius"</span>, <span class="hljs-string">"fahrenheit"</span>],
<span class="hljs-attr">description</span>: <span class="hljs-string">"Temperature unit (default: celsius)"</span>
}
},
<span class="hljs-attr">required</span>: [<span class="hljs-string">"city"</span>]
}
},
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"get_forecast"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Get 5-day weather forecast for any city"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">city</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"City name"</span>
},
<span class="hljs-attr">days</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"number"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Number of days to forecast (1-5, default: 3)"</span>
}
},
<span class="hljs-attr">required</span>: [<span class="hljs-string">"city"</span>]
}
}
]
}));
server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/call"</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">const</span> { name, <span class="hljs-attr">arguments</span>: args } = request.<span class="hljs-property">params</span>;
<span class="hljs-keyword">switch</span> (name) {
<span class="hljs-keyword">case</span> <span class="hljs-string">"get_current_weather"</span>: {
<span class="hljs-keyword">const</span> { city, units = <span class="hljs-string">"celsius"</span> } = args;
<span class="hljs-keyword">const</span> unitParam = units === <span class="hljs-string">"fahrenheit"</span> ? <span class="hljs-string">"imperial"</span> : <span class="hljs-string">"metric"</span>;
<span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(
<span class="hljs-string">`https://api.openweathermap.org/data/2.5/weather?q=<span class="hljs-subst">${<span class="hljs-built_in">encodeURIComponent</span>(city)}</span>&units=<span class="hljs-subst">${unitParam}</span>&appid=<span class="hljs-subst">${API_KEY}</span>`</span>
);
<span class="hljs-keyword">if</span> (!resp.<span class="hljs-property">ok</span>) {
<span class="hljs-keyword">const</span> err = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>();
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Weather not found: <span class="hljs-subst">${err.message || city}</span>`</span> }]
};
}
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>();
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`🌤️ <span class="hljs-subst">${data.name}</span>, <span class="hljs-subst">${data.sys.country}</span>
`</span> +
<span class="hljs-string">` Temperature: <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.round(data.main.temp)}</span>°<span class="hljs-subst">${units === <span class="hljs-string">"fahrenheit"</span> ? <span class="hljs-string">"F"</span> : <span class="hljs-string">"C"</span>}</span>
`</span> +
<span class="hljs-string">` Feels like: <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.round(data.main.feels_like)}</span>°
`</span> +
<span class="hljs-string">` Condition: <span class="hljs-subst">${data.weather[<span class="hljs-number">0</span>].description}</span>
`</span> +
<span class="hljs-string">` Humidity: <span class="hljs-subst">${data.main.humidity}</span>%
`</span> +
<span class="hljs-string">` Wind: <span class="hljs-subst">${data.wind.speed}</span> m/s`</span>
}]
};
}
<span class="hljs-keyword">case</span> <span class="hljs-string">"get_forecast"</span>: {
<span class="hljs-keyword">const</span> { city, days = <span class="hljs-number">3</span> } = args;
<span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(
<span class="hljs-string">`https://api.openweathermap.org/data/2.5/forecast?q=<span class="hljs-subst">${<span class="hljs-built_in">encodeURIComponent</span>(city)}</span>&units=metric&appid=<span class="hljs-subst">${API_KEY}</span>`</span>
);
<span class="hljs-keyword">if</span> (!resp.<span class="hljs-property">ok</span>) {
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Forecast not available for: <span class="hljs-subst">${city}</span>`</span> }]
};
}
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>();
<span class="hljs-keyword">const</span> daily = {};
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> entry <span class="hljs-keyword">of</span> data.<span class="hljs-property">list</span>) {
<span class="hljs-keyword">const</span> date = entry.<span class="hljs-property">dt_txt</span>.<span class="hljs-title function_">split</span>(<span class="hljs-string">" "</span>)[<span class="hljs-number">0</span>];
<span class="hljs-keyword">if</span> (!daily[date]) {
daily[date] = { <span class="hljs-attr">temps</span>: [], <span class="hljs-attr">conditions</span>: [] };
}
daily[date].<span class="hljs-property">temps</span>.<span class="hljs-title function_">push</span>(entry.<span class="hljs-property">main</span>.<span class="hljs-property">temp</span>);
daily[date].<span class="hljs-property">conditions</span>.<span class="hljs-title function_">push</span>(entry.<span class="hljs-property">weather</span>[<span class="hljs-number">0</span>].<span class="hljs-property">description</span>);
}
<span class="hljs-keyword">const</span> forecast = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(daily).<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, days).<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">[date, d]</span>) =></span> {
<span class="hljs-keyword">const</span> avg = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(d.<span class="hljs-property">temps</span>.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =></span> a + b, <span class="hljs-number">0</span>) / d.<span class="hljs-property">temps</span>.<span class="hljs-property">length</span>);
<span class="hljs-keyword">const</span> mostCommon = d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">sort</span>(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =></span>
d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">v</span> =></span> v === a).<span class="hljs-property">length</span> - d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">v</span> =></span> v === b).<span class="hljs-property">length</span>
).<span class="hljs-title function_">pop</span>();
<span class="hljs-keyword">return</span> <span class="hljs-string">` <span class="hljs-subst">${date}</span>: <span class="hljs-subst">${avg}</span>°C, <span class="hljs-subst">${mostCommon}</span>`</span>;
}).<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>);
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`📅 <span class="hljs-subst">${days}</span>-Day Forecast for <span class="hljs-subst">${data.city.name}</span>:
<span class="hljs-subst">${forecast}</span>`</span>
}]
};
}
<span class="hljs-attr">default</span>:
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">`Unknown tool: <span class="hljs-subst">${name}</span>`</span>);
}
});
<span class="hljs-keyword">const</span> transport = <span class="hljs-keyword">new</span> <span class="hljs-title class_">StdioServerTransport</span>();
<span class="hljs-keyword">await</span> server.<span class="hljs-title function_">connect</span>(transport);
Step 4: Test Locally
OPENWEATHER_API_KEY=your_key node index.js
Step 5: Write README.md
<span class="hljs-section"># Weather MCP</span>
Get real-time weather and forecasts via MCP.
<span class="hljs-section">## Install</span>
\<span class="hljs-code">`\`</span>\`bash
mcpm-dev add weather-mcp
\<span class="hljs-code">`\`</span>\`
<span class="hljs-section">## Setup</span>
Get a free API key at https://openweathermap.org/api
<span class="hljs-section">## Tools</span>
See full documentation at https://www.mcpm.dev/packages/weather-mcp
Step 6: Publish
mcpm-dev login
mcpm-dev publish
Key Takeaways
- API keys in env vars — never hardcode
- Handle errors gracefully — agents need clear messages
- Encode user input —
encodeURIComponent() is essential
- Format output for readability — use emoji and newlines
Your weather MCP tool is live! 🎉
#MCP #Tutorial #Weather #mcpm #NodeJS
Building a Weather MCP Tool: Complete Walkthrough
Build a real, working weather MCP tool — from API key to mcpm publish.
What You'll Build
A weather MCP server with:
get_current_weather— current conditions for any cityget_forecast— 5-day forecastStep 1: Get an API Key
Sign up for a free OpenWeatherMap API key at https://openweathermap.org/api.
Free tier: 60 calls/minute, plenty for personal use.
Step 2: Initialize
<span class="hljs-built_in">mkdir</span> weather-mcp && <span class="hljs-built_in">cd</span> weather-mcp npm init -y npm install @modelcontextprotocol/sdkStep 3: Write the Server
Create
index.js:<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Server</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/index.js"</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">StdioServerTransport</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/stdio.js"</span>; <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">API_KEY</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">OPENWEATHER_API_KEY</span>; <span class="hljs-keyword">if</span> (!<span class="hljs-variable constant_">API_KEY</span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">"OPENWEATHER_API_KEY environment variable is required"</span>); process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>); } <span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Server</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">"weather-mcp"</span>, <span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span>, }, { <span class="hljs-attr">capabilities</span>: { <span class="hljs-attr">tools</span>: {} } }); server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/list"</span>, <span class="hljs-title function_">async</span> () => ({ <span class="hljs-attr">tools</span>: [ { <span class="hljs-attr">name</span>: <span class="hljs-string">"get_current_weather"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Get current weather conditions for any city"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">city</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"City name (e.g., 'London', 'Tokyo', 'San Francisco')"</span> }, <span class="hljs-attr">units</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">enum</span>: [<span class="hljs-string">"celsius"</span>, <span class="hljs-string">"fahrenheit"</span>], <span class="hljs-attr">description</span>: <span class="hljs-string">"Temperature unit (default: celsius)"</span> } }, <span class="hljs-attr">required</span>: [<span class="hljs-string">"city"</span>] } }, { <span class="hljs-attr">name</span>: <span class="hljs-string">"get_forecast"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Get 5-day weather forecast for any city"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">city</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"City name"</span> }, <span class="hljs-attr">days</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"number"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Number of days to forecast (1-5, default: 3)"</span> } }, <span class="hljs-attr">required</span>: [<span class="hljs-string">"city"</span>] } } ] })); server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/call"</span>, <span class="hljs-title function_">async</span> (request) => { <span class="hljs-keyword">const</span> { name, <span class="hljs-attr">arguments</span>: args } = request.<span class="hljs-property">params</span>; <span class="hljs-keyword">switch</span> (name) { <span class="hljs-keyword">case</span> <span class="hljs-string">"get_current_weather"</span>: { <span class="hljs-keyword">const</span> { city, units = <span class="hljs-string">"celsius"</span> } = args; <span class="hljs-keyword">const</span> unitParam = units === <span class="hljs-string">"fahrenheit"</span> ? <span class="hljs-string">"imperial"</span> : <span class="hljs-string">"metric"</span>; <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>( <span class="hljs-string">`https://api.openweathermap.org/data/2.5/weather?q=<span class="hljs-subst">${<span class="hljs-built_in">encodeURIComponent</span>(city)}</span>&units=<span class="hljs-subst">${unitParam}</span>&appid=<span class="hljs-subst">${API_KEY}</span>`</span> ); <span class="hljs-keyword">if</span> (!resp.<span class="hljs-property">ok</span>) { <span class="hljs-keyword">const</span> err = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>(); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Weather not found: <span class="hljs-subst">${err.message || city}</span>`</span> }] }; } <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>(); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`🌤️ <span class="hljs-subst">${data.name}</span>, <span class="hljs-subst">${data.sys.country}</span> `</span> + <span class="hljs-string">` Temperature: <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.round(data.main.temp)}</span>°<span class="hljs-subst">${units === <span class="hljs-string">"fahrenheit"</span> ? <span class="hljs-string">"F"</span> : <span class="hljs-string">"C"</span>}</span> `</span> + <span class="hljs-string">` Feels like: <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.round(data.main.feels_like)}</span>° `</span> + <span class="hljs-string">` Condition: <span class="hljs-subst">${data.weather[<span class="hljs-number">0</span>].description}</span> `</span> + <span class="hljs-string">` Humidity: <span class="hljs-subst">${data.main.humidity}</span>% `</span> + <span class="hljs-string">` Wind: <span class="hljs-subst">${data.wind.speed}</span> m/s`</span> }] }; } <span class="hljs-keyword">case</span> <span class="hljs-string">"get_forecast"</span>: { <span class="hljs-keyword">const</span> { city, days = <span class="hljs-number">3</span> } = args; <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>( <span class="hljs-string">`https://api.openweathermap.org/data/2.5/forecast?q=<span class="hljs-subst">${<span class="hljs-built_in">encodeURIComponent</span>(city)}</span>&units=metric&appid=<span class="hljs-subst">${API_KEY}</span>`</span> ); <span class="hljs-keyword">if</span> (!resp.<span class="hljs-property">ok</span>) { <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Forecast not available for: <span class="hljs-subst">${city}</span>`</span> }] }; } <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.<span class="hljs-title function_">json</span>(); <span class="hljs-keyword">const</span> daily = {}; <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> entry <span class="hljs-keyword">of</span> data.<span class="hljs-property">list</span>) { <span class="hljs-keyword">const</span> date = entry.<span class="hljs-property">dt_txt</span>.<span class="hljs-title function_">split</span>(<span class="hljs-string">" "</span>)[<span class="hljs-number">0</span>]; <span class="hljs-keyword">if</span> (!daily[date]) { daily[date] = { <span class="hljs-attr">temps</span>: [], <span class="hljs-attr">conditions</span>: [] }; } daily[date].<span class="hljs-property">temps</span>.<span class="hljs-title function_">push</span>(entry.<span class="hljs-property">main</span>.<span class="hljs-property">temp</span>); daily[date].<span class="hljs-property">conditions</span>.<span class="hljs-title function_">push</span>(entry.<span class="hljs-property">weather</span>[<span class="hljs-number">0</span>].<span class="hljs-property">description</span>); } <span class="hljs-keyword">const</span> forecast = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(daily).<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, days).<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">[date, d]</span>) =></span> { <span class="hljs-keyword">const</span> avg = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(d.<span class="hljs-property">temps</span>.<span class="hljs-title function_">reduce</span>(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =></span> a + b, <span class="hljs-number">0</span>) / d.<span class="hljs-property">temps</span>.<span class="hljs-property">length</span>); <span class="hljs-keyword">const</span> mostCommon = d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">sort</span>(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =></span> d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">v</span> =></span> v === a).<span class="hljs-property">length</span> - d.<span class="hljs-property">conditions</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">v</span> =></span> v === b).<span class="hljs-property">length</span> ).<span class="hljs-title function_">pop</span>(); <span class="hljs-keyword">return</span> <span class="hljs-string">` <span class="hljs-subst">${date}</span>: <span class="hljs-subst">${avg}</span>°C, <span class="hljs-subst">${mostCommon}</span>`</span>; }).<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`📅 <span class="hljs-subst">${days}</span>-Day Forecast for <span class="hljs-subst">${data.city.name}</span>: <span class="hljs-subst">${forecast}</span>`</span> }] }; } <span class="hljs-attr">default</span>: <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">`Unknown tool: <span class="hljs-subst">${name}</span>`</span>); } }); <span class="hljs-keyword">const</span> transport = <span class="hljs-keyword">new</span> <span class="hljs-title class_">StdioServerTransport</span>(); <span class="hljs-keyword">await</span> server.<span class="hljs-title function_">connect</span>(transport);Step 4: Test Locally
Step 5: Write README.md
<span class="hljs-section"># Weather MCP</span> Get real-time weather and forecasts via MCP. <span class="hljs-section">## Install</span> \<span class="hljs-code">`\`</span>\`bash mcpm-dev add weather-mcp \<span class="hljs-code">`\`</span>\` <span class="hljs-section">## Setup</span> Get a free API key at https://openweathermap.org/api <span class="hljs-section">## Tools</span> See full documentation at https://www.mcpm.dev/packages/weather-mcpStep 6: Publish
Key Takeaways
encodeURIComponent()is essentialYour weather MCP tool is live! 🎉
#MCP #Tutorial #Weather #mcpm #NodeJS