Skip to main content
Glama
enachimuthu

mcp-toolkit-server

by enachimuthu
README.md
# mcp-toolkit-server

A production-quality [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server, written in TypeScript, that exposes a small toolkit of everyday utilities as MCP **tools**, **resources**, and **prompts**.

## What is MCP?

The **Model Context Protocol** is an open protocol from Anthropic that standardizes how applications provide context and capabilities to large language models. An MCP *server* advertises **tools** (functions the model can call), **resources** (readable data the model can pull in as context), and **prompts** (reusable prompt templates). MCP *clients* — such as Claude Desktop, IDE assistants, or custom agents — connect to servers and let the model use those capabilities.

This server speaks MCP over **stdio**: the client launches it as a subprocess and communicates via JSON-RPC on stdin/stdout. All logging is therefore sent to **stderr** so it never corrupts the protocol stream.

## What this server does

`mcp-toolkit-server` bundles a handful of self-contained utilities so you can experiment with MCP without external services or API keys. It also keeps an in-memory notes store that is exposed both as tools and as browsable resources.

## Tools

| Tool | Description | Inputs |
| --- | --- | --- |
| `calculator` | Safely evaluate a basic arithmetic expression (`+ - * / % **`, parentheses). Uses a hand-written parser — **never** `eval`. Reports divide-by-zero and invalid input as errors. | `expression: string` |
| `text_stats` | Return word, character, line, and sentence counts for a block of text. | `text: string` |
| `slugify` | Convert text into a URL-friendly slug (lowercased, diacritics stripped, hyphenated). | `text: string` |
| `base64` | Encode a UTF-8 string to base64, or decode base64 back to UTF-8. | `input: string`, `mode: "encode" \| "decode"` |
| `hash` | Compute the `md5` or `sha256` hex digest of a string. | `input: string`, `algo: "md5" \| "sha256"` |
| `uuid` | Generate one or more random v4 UUIDs. | `count?: number (1–100)` |
| `datetime` | Return the current date/time for a given IANA timezone. | `timezone: string` |
| `notes_add` | Create a new note; returns the note with its generated id. | `title: string`, `content: string` |
| `notes_list` | List all stored notes. | *(none)* |
| `notes_get` | Retrieve a single note by id. | `id: string` |
| `notes_delete` | Delete a note by id. | `id: string` |

## Resources

| Resource | URI | Description |
| --- | --- | --- |
| Server info | `server://info` | Static JSON document with server metadata (name, version, capabilities, note count). |
| Note | `note://{id}` | Dynamic resource template. Listing enumerates every stored note; reading `note://<id>` returns that note as JSON. |

## Prompts

| Prompt | Description | Arguments |
| --- | --- | --- |
| `summarize` | Ask the model to produce a concise summary of the provided text. | `text: string` |
| `code_review` | Ask the model to review a code snippet for bugs, security, and style. | `language: string`, `code: string` |

## Install & build

Requires **Node.js 18+**.

```bash
npm install
npm run build
```

This compiles `src/` to `dist/` (with type declarations).

## Run

After building, run the compiled server:

```bash
node dist/index.js
```

Or, once published/installed, via the bin entry:

```bash
npx mcp-toolkit-server
```

The server communicates over stdio, so running it directly in a terminal will simply wait for a client to connect. You should see the startup line printed to stderr:

```
mcp-toolkit-server v0.1.0 running on stdio.
```

## Add it to an MCP client (Claude Desktop)

Add an entry to your `claude_desktop_config.json` (on Windows this lives at
`%APPDATA%\Claude\claude_desktop_config.json`). Use an absolute path to the built entrypoint:

```json
{
  "mcpServers": {
    "toolkit": {
      "command": "node",
      "args": ["C:\\SourceCode\\mcp-toolkit-server\\dist\\index.js"]
    }
  }
}
```

Restart the client; the `toolkit` server's tools, resources, and prompts will then be available.

## Development

```bash
# Run directly from TypeScript source without building (via tsx):
npm run dev

# Type-check only:
npm run lint

# Run the test suite (Vitest):
npm test

# Watch mode:
npm run test:watch
```

The pure logic (`calculator`, `text_stats`, `slugify`, `base64`, `hash`, and the notes store) lives in dedicated modules under `src/tools/` and `src/store.ts`, and is unit-tested in `test/` without requiring a running server.

## Project structure

```
mcp-toolkit-server/
├── src/
│   ├── index.ts          # Entrypoint: create server, register everything, connect via stdio
│   ├── config.ts         # Server name/version constants
│   ├── store.ts          # In-memory NotesStore (shared by tools and resources)
│   ├── resources.ts      # server://info and note://{id} resources
│   ├── prompts.ts        # summarize and code_review prompts
│   └── tools/
│       ├── index.ts      # Registers all tools on the server
│       ├── calculator.ts # Safe arithmetic evaluator
│       ├── text.ts       # textStats + slugify
│       ├── encoding.ts   # base64 + hash
│       └── datetime.ts   # timezone formatting
├── test/                 # Vitest unit tests for the pure logic
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── LICENSE
└── README.md
```

## License

[MIT](./LICENSE) © 2026 Nachimuthu Easwaramoorthy

TDQS

A3.9/5.0

Scored across 11 tools

Disambiguation5/5

Each tool targets a clearly distinct purpose: math, text stats, slugification, notes CRUD, encoding, hashing, UUID generation, and datetime. Even notes_list and notes_get are clearly separated by list vs. single-item retrieval. There is no meaningful overlap or confusion between tools.

Naming Consistency3/5

The notes tools follow a consistent notes_<verb> pattern, but the utility tools do not follow a single convention: some are nouns, some are noun_verb, and one is a bare verb. The names are individually readable and the mix is understandable, but the overall naming style is inconsistent.

Tool Count5/5

Eleven tools is well within the ideal range for a general-purpose toolkit. Each utility has a standalone use case, and the notes tools form a small, focused CRUD group without unnecessary bloat.

Completeness4/5

The utility tools cover common string, text, encoding, hash, UUID, and datetime operations well. The notes store supports list, add, get, and delete, but lacks an update operation, which is a minor gap that can be worked around with delete and re-add.

Maintenance

ActivityMaintained
ResponsivenessNo issues