Skip to content

MCP Server API

The MCP server module exposes corpus search as tools for LLM clients via the Model Context Protocol (MCP).

Optional Module

This module requires the mcp extra:

pip install ifcraftcorpus[mcp]

Overview

The MCP server allows LLMs like Claude to search the IF Craft Corpus directly during conversations. It provides tools for searching, browsing, and retrieving craft guidance.

Quick Start

Running the Server

# Using uvx (recommended)
uvx ifcraftcorpus-mcp

# Using Python directly
python -m ifcraftcorpus.mcp_server

Claude Desktop Configuration

Add to your Claude Desktop config file (claude_desktop_config.json):

{
    "mcpServers": {
        "if-craft-corpus": {
            "command": "uvx",
            "args": ["ifcraftcorpus-mcp"]
        }
}
}

Verbose Logging

Set LOG_LEVEL (for example INFO, DEBUG) or VERBOSE=1 before launching the MCP server to emit detailed logs to stderr without interfering with stdio transport. The same variables work for the CLI (ifcraftcorpus) and the Docker image.

Available Tools

search_corpus

Search the IF Craft Corpus for writing guidance.

@mcp.tool
def search_corpus(
    query: str,
    cluster: str | None = None,
    limit: int = 5,
) -> list[dict]

Parameters:

Parameter Type Default Description
query str required Search query describing what guidance you need
cluster str \| None None Topic cluster to filter by
limit int 5 Maximum results (1-20)

Valid Clusters:

  • narrative-structure
  • prose-and-language
  • genre-conventions
  • audience-and-access
  • world-and-setting
  • emotional-design
  • scope-and-planning
  • craft-foundations
  • agent-design
  • game-design

Returns: List of dicts with keys: source, title, cluster, content, topics.

Example Queries:

  • "dialogue subtext"
  • "branching narrative"
  • "pacing action scenes"
  • "horror atmosphere"

get_document

Get a specific document from the corpus by name.

@mcp.tool
def get_document(name: str) -> dict | None

Parameters:

Parameter Type Description
name str Document name (e.g., "dialogue_craft")

Returns: Full document with title, summary, cluster, topics, and all sections. Returns None if not found.

list_documents

List all documents in the corpus.

@mcp.tool
def list_documents(cluster: str | None = None) -> list[dict]

Parameters:

Parameter Type Default Description
cluster str \| None None Optional cluster to filter by

Returns: List of dicts with keys: name, title, cluster, topics.

list_clusters

List all topic clusters with document counts.

@mcp.tool
def list_clusters() -> list[dict]

Returns: List of dicts with keys: name, document_count.

corpus_stats

Get statistics about the corpus.

@mcp.tool
def corpus_stats() -> dict

Returns: Dict with keys:

  • document_count - Total number of documents
  • cluster_count - Number of clusters
  • clusters - List of cluster names
  • semantic_search_available - Whether embeddings are loaded

Functions

run_server

def run_server(
    transport: Literal["stdio", "http"] = "stdio",
    host: str = "127.0.0.1",
    port: int = 8000,
) -> None

Run the MCP server with the specified transport.

Parameters:

Parameter Type Default Description
transport str "stdio" Transport protocol ("stdio" or "http")
host str "127.0.0.1" Host for HTTP transport
port int 8000 Port for HTTP transport

Example:

from ifcraftcorpus.mcp_server import run_server

# Run with stdio (default, for CLI clients)
run_server()

# Run as HTTP server
run_server(transport="http", host="0.0.0.0", port=8080)

get_corpus

def get_corpus() -> Corpus

Get or create the global Corpus instance used by the server.

Returns: The shared Corpus instance.

Server Configuration

The FastMCP Instance

from fastmcp import FastMCP

mcp = FastMCP(
    name="IF Craft Corpus",
    instructions="""
    This server provides access to the Interactive Fiction Craft Corpus,
    a curated knowledge base for writing interactive fiction. Use the tools
    to search for craft guidance on topics like narrative structure, dialogue,
    branching, prose style, and genre conventions.
    """,
)

HTTP Transport

For web-based integrations, run the server in HTTP mode:

# Start HTTP server
python -c "from ifcraftcorpus.mcp_server import run_server; run_server(transport='http', port=8080)"

The server will be available at http://localhost:8080.

Programmatic Usage

You can also use the MCP tools programmatically:

from ifcraftcorpus.mcp_server import search_corpus, get_document, list_clusters

# Search for content
results = search_corpus("dialogue techniques", limit=3)
for r in results:
    print(f"{r['source']}: {r['content'][:100]}...")

# Get a specific document
doc = get_document("dialogue_craft")
if doc:
    print(doc["title"])

# List clusters
clusters = list_clusters()
for c in clusters:
    print(f"{c['name']}: {c['document_count']} docs")