Simple MCP tool using NodeJS
Creating an MCP server using Node.js is straightforward. You can integrate various third-party tools—such as JIRA, build tools (TeamCity, Jenkins), and many others—using the code provided below. If you prefer not to rely on external MCP servers, you can follow these steps to create and run your own local MCP server, which can then be used with any AI client.
Folder structure
mcp-server
- .vscode
- mcp.json
- src
- lib
- tools.ts
- index.ts
- .env
- .npmrc
- package.json
- tsconfig.json
File contents
package.json
Contains script for build, dev and other dependancies information
{
"name": "groww-mcp-server",
"version": "1.0.0",
"description": "",
"main": "src/index.ts",
"type": "module",
"bin": {
"groww_mcp_server": "./build/index.js"
},
"scripts": {
"build": "tsc && chmod 755 build/index.js",
"build:watch": "tsc --watch",
"dev": "tsc --watch",
"start": "node ./build/index.js",
"clean": "rm -rf build"
},
"files": [
"build"
],
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.17.4",
"@types/node-fetch": "^2.6.13",
"dotenv": "^17.2.1",
"node-fetch": "^3.3.2",
"totp-generator": "^1.0.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^24.3.0",
"typescript": "^5.9.2"
}
}
tsconfig.json
Typescript compiler options
{
"compilerOptions": {
"target": "ES2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"sourceMap": true,
"declaration": false,
"incremental": true,
"tsBuildInfoFile": "./build/.tsbuildinfo"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "build"],
"watchOptions": {
"watchFile": "useFsEvents",
"watchDirectory": "useFsEvents",
"fallbackPolling": "dynamicPriority",
"synchronousWatchDirectory": true,
"excludeDirectories": ["**/node_modules", "_tmp"]
}
}
.npmrc
registry=https://registry.npmjs.com/
... other project related node settings like freezing node version
.env
# MCP Server configuration
MCP_HOST=127.0.0.1
MCP_PORT=8000
MCP_DEBUG=true
# Docker configuration
DOCKER_PORT=8000
DOCKER_ENV=production
API_KEY=xxxxxx
...other ENV settings...
src/index.ts
This defines all the tools that a MCP server contains. You can add as many tools you can till you are tired.
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 { Tools, ToolResponse } from './lib/tools.js';
dotenv.config();
// Create server instance
const server = new McpServer({
name: 'weather',
version: '1.0.0',
capabilities: {
resources: {},
tools: {},
},
});
const tools = new Tools();
server.tool(
'get-user-margin',
"get available margin for a user",
{},
async () => {
const response: ToolResponse = await Tools.getAvailableMargin();
return response;
}
)
server.tool(
'get-historical-data',
"get historical data for stocks",
{
exchange: z.string(),
segment: z.string(),
trading_symbol: z.string(),
start_time: z.string(),
end_time: z.string(),
interval_in_minutes: z.number().min(1).optional()
},
async ({ exchange, segment, trading_symbol, start_time, end_time, interval_in_minutes }) => {
const response: ToolResponse = await Tools.getHistoricalStockData({
exchange,
segment,
trading_symbol,
start_time,
end_time,
interval_in_minutes
});
return response;
}
)
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Calculator MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
src/lib/tools.ts
export interface ToolResponse {
content: {
type: string;
text: string;
}[];
}
export class Tools {
private api: Api;
constructor() {
const Config = {
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
};
this.api = new Api(Config);
this.api.authenticate();
}
async getAvailableMargin(): Promise<ToolResponse> {
const margin = await this.api.getAvailableMargin();
return {
content: [
{
type: 'text',
text: `Your available margin is ₹${margin}`,
},
],
};
}
async getHistoricalStockData(params: HistoricalDataParams): Promise<ToolResponse> {
const historicalData = await this.api.getHistoricalStockData(params);
return {
content: [
{
type: 'text',
text: `Your historical stock data is: ${JSON.stringify(historicalData)}`,
},
],
};
}
}
mcp.json
This is how you can use it in VSCode. Settings for other AI tools are different depending on the tools.
{
"servers": {
"mcp-server": {
"command": "node",
"args": ["./server/build/index.js"],
"envFile": "${workspaceFolder}/server/.env"
}
}
}