#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{
name: "simple-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// In-memory storage for notes
const notes = new Map();
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "calculator",
description: "Perform basic arithmetic operations (add, subtract, multiply, divide)",
inputSchema: {
type: "object",
properties: {
operation: {
type: "string",
enum: ["add", "subtract", "multiply", "divide"],
description: "The arithmetic operation to perform",
},
a: {
type: "number",
description: "First number",
},
b: {
type: "number",
description: "Second number",
},
},
required: ["operation", "a", "b"],
},
},
{
name: "add_note",
description: "Add a note with a title and content",
inputSchema: {
type: "object",
properties: {
title: {
type: "string",
description: "The title of the note",
},
content: {
type: "string",
description: "The content of the note",
},
},
required: ["title", "content"],
},
},
{
name: "get_note",
description: "Retrieve a note by its title",
inputSchema: {
type: "object",
properties: {
title: {
type: "string",
description: "The title of the note to retrieve",
},
},
required: ["title"],
},
},
{
name: "list_notes",
description: "List all note titles",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "delete_note",
description: "Delete a note by its title",
inputSchema: {
type: "object",
properties: {
title: {
type: "string",
description: "The title of the note to delete",
},
},
required: ["title"],
},
},
],
};
});
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case "calculator": {
const { operation, a, b } = args;
let result;
switch (operation) {
case "add":
result = a + b;
break;
case "subtract":
result = a - b;
break;
case "multiply":
result = a * b;
break;
case "divide":
if (b === 0) {
throw new Error("Cannot divide by zero");
}
result = a / b;
break;
default:
throw new Error(`Unknown operation: ${operation}`);
}
return {
content: [
{
type: "text",
text: `${a} ${operation} ${b} = ${result}`,
},
],
};
}
case "add_note": {
const { title, content } = args;
notes.set(title, {
content,
created: new Date().toISOString(),
updated: new Date().toISOString(),
});
return {
content: [
{
type: "text",
text: `Note "${title}" has been added successfully.`,
},
],
};
}
case "get_note": {
const { title } = args;
const note = notes.get(title);
if (!note) {
return {
content: [
{
type: "text",
text: `Note "${title}" not found.`,
},
],
};
}
return {
content: [
{
type: "text",
text: `Title: ${title}\nContent: ${note.content}\nCreated: ${note.created}\nUpdated: ${note.updated}`,
},
],
};
}
case "list_notes": {
const titles = Array.from(notes.keys());
if (titles.length === 0) {
return {
content: [
{
type: "text",
text: "No notes found.",
},
],
};
}
return {
content: [
{
type: "text",
text: `Available notes:\n${titles.map(title => `- ${title}`).join('\n')}`,
},
],
};
}
case "delete_note": {
const { title } = args;
if (!notes.has(title)) {
return {
content: [
{
type: "text",
text: `Note "${title}" not found.`,
},
],
};
}
notes.delete(title);
return {
content: [
{
type: "text",
text: `Note "${title}" has been deleted successfully.`,
},
],
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error: ${error.message}`,
},
],
isError: true,
};
}
});
// Start the server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Simple MCP Server running on stdio");
}
main().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});