Build Your First MCP Server with TypeScript & Gemini API: Step-by-Step Guide

Building Your First MCP Server with TypeScript (feat. Gemini API!)

Let's walk through creating a basic Model Context Protocol (MCP) server locally using TypeScript. MCP is a standard way for Large Language Models (LLMs) to interact with external tools and data. We'll build a server with a simple calculator tool and another tool that calls the Google Gemini API.

For more background on MCP, check out my previous post explaining the protocol:
what-is-mcp-a-beginner-friendly-guide-to-the-ai-communication-protocol

✅ Prerequisites
Node.js (LTS recommended)

Google Gemini API Key → Get one at Google AI Studio

✅ Step 1: Project Setup

# Create a new folder
mkdir my-mcp-gemini-server

Move into it

cd my-mcp-gemini-server

Initialize npm project

npm init -y

✅ Step 2: Install Dependencies

### Install core libraries
npm install @modelcontextprotocol/sdk zod @google/generative-ai dotenv

### Install dev tools
npm install -D typescript @types/node

✅ Step 3: Configure TypeScript

Create a tsconfig.json file in your project root:


{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Node",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}

✅ Step 4: Prepare Code Files

# Create source directory
mkdir src

# Create main TypeScript file
touch src/index.ts

# Create .env file
touch .env
Inside .env:

env

GEMINI_API_KEY=YOUR_ACTUAL_GEMINI_API_KEY

🚨 Don't forget to add .env to .gitignore!

✅ Step 5: Write the MCP Server Code

Paste the following into src/index.ts:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import dotenv from 'dotenv';
import { GoogleGenerativeAI } from "@google/generative-ai";

dotenv.config();

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY || "");
if (!process.env.GEMINI_API_KEY) {
  console.warn("⚠️ WARNING: GEMINI_API_KEY not set in .env file.");
}
const geminiModel = genAI.getGenerativeModel({ model: "gemini-2.0-flash" });

const server = new McpServer({
  name: "MyGeminiHelper",
  version: "1.0.0",
});

// Tool: Add
server.tool(
  "add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => {
    const result = a + b;
    process.stderr.write(`🛠️ Tool 'add' called: ${a} + ${b} = ${result}\n`);
    return { content: [{ type: "text", text: String(result) }] };
  }
);

// Tool: askGemini
server.tool(
  "askGemini",
  { prompt: z.string() },
  async ({ prompt }) => {
    process.stderr.write(`🤖 Tool 'askGemini' called with prompt: "${prompt}"\n`);
    try {
      const result = await geminiModel.generateContent(prompt);
      const response = await result.response;
      const text = response.text();
      process.stderr.write(`✅ Gemini response received.\n`);
      return { content: [{ type: "text", text: text }] };
    } catch (error) {
      process.stderr.write(`❌ Gemini API Error: ${error}\n`);
      return { content: [{ type: "text", text: `Error: ${error.message}` }] };
    }
  }
);

const transport = new StdioServerTransport();

console.log("🚀 Starting MCP server...");
await server.connect(transport);
console.log("✅ Server connected and listening for requests!");

✅ Step 6: Compile and Run (Handle ESM Issues)

Compile TypeScript

npx tsc

Fix import error
In your package.json, add this line:

"type": "module",

Final package.json should look something like:

{
  "name": "my-mcp-gemini-server",
  "version": "1.0.0",
  "type": "module",
  ...
}

Run the server

node dist/index.js

You should see:

🚀 Starting MCP server...
✅ Server connected and listening for requests!

✅ Step 7: Test Your Server

Test the add tool:
Paste this into the terminal:

{"jsonrpc":"2.0","id":"test-add-1","method":"tools/call","params":{"name":"add","arguments":{"a":7,"b":3}}}

You should see:

🛠️ Tool 'add' called: 7 + 3 = 10

Test the askGemini tool:

{"jsonrpc":"2.0","id":"test-gemini-1","method":"tools/call","params":{"name":"askGemini","arguments":{"prompt":"Explain MCP briefly"}}}

You'll see:

🤖 Tool 'askGemini' called with prompt: "Explain MCP briefly"
✅ Gemini response received.

🎉 Conclusion
You've successfully built a local MCP server using TypeScript that can execute simple logic and interact with an external API like Gemini! This server uses Stdio for communication, but the MCP SDK also supports other transports like HTTP for web-based interactions.

This is just the beginning of exploring what's possible with MCP.

If you have any questions, feel free to email me!

@thunderbizlab@gmail.com