Skip to main content
Glama
README.md
# devkit-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives an AI assistant seven
everyday developer utilities: sending HTTP requests, inspecting JWTs, hashing, generating UUIDs,
testing regular expressions, explaining cron schedules, and encoding text.

No API keys, no accounts, no configuration. Clone it, build it, point a client at it.

```
┌────────────┐   MCP over stdio   ┌──────────────┐
│  AI client │ ◄────────────────► │  devkit-mcp  │
│  (Claude)  │    JSON-RPC 2.0    │   7 tools    │
└────────────┘                    └──────────────┘
```

## Why this exists

Language models are bad at exactly the things these tools are good at: computing a SHA-256 by hand,
predicting when `0 9 * * 1-5` next fires in `America/New_York`, or deciding whether a base64 string
round-trips. Each tool here replaces a plausible-sounding guess with a real answer.

## Tools

| Tool | What it does |
| --- | --- |
| `http_request` | Sends an HTTP request and returns status, headers, timing, and body. Parses JSON bodies automatically. Redirects are followed manually and re-checked at every hop. |
| `decode_jwt` | Decodes a JWT header and payload, and reports `iat`/`nbf`/`exp` in epoch and ISO form with expiry status. **Does not verify signatures** — and says so in every response. |
| `hash_text` | MD5, SHA-1, SHA-256, SHA-384, SHA-512 digests or keyed HMACs, in hex, base64, or base64url. Optionally verifies against an expected digest in constant time. |
| `generate_uuid` | UUIDv4 (random) or UUIDv7 (time-ordered, RFC 9562) from a cryptographically secure source. |
| `regex_test` | Runs a regex and returns every match with its offset, positional groups, and named groups. Can preview a replacement. |
| `cron_explain` | Translates a cron expression to plain English and lists its next runs in a given timezone. Handles 5-field and 6-field syntax. |
| `transform_text` | base64, base64url, hex, and URL encoding in both directions, plus JSON formatting and minification. Decoders reject bad input instead of returning garbage. |

## Install

Requires Node.js 20 or newer.

```bash
git clone https://github.com/lllNuggetslll/devkit-mcp.git
cd devkit-mcp
npm install
npm run build
```

## Connect it to a client

### Claude Code

```bash
claude mcp add devkit -- node /absolute/path/to/devkit-mcp/dist/index.js
```

### Claude Desktop

Add this to `claude_desktop_config.json`:

- macOS — `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows — `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "devkit": {
      "command": "node",
      "args": ["/absolute/path/to/devkit-mcp/dist/index.js"]
    }
  }
}
```

Restart the client, and the seven tools appear.

### Anything else

The server speaks MCP over stdio, so any compliant client works:

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

## Try it

Once connected, these all work in plain language:

- *"What's the SHA-256 of `hunter2`?"*
- *"When does `0 */4 * * *` next run in Tokyo time?"*
- *"Decode this JWT and tell me if it's expired."*
- *"Does `^\d{3}-\d{4}$` match `555-1234`?"*
- *"Generate 5 UUIDv7s for my database seeds."*
- *"GET https://api.github.com/repos/anthropics/claude-code and show me the star count."*

## Network access and SSRF

`http_request` refuses requests to loopback, link-local, and RFC 1918 addresses by default.

This matters more for an MCP server than for an ordinary HTTP client. The server takes its
instructions from a model, and a model can be steered by whatever text it just read — a web page, an
issue comment, a log file. An unrestricted fetch tool is therefore a server-side request forgery
primitive aimed at everything the host machine can reach, including cloud metadata endpoints like
`169.254.169.254`.

The guard resolves hostnames before deciding, so a DNS record pointing at `127.0.0.1` does not get
through, and it re-checks every redirect hop rather than trusting the first URL.

Testing a local API is the legitimate case for this, so it is one variable away:

```json
{
  "mcpServers": {
    "devkit": {
      "command": "node",
      "args": ["/absolute/path/to/devkit-mcp/dist/index.js"],
      "env": { "DEVKIT_ALLOW_PRIVATE_HOSTS": "1" }
    }
  }
}
```

Other limits: responses are capped at 256 KB, redirects at 5 hops, and requests time out after 15
seconds by default (60 seconds maximum).

## Development

```bash
npm test          # run the suite
npm run test:watch
npm run typecheck
npm run dev       # tsc --watch
```

The suite has 38 tests in two layers. `tests/tools.test.ts` covers the pure functions, including
published test vectors — the RFC 4231 HMAC-SHA256 vector, the known SHA-256 of the empty string —
plus the edge cases worth pinning down: zero-length regex matches that would otherwise loop forever,
IPv4-mapped IPv6 addresses like `::ffff:127.0.0.1` that would slip past a naive private-range check,
and encodings that must round-trip exactly.

`tests/server.test.ts` runs the real server against a real MCP client over an in-memory transport,
so tool registration, schema generation, defaults, and error results are verified through the
protocol rather than around it.

## How it is put together

```
src/
  index.ts          entry point; stdio transport and signal handling
  server.ts         builds the McpServer and registers every tool
  tools/
    types.ts        ToolDefinition contract and result helpers
    index.ts        the tool registry
    http.ts         http_request, plus the SSRF host policy
    jwt.ts  hash.ts  uuid.ts  regex.ts  cron.ts  text.ts
```

Every tool is a `ToolDefinition`: a name, a description, a Zod input schema, MCP annotations, and a
handler. `server.ts` iterates the registry and registers each one, so adding a tool means writing a
module and adding a line to `tools/index.ts` — nothing else changes.

Two conventions are worth calling out:

**The logic is separate from the protocol.** Each module exports a plain function — `hashText`,
`decodeJwt`, `explainCron` — that knows nothing about MCP. The tool wrapper handles argument parsing
and result formatting. That is what lets the unit tests call the real logic directly, with no
transport in the way.

**Failures are results, not exceptions.** MCP models a tool failure as an ordinary response with
`isError: true`, which lets the model read the message and correct itself. A thrown protocol error
would just look like a broken server. Every handler catches and returns `fail(message)` instead.

Tools also declare their side effects through MCP annotations, so a host can decide what needs
approval: everything is `readOnlyHint: true` except `http_request`, which is the only one marked
`openWorldHint: true`.

## License

MIT

TDQS

A4.3/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: HTTP requests, JWT decoding, hashing, UUID generation, regex testing, cron explanation, and text transformations. No overlap or ambiguity exists.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., decode_jwt, hash_text, generate_uuid). The pattern is predictable and easy to understand.

Tool Count5/5

Seven tools is well-scoped for a general developer utility kit. Each tool covers a fundamental, non-overlapping function without being excessive or insufficient.

Completeness4/5

The tool set covers key developer needs: networking, crypto, identifiers, text processing, regex, and cron. Minor gaps like JSONPath or data format conversion are not critical for the stated purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues