Skip to main content
Glama
gabrielestes

vader-mcp

by gabrielestes
README.md
# vader-mcp

A local stdio MCP server, written in TypeScript, that makes Claude answer as
Darth Vader whenever you mention Star Wars.

## How the trigger actually works

An MCP server cannot intercept your messages — it exposes tools, and the model
decides when to call them. So the persona fires from two things working
together:

1. **Server instructions.** On connect, the server sends an `instructions`
   block that Claude Code injects into its system prompt. It tells Claude to
   call `sense_disturbance` on any message that might mention Star Wars, and to
   stay in voice while `engage` is true.
2. **The `sense_disturbance` tool.** Deterministic keyword matching over ~120
   Star Wars terms, returning the matched keywords, an intensity level, and the
   persona directive.

This is best-effort by design — the model chooses to call the tool. If you want
it guaranteed, use the `vader_mode` prompt (`/vader_mode`) to pin the persona on
for the whole conversation.

## Tools

| Tool | Purpose |
|---|---|
| `sense_disturbance` | Scan text for Star Wars keywords. Returns `engage`, matched `keywords`, `intensity`, and the persona `directive`. |
| `vader_speak` | Restyle a message in Vader's register — no contractions, formal phrasing, framed by an opening and closing line. Takes `intensity` of `low`/`medium`/`high`. |
| `vader_quote` | Return a canonical Vader line, optionally by topic (`power`, `father`, `failure`, `destiny`, ...). |

## Prompt

`vader_mode` — force the persona on for the rest of the conversation.

## Install

```bash
npm install   # `prepare` builds dist/ automatically
```

Register with Claude Code (user scope, available in every project):

```bash
claude mcp add vader --scope user -- node /Users/gabrielestes/vader_mcp/dist/index.js
```

Remove it with `claude mcp remove vader --scope user`.

> The registered server runs compiled JavaScript from `dist/`, so it has no
> dependency on experimental Node features. **Re-run `npm run build` after
> editing `src/`** or the running server keeps serving the old build.

## Scripts

| Command | What it does |
|---|---|
| `npm run build` | `tsc -p tsconfig.build.json` → `dist/` (JS + `.d.ts` + sourcemaps) |
| `npm run typecheck` | Typechecks `src/`, `test/`, and `scripts/` with no emit |
| `npm test` | Unit tests for the voice engine, run straight from `.ts` |
| `npm run probe` | Builds, then drives every tool over real JSON-RPC against `dist/` |
| `npm run dev` | Runs the server straight from `src/index.ts` |

`npm test` and `npm run dev` rely on Node's native type stripping (Node ≥ 22.18),
which prints an experimental warning. The build path does not.

## TypeScript setup

- `tsconfig.json` — strict base config, `noEmit`, covers `src`/`test`/`scripts`.
- `tsconfig.build.json` — extends it, emits `src/` to `dist/`.

Relative imports are written with `.ts` extensions so Node can run the sources
directly; `rewriteRelativeImportExtensions` turns them into `.js` on build.
`erasableSyntaxOnly` keeps the source compatible with type stripping, so the
same files run both ways.

Strictness beyond `strict`: `noUncheckedIndexedAccess`,
`exactOptionalPropertyTypes`, `noImplicitOverride`, `noUnusedLocals`,
`noUnusedParameters`, `verbatimModuleSyntax`.

## Layout

- `src/vader.ts` — keyword detection, quotes, and text styling. Pure functions, no I/O.
- `src/index.ts` — MCP wiring: tool registration and stdio transport.
- `test/vader.test.ts` — unit tests for the voice engine.
- `scripts/probe.ts` — spawns the built server and exercises every tool over real JSON-RPC.

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clear, non-overlapping role: one detects whether Vader mode should activate, one restyles an arbitrary message, and one returns a canned quote. There is little chance an agent would confuse them.

Naming Consistency3/5

The names are readable and all snake_case, but they follow different patterns: sense_disturbance is verb_noun, vader_speak is noun_verb, and vader_quote is noun_noun. Two share a vader_ prefix while the third does not, making the convention inconsistent.

Tool Count5/5

Three tools is appropriate for a narrow Vader roleplay server. Each tool earns its place and there is no bloat or redundancy.

Completeness5/5

The server covers the full intended workflow: detect when Vader's voice should engage, restyle a message into that voice, and provide authentic quotes. No obvious gaps or dead ends exist for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues