@@ -48,7 +48,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
4848
4949<Steps >
5050 <Step title = " Define types" >
51- Create a file ` types.ts ` , and add the following:
51+ Create a file ` src/ types.ts` , and add the following:
5252
5353 ``` typescript
5454 export interface OpenWeatherResponse {
@@ -85,7 +85,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
8585 }
8686
8787 // Type guard for forecast arguments
88- export function isValidForecastArgs(args : unknown ): args is GetForecastArgs {
88+ export function isValidForecastArgs(args : any ): args is GetForecastArgs {
8989 return (
9090 typeof args === " object" &&
9191 args !== null &&
@@ -98,9 +98,10 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
9898 </Step >
9999
100100 <Step title = " Add the base code" >
101- Replace ` index.ts ` with the following:
101+ Replace ` src/ index.ts` with the following:
102102
103103 ``` typescript
104+ #! / usr / bin / env node
104105 import { Server } from " @modelcontextprotocol/sdk/server/index.js" ;
105106 import { StdioServerTransport } from " @modelcontextprotocol/sdk/server/stdio.js" ;
106107 import {
@@ -116,7 +117,6 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
116117 import {
117118 WeatherData ,
118119 ForecastDay ,
119- GetForecastArgs ,
120120 OpenWeatherResponse ,
121121 isValidForecastArgs
122122 } from " ./types.js" ;
@@ -145,6 +145,11 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
145145 this .server = new Server ({
146146 name: " example-weather-server" ,
147147 version: " 0.1.0"
148+ }, {
149+ capabilities: {
150+ resources: {},
151+ tools: {}
152+ }
148153 });
149154
150155 // Configure axios with defaults
@@ -197,7 +202,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
197202 </Step >
198203
199204 <Step title = " Add resource handlers" >
200- Add this to the ` setupHandlers ` method:
205+ Add this to the ` setupResourceHandlers ` method:
201206
202207 ``` typescript
203208 private setupResourceHandlers (): void {
@@ -263,7 +268,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
263268 </Step >
264269
265270 <Step title = " Add tool handlers" >
266- Add these handlers to the ` setupHandlers ` method:
271+ Add these handlers to the ` setupToolHandlers ` method:
267272
268273 ``` typescript
269274 private setupToolHandlers (): void {
@@ -333,13 +338,21 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
333338 });
334339 }
335340
336- return { toolResult: forecasts };
341+ return {
342+ content: {
343+ mimeType: " application/json" ,
344+ text: JSON .stringify (forecasts , null , 2 )
345+ }
346+ };
337347 } catch (error ) {
338348 if (axios .isAxiosError (error )) {
339- throw new McpError (
340- ErrorCode .InternalError ,
341- ` Weather API error: ${error .response ?.data .message ?? error .message } `
342- );
349+ return {
350+ content: {
351+ mimeType: " text/plain" ,
352+ text: ` Weather API error: ${error .response ?.data .message ?? error .message } `
353+ },
354+ isError: true ,
355+ }
343356 }
344357 throw error ;
345358 }
@@ -361,7 +374,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
361374
362375<Steps >
363376 <Step title = " Update Claude config" >
364- Add to ` claude_desktop_config.json ` :
377+ If you didn't already connect to Claude Desktop during project setup, add to ` claude_desktop_config.json ` :
365378
366379 ``` json
367380 {
@@ -466,14 +479,35 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
466479 title = " Error Handling"
467480 icon = " shield"
468481 >
482+ When a tool encounters an error, return the error message with ` isError: true ` , so the model can self-correct:
483+
484+ ``` typescript
485+ try {
486+ const response = await axiosInstance .get (... );
487+ } catch (error ) {
488+ if (axios .isAxiosError (error )) {
489+ return {
490+ content: {
491+ mimeType: " text/plain" ,
492+ text: ` Weather API error: ${error .response ?.data .message ?? error .message } `
493+ },
494+ isError: true ,
495+ }
496+ }
497+ throw error ;
498+ }
499+ ```
500+
501+ For other handlers, throw an error, so the application can notify the user:
502+
469503 ``` typescript
470504 try {
471505 const response = await this .axiosInstance .get (... );
472506 } catch (error ) {
473507 if (axios .isAxiosError (error )) {
474508 throw new McpError (
475509 ErrorCode .InternalError ,
476- ` API error: ${error .response ?.data .message } `
510+ ` Weather API error: ${error .response ?.data .message }`
477511 );
478512 }
479513 throw error ;
@@ -482,11 +516,11 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
482516 </Card >
483517
484518 <Card
485- title = " Type Guards "
519+ title = " Type Validation "
486520 icon = " check"
487521 >
488522 ``` typescript
489- function isValidForecastArgs(args : unknown ): args is GetForecastArgs {
523+ function isValidForecastArgs(args : any ): args is GetForecastArgs {
490524 return (
491525 typeof args === " object" &&
492526 args !== null &&
@@ -495,71 +529,36 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
495529 );
496530 }
497531 ```
498- </Card >
499532
500- <Card
501- title = " Environment Variables"
502- icon = " gear"
503- >
504- ``` typescript
505- if (! process .env .OPENWEATHER_API_KEY ) {
506- throw new Error (" OPENWEATHER_API_KEY is required" );
507- }
508- ```
509- </Card >
510-
511- <Card
512- title = " Constants"
513- icon = " box"
514- >
515- ``` typescript
516- const API_CONFIG = {
517- BASE_URL: ' ...' ,
518- ENDPOINTS: {
519- CURRENT: ' weather' ,
520- FORECAST: ' forecast'
521- }
522- } as const ;
523- ```
533+ <Tip >You can also use libraries like [ Zod] ( https://zod.dev/ ) to perform this validation automatically.</Tip >
524534 </Card >
525535</CardGroup >
526536
527537## Available transports
528538
529- While this guide uses stdio transport, MCP supports multiple transport options:
530-
531- ### WebSocket
532- ``` typescript
533- import { WebSocketServerTransport } from " @modelcontextprotocol/sdk/server/websocket.js" ;
534- const transport = new WebSocketServerTransport ();
535- ```
536-
537- ### SSE (Server-Sent Events)
538- ``` typescript
539- import { SSEServerTransport } from " @modelcontextprotocol/sdk/server/sse.js" ;
540- const transport = new SSEServerTransport (" /events" , response );
541- ```
539+ While this guide uses stdio to run the MCP server as a local process, MCP supports other [ transports] ( /docs/concepts/transports ) as well.
542540
543541## Troubleshooting
544542
543+ <Info >
544+ The following troubleshooting tips are for macOS. Guides for other platforms are coming soon.
545+ </Info >
546+
545547### Build errors
546548``` bash
547549# Check TypeScript version
548550npx tsc --version
549551
550552# Clean and rebuild
551- rm -rf dist /
553+ rm -rf build /
552554npm run build
553555```
554556
555557### Runtime errors
556- Look for detailed error messages in the Claude app logs:
558+ Look for detailed error messages in the Claude Desktop logs:
557559``` bash
558- # Launch Claude with logging
559- open /Applications/Claude.app --stdout ~ /Claude.log --stderr ~ /Claude.log
560-
561560# Monitor logs
562- tail -f ~ /Claude.log
561+ tail -n 20 - f ~ /Library/Application \ Support/ Claude/mcp * .log
563562```
564563
565564### Type errors
0 commit comments