├── .gitignore ├── package.json ├── readme.md └── server.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bun.lockb 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcp-quickstart", 3 | "dependencies": { 4 | "@modelcontextprotocol/sdk": "^1.0.3", 5 | "zod": "^3.24.1" 6 | }, 7 | "devDependencies": { 8 | "@types/node": "^22.10.2", 9 | "typescript": "^5.7.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # MCP Server Quickstart 2 | 3 | Setup a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server in 60 seconds. 4 | 5 | https://github.com/user-attachments/assets/19a2248a-64f4-4e0b-aedc-55eb51c7cbfe 6 | 7 | ## Usage 8 | 9 | 1. Ensure you have [Bun](https://bun.sh/docs/installation) installed. 10 | 2. Clone the repo and install dependencies: 11 | ```bash 12 | git clone https://github.com/dexaai/mcp-quickstart.git mcp-quickstart && cd mcp-quickstart && bun install 13 | ``` 14 | 3. Copy the absolute path to the server: 15 | ```bash 16 | realpath server.ts | pbcopy 17 | ``` 18 | 4. Open the Claude desktop app config: 19 | ```bash 20 | vim ~/Library/Application\ Support/Claude/claude_desktop_config.json 21 | ``` 22 | 5. Add the server config with the path from step 3 instead of `/server.ts`. 23 | ```json 24 | { 25 | "mcpServers": { 26 | "weather-quickstart": { 27 | "command": "bun", 28 | "args": ["/server.ts"] 29 | } 30 | } 31 | } 32 | ``` 33 | 6. Restart the Claude desktop app and ask for the weather. 34 | -------------------------------------------------------------------------------- /server.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 2 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 3 | import { 4 | CallToolRequestSchema, 5 | ListToolsRequestSchema, 6 | } from "@modelcontextprotocol/sdk/types.js"; 7 | import { z } from "zod"; 8 | 9 | const WeatherSchema = z.object({ location: z.string() }); 10 | 11 | // Create server instance 12 | const server = new Server( 13 | { name: "weather", version: "1.0.0" }, 14 | { capabilities: { tools: {} } }, 15 | ); 16 | 17 | // List available tools 18 | server.setRequestHandler(ListToolsRequestSchema, async () => { 19 | return { 20 | tools: [ 21 | { 22 | name: "check-weather", 23 | description: "Check the weather for a location", 24 | inputSchema: { 25 | type: "object", 26 | properties: { 27 | location: { 28 | type: "string", 29 | description: "The location to check the weather for", 30 | }, 31 | }, 32 | required: ["location"], 33 | }, 34 | }, 35 | ], 36 | }; 37 | }); 38 | 39 | // Handle tool execution 40 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 41 | const { name, arguments: args } = request.params; 42 | 43 | try { 44 | if (name === "check-weather") { 45 | const { location } = WeatherSchema.parse(args); 46 | const weather = await getWeather(location); 47 | return { content: [{ type: "text", text: weather }] }; 48 | } else { 49 | throw new Error(`Unknown tool: ${name}`); 50 | } 51 | } catch (error) { 52 | if (error instanceof z.ZodError) { 53 | throw new Error( 54 | `Invalid arguments: ${error.errors 55 | .map((e) => `${e.path.join(".")}: ${e.message}`) 56 | .join(", ")}`, 57 | ); 58 | } 59 | throw error; 60 | } 61 | }); 62 | 63 | // Fake weather API 64 | async function getWeather(location: string): Promise { 65 | return `It's bright and sunny in ${location} today.`; 66 | } 67 | 68 | async function main() { 69 | const transport = new StdioServerTransport(); 70 | await server.connect(transport); 71 | } 72 | 73 | main().catch((error) => { 74 | console.error("Fatal error in main():", error); 75 | process.exit(1); 76 | }); 77 | --------------------------------------------------------------------------------