Skip to main content
Glama
README.md
# Kanka MCP Tool

Local MCP tool for the Kanka worldbuilding API. Runs on your machine via stdio — no remote server needed.

## Prerequisites

- Node.js 20+.
- A Kanka API token (get one at [kanka.io/en/settings/api](https://kanka.io/en/settings/api)).

## Install

```bash
npm install
```

## Usage

### MCP client configuration (Claude Desktop, Cursor, etc.)

Add this to your MCP client config:

```json
{
  "mcpServers": {
    "kanka": {
      "command": "node",
      "args": ["<ABSOLUTE_PATH_TO_REPO>/index.js"],
      "env": {
        "KANKA_API_TOKEN": "<YOUR_KANKA_TOKEN>"
      }
    }
  }
}
```

Notes:
- Replace `<ABSOLUTE_PATH_TO_REPO>` with the full path to this repository.
- On Windows, prefer forward slashes (`C:/Users/...`) or escaped backslashes (`C:\\Users\\...`).
- Restart the MCP client after editing the config.

### Run directly

```bash
KANKA_API_TOKEN=your_token npm start
```

### Install globally

```bash
npm install -g .
KANKA_API_TOKEN=your_token kanka-mcp
```

## Available tools

The tool exposes 77 MCP tools for interacting with Kanka:

- **list_campaigns** — List all campaigns
- **search** — Search entities within a campaign
- For each entity type (Character, Location, Family, Organization, Item, Note, Event, Calendar, Timeline, Creature, Race, Quest, Map, Journal, Ability):
  - `list_<entities>` — List all
  - `get_<entity>` — Get details
  - `create_<entity>` — Create new
  - `update_<entity>` — Update existing
  - `delete_<entity>` — Delete existing

### Listing options

Big campaigns return list pages that are too large for some MCP clients to show
in full, which hides the records in the middle of the response. Every
`list_<entities>` tool takes these options to keep a page small and complete:

| Option | Values | Description |
| --- | --- | --- |
| `page` | number | Page number, default `1`. |
| `per_page` | 1–100 | Records per page. Enforced by this server, so it holds even when the Kanka API answers with a different page size. Omit it to return the API's own page untouched. |
| `entries` | boolean | Default `true`. Set `false` to drop the long `entry`/`entry_parsed` fields and get a `has_entry` boolean per record instead. |
| `entry_filter` | `all`, `empty`, `filled` | Default `all`. Keep only records whose entry is empty, or only those with text. Applied across the whole collection, not just one API page. |

When `per_page` or `entry_filter` is used, the response carries this server's own
`meta` instead of the API's:

```json
{
  "data": [{ "id": 42, "name": "Thalion", "has_entry": false }],
  "meta": {
    "page": 1,
    "per_page": 100,
    "count": 1,
    "has_more": false,
    "entry_filter": "empty",
    "entries_included": false,
    "total_unfiltered": 168,
    "api_pages_fetched": 12
  }
}
```

Notes:
- `per_page` defaults to 25 with entries, 100 without, and pages are stitched
  from as many API requests as needed.
- `total_unfiltered` is the size of the whole collection as reported by Kanka —
  it is not the number of records left after `entry_filter`. Walk pages until
  `has_more` is `false`.
- `scan_incomplete: true` means the budget of 50 API requests per call ran out
  before the window was filled, so records past that point were not scanned.

Example — find every character with no entry yet, in as few calls as possible:

```json
{ "campaignId": 235025, "per_page": 100, "entries": false, "entry_filter": "empty" }
```

## Contributing

Community contributions are welcome.

- Read [CONTRIBUTING.md](CONTRIBUTING.md) for workflow, coding standards, and PR checklist.
- Review [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) before participating.

### Local quality checks

```bash
npm run lint
npm run format:check
npm test
```

### Claude Desktop bundle (.mcpb)

The `.mcpb` bundle is built by the `MCP bundle (.mcpb)` GitHub Actions workflow, not by hand. On every pull request it validates `manifest.json`, packs the bundle with the official `mcpb` CLI and starts it to check that it answers an MCP `initialize` request. Pushes to `main` keep the bundle as a workflow artifact, and `v*` tags attach it to the matching GitHub release.

To cut a release, bump the version in both `package.json` and `manifest.json` (CI fails if they differ), merge, then push the tag `v<version>`. The workflow creates the GitHub release for that tag if it does not exist yet and attaches the `.mcpb` to it; write the release notes by editing that release afterwards. Files that must stay out of the bundle are listed in `.mcpbignore`.

To build one locally:

```bash
npm ci --omit=dev
npx @anthropic-ai/mcpb@2.1.2 pack . kanka-mcp.mcpb
npm ci   # restore the dev dependencies (eslint, prettier) removed above
```

TDQS

C2.5/5.0

Scored across 77 tools

Disambiguation4/5

Each entity type has a clear list/get/create/update/delete split, so tool selection is mostly determined by the entity being managed. The generic `search` tool and the broad `list_*`/`get_*` surface add slight overlap, but no two tools appear to do the same job.

Naming Consistency4/5

Nearly all tools follow a snake_case verb_noun pattern, such as `create_event` and `delete_calendar`. Minor deviations exist: `search` is a bare verb, and the spelling inconsistency between `list_organisations` and the CRUD tools using `organization` breaks the otherwise predictable naming.

Tool Count1/5

77 tools for CRUD across 16 entity types is extremely heavy and well past the 50+ threshold for an oversized surface. The same coverage could be exposed with fewer generic or grouped tools, and this count is likely to overwhelm tool selection.

Completeness4/5

Core lifecycle coverage is strong: every major entity type has list/get/create/update/delete operations, avoiding obvious CRUD dead ends. However, campaign-level operations, relations, tags, posts, members, and other Kanka features are absent, so non-CRUD workflows may hit gaps.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive