Skip to main content

LoreHub MCP

An MCP server that lets AI agents (Claude, Cursor and any other MCP client) read a LoreHub world: its stories and dialogues, its lore documents, its timeline, each story's route map and variables, translations, the Export Schema JSON for your engine, and counts. With a Read key it only reads. With a Write key it can also create and edit content, but it never deletes anything.

More on the LoreHub MCP page.

What you can ask

Each role gets something different from the same world. Some example asks:

  • Writers: "Read the dialogue Tom at Grandpa's and tell me where Grandpa sounds out of character." "Does this scene contradict anything in the lore or the timeline?" (the continuity_check prompt)
  • Lore keepers: "Give me an overview of the world, then list every document tagged faction." "What happened between 1200 and 1250, and who was involved?"
  • Narrative designers: "Show me the story map of Episode 1: which links conflict, and where is has_key set and checked?" "Check this dialogue for dead ends and unused variables."
  • Directors and artists: "Turn the Meta Areas of this dialogue into a reference brief." "Write a shot list for this scene." (see Meta Areas)
  • Localisers: "Review the German translation of this dialogue and list what is missing or outdated." (the translation_review prompt)
  • Programmers: "Get the export of this dialogue and write a Godot loader for it." (the engine_import_guide prompt)
  • Producers: "How many words does each story have, how many lines does each character speak, and how far along is each translation?"

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 key belongs to one world. LoreHub accepts it only in that world, never in other worlds, and never for your account, password, billing, members or sharing. A Read key only reads what your account can see. A Write key can also create and edit content, if your account can write in the world: pick Write under access when you create it. Use a Read key unless you want the agent to change your world. 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.3

0.4 adds seven read tools (get_world_overview, list_documents, get_timeline, get_story_map, get_translations, get_export, get_world_stats), seventeen write tools for Write keys, and three prompts (continuity_check, translation_review, engine_import_guide). The server now calls itself lorehub instead of lorehub-meta; the package is still lorehub-mcp, so your MCP config doesn't change. get_dialogue now also returns each node's node_id, each option's option_id and each link's linkId, for the write tools. The new tools need a LoreHub API with the 0.4 agent read endpoints (/api/v3/worlds/{world}/overview, …/documents, …/timeline, …/stats, …/storymap, …/translations, …/export).

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 check it", and it calls list_worlds, list_dialogues and check_dialogue in turn. get_world_overview lists the stories and documents with their ids, and 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

The tools come in two groups: reads, which work with any key, and writes, which need a Write key.

Reads

Every API call counts against the world's daily limit, so every tool but two answers 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.
get_world_overview(world_id) 1 The canon map: stories with their dialogue counts, documents grouped by folder and by tag, top-level documents, and counts of stories, dialogues, documents, tags and timeline events.
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.
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.
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.
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.
list_documents(world_id, tag?, parent_id?, name?, limit=100) 1 Documents with their parent and tags, filtered by tag, folder or name (up to 200).
get_timeline(world_id, from_year?, to_year?) 1 The calendar (years, months and their days) and the instant and lasting events in date order, each with a readable date and its linked documents.
get_story_map(world_id, game_id) 1 The story's route map (dialogues with what they require and produce, links with their check and why), its route scopes as a tree, and every variable with the dialogues and nodes that set and check 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.
get_translations(world_id, game_id, dialogue_id, language?, only_untranslated=false) 1 The source language, each language's policy and progress, and each line and option with its key, speaker, source and per language its translation and status (translated, outdated, missing or fallback).
get_export(world_id, game_id, dialogue_id) 1 The dialogue's Export Schema v2 JSON, as the Export button gives it, with a count of each resource type. It doesn't record an export in LoreHub.
get_world_stats(world_id, game_id?) 1 Per story: dialogues, nodes, lines, options and words, lines and words per character, and translation progress per language. Plus the world's totals.
get_dialogue_meta(world_id, dialogue_id, area?, include_nodes=true) 2–3 A dialogue's Meta Areas. See Meta Areas.

Writes

With a Write key, the agent can create and edit a world's content through the same endpoints the LoreHub app uses, so every change goes through LoreHub's checks, plan limits and live updates (people with the dialogue open see it change). Each change shows up in LoreHub's history under the key's owner, like an edit in the app; the key's id is recorded in LoreHub's request logs. With a Read key, a write tool fails with a message saying a Write key is needed.

Agents can't delete. There are no delete tools, and no tool removes something it wasn't asked to change: edit_node refuses a shorter list of lines, edit_document only adds tags, edit_meta_area merges rules, and empty text is refused everywhere. Delete in LoreHub. The tools that replace a value (a name, a line, a description, a translation) are marked as destructive for MCP clients that ask before those.

The write tools take GUIDs: node_id, option_id and linkId from get_dialogue, lineId from get_translations, area ids from get_dialogue_meta.

Tool API calls What it does
create_dialogue(world_id, game_id, name) 2 Creates a dialogue in a story.
rename_dialogue(world_id, dialogue_id, name) 1 Renames a dialogue.
add_node(world_id, dialogue_id, x, y, after_node_id?, speaker_document_id?, lines?) 1, plus 1 + 2 per speaker and line Adds a node, optionally after another node, with a speaker and lines.
edit_node(world_id, dialogue_id, node_id, lines?, speaker_document_id?) 1 + 1 per changed line (2 per new line) Changes a node's speaker and lines in place. Send all its lines; new ones are added at the end.
move_node(world_id, node_id, x, y) 1 Moves a node on the canvas.
set_node_meta(world_id, game_id, node_id, values) 2 + 1 per value (2 for a new one) Sets meta values by field name, like shot = close_up. Other fields stay.
add_option(world_id, game_id, dialogue_id, node_id, text, conditions?) 2, plus 1 + 1 per condition Adds an option, optionally shown only when variables have given values.
edit_option(world_id, node_id, option_id, text) 1 Changes an option's text.
link_nodes(world_id, game_id, dialogue_id, to_node_id, from_node_id?, from_option_id?, conditions?) 1, plus 1 + 1 per condition Links a node, an option or the dialogue's start to a node, optionally with conditions.
create_variable(world_id, game_id, name, default?, comment?) 1 Creates a true/false story variable.
set_variable_on_node(world_id, game_id, dialogue_id, node_id, variable, value?) 2 Makes a node set a variable when it plays.
create_document(world_id, name, description?, parent_id?, tags?) 1, plus 1 each for description and parent, 1 + 1–2 per tag Creates a document. The description is simple Markdown (headings, paragraphs, lists, bold, italic).
edit_document(world_id, document_id, name?, description?, parent_id?, add_tags?) 1 per part Changes only what you send. A description replaces the whole text; tags are only added.
relate_documents(world_id, document_id, related_document_id, relation) 2 Relates two documents by a relation side name, like Son in Father / Son.
add_meta_area(world_id, dialogue_id, title, x, y, width, height, note?, color?, game_id?, rules?) 1, plus 2 for rules Draws a Meta Area.
edit_meta_area(world_id, dialogue_id, area_id, …) 1 + 1 per part (+1 for rules) Changes an area's text, place, size or rules. Only what you send changes; rules are merged.
set_translation(world_id, line_id, language, text) 1 Writes a line's translation in one language.

Prompts

Prompts tell the agent which tools to call, so it spends as few API calls as it can:

Prompt For Arguments
continuity_check Writers, lore keepers world_id, dialogue_id: checks a scene against the documents and the timeline.
translation_review Localisers world_id, game_id, dialogue_id, language: missing and outdated rows, meaning, tone and terms.
engine_import_guide Programmers world_id, game_id, dialogue_id, engine (Unity, Godot or Unreal): the export's shape and loader code.
reference_brief Directors, artists world_id, dialogue_id: per Meta Area, subject, characters, shot, background and mood.
shot_list Directors world_id, dialogue_id: one numbered shot per node.
voice_casting_sheet Producers, audio world_id, game_id: one entry per speaking character with sample lines.

Meta Areas

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. get_dialogue_meta returns each area's title, note, priority and rules as field name: value, the nodes inside it with their speaker and lines, and the nodes where areas overlap (higher priority first). area filters by title text or area id. The third API call (the story's meta schema) is made only when an area has rules. A node is inside an area when the middle of its header is, the same rule the Dialogue Builder uses. More in the Meta Areas guide.

Example output:

{
  "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 API key from Profile → API keys: Read, or Write to let the agent change content.
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 calls the LoreHub API with your API key: GET for the read tools, and the app's own POST and PUT endpoints for the write tools. LoreHub has read-only endpoints shaped for agents (a dialogue's script, a document's text, the world's overview, timeline and stats, a story's lines, map and translations, a dialogue's export), so each tool needs as few calls as possible. No read writes anything: not export history, and not the empty route map or default timeline the app creates the first time you open one.

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, names, area titles, notes, rule values, document text and translations are written by your world's collaborators, so the server tells the agent to treat them as data, not instructions.

Not yet: gallery images, document text in search, timeline events and route map edits.

License

MIT

Metadata

Release files for lorehub-mcp 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lorehub-mcp 0.4.0
File Size Uploaded Provenance Actions
lorehub_mcp-0.4.0.tar.gz 38.7 kB With provenance Details for lorehub_mcp-0.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for lorehub-mcp 0.4.0
File Interpreter ABI Platform Actions
lorehub_mcp-0.4.0-py3-none-any.whl Python 3 none any Details for lorehub_mcp-0.4.0-py3-none-any.whl

Total release size: 70.9 kB

Release files / lorehub_mcp-0.4.0.tar.gz

Download URL lorehub_mcp-0.4.0.tar.gz
Size 38.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ad9699f94ee9c7abdfef8cb4d7271612af563e8cdadcbe09be4e7f9456846ff0
BLAKE2b-256 checksum
How to use checksums
a953f00f847f9795440c1db1a2e393dfc694165a2af16ef3caf6a4791316944a
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 log

Release files / lorehub_mcp-0.4.0-py3-none-any.whl

Download URL lorehub_mcp-0.4.0-py3-none-any.whl
Size 32.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59fdfd0b41f962f32cdbdec7e824cb5f8d92995eba9a8e939720df2703fa1e42
BLAKE2b-256 checksum
How to use checksums
961a1f9ee9ede935c898701281f5bbaffc1d1b198aba06c1f2343e8dce9a58e7
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 log

Security for lorehub-mcp 0.4.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.

Select from 2 files

Attestation for lorehub_mcp-0.4.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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page