Skip to main content
Glama
README.md
# jokebox

jokebox serves dad jokes from [icanhazdadjoke.com](https://icanhazdadjoke.com).
Ask for a joke at random, hunt for jokes that mention a word or
phrase, or pull up one specific joke again when you know its ID.
One binary offers both a small command-line interface and a stdio
MCP server, so the same install works in a terminal and inside an
MCP client.

There is nothing to configure: the upstream service is public,
needs no API key, and asks only that clients identify themselves
and accept JSON answers — jokebox does both on every request.

## Install

```bash
npx @reneturcios/jokebox random
```

Or run the container image:

```bash
docker run -i ghcr.io/cloudcorprecords/jokebox
```

The container defaults to the MCP server (see below). Pass CLI
arguments to use it as a CLI instead.

## CLI

```bash
jokebox random
jokebox search pizza
jokebox search pizza --limit 3
jokebox joke R7UfaahVfFd

jokebox --version
```

Every command prints JSON. `random` prints one joke as
`{ "id": ..., "joke": ... }`. `search` prints
`{ "term": ..., "total_jokes": ..., "jokes": [...] }`, where
`total_jokes` counts every match the upstream holds for the term
and `jokes` holds the requested page of them. `joke` prints the
single joke stored under the given ID.

Search limits: `--limit` is an integer from 1 to 30 and defaults
to 5. An out-of-range limit, a missing search term, or a missing
joke ID is a usage error and no request is sent.

Exit codes: `0` on success, `1` when the upstream request fails
(the error names the HTTP status or the malformed answer), `2`
for usage errors.

## MCP server

One bin serves both faces. The `mcp` subcommand starts a stdio MCP
server:

```bash
npx -y @reneturcios/jokebox mcp
```

MCP client configuration:

```json
{
  "mcpServers": {
    "jokebox": {
      "command": "npx",
      "args": ["-y", "@reneturcios/jokebox", "mcp"]
    }
  }
}
```

### Tools

| Tool | Input | What it returns |
| --- | --- | --- |
| `get_random_joke_tool` | (none) | One random dad joke: its `id` and `joke` text. |
| `search_jokes_tool` | `term` (string, required), `limit` (integer, optional, default 5, max 30) | Jokes containing the term: the term, the total match count, and the matching jokes. |
| `get_joke_by_id_tool` | `joke_id` (string, required) | The single joke stored under that ID. |

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # node test runner over test/*.test.ts, no network (fake fetch only)
npm run dev     # run the CLI from source via tsx
```

## License

MIT — see `LICENSE`.