LoreHub MCP
An MCP server that lets AI agents (Claude, Cursor and any other MCP client) read a LoreHub world: dialogues as scripts, the Meta Areas a director marked, documents such as characters and places, a search across the world, and a story's lines by speaker.
A director draws Meta Areas on the Dialogue Builder canvas: a shot, a location, a mood, with a note, a priority and meta rules such as shot = close_up. With this server, your agent reads those areas, the lines inside them and the characters who speak them, and turns them into references, shot lists, mood boards or voice casting sheets. It only reads: it never changes your world.
More on the LoreHub MCP page and in the Meta Areas guide.
Install
You need a LoreHub account with at least Viewer access to the world, and uv. Nothing else to install: uvx downloads and runs the server.
Create an API key
In LoreHub, open Profile → API keys, pick the world the key is for, give the key a name (for example "Claude Desktop"), leave its access on Read, choose when it expires (90 days unless you pick 30 days, 1 year or never) and select Create key. Copy the key, which starts with lh_: LoreHub shows it only once.
A Read key belongs to one world. LoreHub accepts it only for reading what your account can see in that world, never other worlds, never to change anything, and never for your account, password or billing. This server only reads, so it needs no Write key. For another world, create another key. Each world gets a number of API calls a day from its plan (10 on Free), shared by all its members' keys. You don't put your password anywhere. If a key leaks, or you stop using it, revoke it on the same page and it stops working at once. When a key expires, LoreHub rejects it: create a new one and put it in your MCP config.
uvx lorehub-mcp
Or with pip: pip install lorehub-mcp, then run lorehub-mcp.
Claude Code
claude mcp add lorehub --env LOREHUB_API_KEY=lh_your-key -- uvx lorehub-mcp
Claude Desktop
Settings → Developer → Edit Config, then add to claude_desktop_config.json:
{
"mcpServers": {
"lorehub": {
"command": "uvx",
"args": ["lorehub-mcp"],
"env": {
"LOREHUB_API_KEY": "lh_your-key"
}
}
}
}
Cursor
Add the same block to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):
{
"mcpServers": {
"lorehub": {
"command": "uvx",
"args": ["lorehub-mcp"],
"env": {
"LOREHUB_API_KEY": "lh_your-key"
}
}
}
}
Other MCP clients work the same way: run uvx lorehub-mcp over stdio with LOREHUB_API_KEY set.
Upgrading from 0.2
0.3 adds six tools and three prompts. get_dialogue_meta now lists an area's nodes by short id (node_04) with their speaker and lines, instead of full ids, and makes 2–3 API calls instead of 4. It needs a LoreHub API with the agent read endpoints (/api/v3/worlds/{world}/…/script, …/text, …/search, …/lines).
Upgrading from 0.1
0.1 signed in with LOREHUB_LOGIN and LOREHUB_PASSWORD (or LOREHUB_TOKEN). 0.2 no longer reads them. Create an API key, put it in LOREHUB_API_KEY, and delete the login and password from your MCP config. If that config was ever shared or synced, change your LoreHub password too.
Find your world and dialogue ids
You don't need to look them up yourself. Ask the agent, for example "List my LoreHub worlds, then find the dialogue Tom at Grandpa's and give me its Meta Areas", and it calls list_worlds, list_dialogues and get_dialogue_meta in turn. search_world finds a dialogue or character by any word in it.
To copy them by hand: open the dialogue in the Dialogue Builder. The address looks like app.lorehub.app/<owner>/<world>/game/<story id>?dialogue=<dialogue id>, so the dialogue id is after ?dialogue=. The world id comes from list_worlds, which returns the key's world.
Tools
Every API call counts against the world's daily limit, so most tools answer in one call. Each result carries calls_left_today when LoreHub reports it.
| Tool | API calls | What it returns |
|---|---|---|
list_worlds() |
1 | The key's world, with its id and your role. |
list_dialogues(world_id, game_id?, name?) |
1 with game_id, else 1 + 1 per story |
Stories and their dialogues with ids. name filters by dialogue name. |
get_dialogue(world_id, dialogue_id) |
1 | The dialogue as a script: story, start node, and each node in reading order with its short id (node_03), speaker, lines, options (text, conditions, target), next links with conditions, variables it sets, meta values and the Meta Areas it is in. Also the variables and characters it uses. |
get_dialogue_meta(world_id, dialogue_id, area?, include_nodes=true) |
2–3 | Each Meta Area's title, note, priority and meta rules as field name: value, the nodes inside it with speaker and lines, and the nodes where areas overlap (higher priority first). area filters by title text or area id. The third call (the story's meta schema) is made only when an area has rules. |
search_world(world_id, query, limit=20) |
1 | Matches in document names, dialogue names, dialogue lines and option texts (case-insensitive, at least 2 characters, up to 50 hits), with the dialogue, node and a snippet for lines. |
get_document(world_id, document_id) |
1 | A document's name, parent, tags, description as Markdown-like text, relations, and the dialogues that mention it. |
get_character_lines(world_id, game_id, speaker_document_id?) |
1 | Every line of a story grouped by speaker, with line and word counts, the line before each one and the node's meta values, plus the story's totals. |
check_dialogue(world_id, dialogue_id) |
2 | Nodes not reachable from the start, options without a target, nodes where the dialogue ends, variables set but never checked (or checked but never set), and a summary of the story's route map link checks. |
Prompts: reference_brief(world_id, dialogue_id) (per Meta Area: subject, characters, shot, background, mood), shot_list(world_id, dialogue_id) and voice_casting_sheet(world_id, game_id). Each tells the agent which tools to call, so it spends as few API calls as it can.
Example output of get_dialogue_meta:
{
"dialogue": "Tom at Grandpa's",
"dialogue_id": "…",
"areas": [
{"title": "Grandpa's house: wide", "priority": 1,
"rules": {"shot": "wide", "background": "grandpas_house"},
"nodes": [{"id": "node_01", "speaker": "Tom", "lines": ["Where is Grandpa today?"]},
{"id": "node_04", "speaker": "Grandpa", "lines": ["Did you find the key?"]}], "id": "…"},
{"title": "Close-up: Tom is crying", "note": "Tears, low light", "priority": 2,
"rules": {"shot": "close_up", "background": "grandpas_house", "tom_emotion": "crying"},
"nodes": [{"id": "node_04", "speaker": "Grandpa", "lines": ["Did you find the key?"]}], "id": "…"}
],
"overlaps": [{"node": "node_04", "areas": ["Close-up: Tom is crying (P2)", "Grandpa's house: wide (P1)"]}],
"calls_left_today": 94
}
Configuration
| Variable | Default | |
|---|---|---|
LOREHUB_API_KEY |
Required. Your read-only API key from Profile → API keys. | |
LOREHUB_API_URL |
https://api.lorehub.app |
Must be https:// and a lorehub.app host (plain http:// only for localhost), so the key can't be sent anywhere else. |
LOREHUB_ALLOW_CUSTOM_API_URL |
Set to 1 only if you run LoreHub on your own HTTPS host. |
|
LOREHUB_TIMEOUT |
30 |
Seconds per request. |
LOREHUB_LOG_LEVEL |
INFO |
Logs go to stderr. |
LOREHUB_NODE_WIDTH, LOREHUB_NODE_HEADER_HEIGHT |
200, 32 |
The canvas node card size. Leave them as they are. |
How it works
The server makes GET calls to the LoreHub API with your API key. LoreHub has read-only endpoints shaped for agents (a dialogue's script, a document's text, a search, a story's lines), so each tool needs as few calls as possible; none of them writes anything, not even export history. A node is inside a Meta Area when the middle of its header is, the same rule the Dialogue Builder uses, and LoreHub works that out for the script.
When the world's calls for the day are used up, tools fail with a clear message and the time the count resets.
Security: ids must be GUIDs, so a crafted id can't reach other API endpoints. The server doesn't follow redirects, doesn't log the key, and doesn't pass the API's error text on to the agent. Dialogue lines, area titles, notes, rule values and document text are written by your world's collaborators, so the server tells the agent to treat them as data, not instructions.
Not yet: gallery images, translations, timelines and exports.
License
MIT
Metadata
Release files for lorehub-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lorehub_mcp-0.3.0.tar.gz | 18.7 kB | With provenance | Details for lorehub_mcp-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lorehub_mcp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for lorehub_mcp-0.3.0-py3-none-any.whl |
Total release size: 35.5 kB
Release files / lorehub_mcp-0.3.0.tar.gz
| Download URL | lorehub_mcp-0.3.0.tar.gz |
|---|---|
| Size | 18.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
029e4b0614ac5363f4d08b78a99302ce39206e7bdd32a787258a47c28dedd3a1
|
|
BLAKE2b-256 checksum How to use checksums |
8e712677f6703164aabd14afaca33dd026a017eb58dca5f703f4dc17b6c716db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / lorehub_mcp-0.3.0-py3-none-any.whl
| Download URL | lorehub_mcp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 16.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
340a5e3aec3f580d9e4cf55502e4a32d66d98765bfe2d2c4b0dd298bd4c6ba0b
|
|
BLAKE2b-256 checksum How to use checksums |
078421936c7a20eaee06d21dad6667197931b7b76cc3ccfda72c77f2badd27a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logSecurity for lorehub-mcp 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for lorehub_mcp-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.