Skip to content

MCP server API

locallore.server.mcp

mcp = FastMCP('LocalLore', instructions='Offline memory for local Claude Code sessions.', streamable_http_path='/mcp', stateless_http=True, json_response=True, transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=True, allowed_hosts=['127.0.0.1:8765'], allowed_origins=['http://127.0.0.1:8765'])) module-attribute

healthz(_request) async

Return non-sensitive liveness after migration and listener startup.

Source code in src/locallore/server/mcp.py
@mcp.custom_route(  # type: ignore[untyped-decorator]
    "/healthz", methods=["GET"], include_in_schema=False
)
async def healthz(_request: Request) -> JSONResponse:
    """Return non-sensitive liveness after migration and listener startup."""
    return JSONResponse({"status": "ok"})

statusz(_request) async

Source code in src/locallore/server/mcp.py
@mcp.custom_route(  # type: ignore[untyped-decorator]
    "/statusz", methods=["GET"], include_in_schema=False
)
async def statusz(_request: Request) -> JSONResponse:
    runtime = _runtime
    status = get_status(
        Settings.from_env().database_path,
        runtime.status() if runtime is not None else None,
    )
    return JSONResponse(status)

locallore_status()

Report LocalLore index and offline-runtime status.

Source code in src/locallore/server/mcp.py
@mcp.tool()
def locallore_status() -> Status:
    """Report LocalLore index and offline-runtime status."""
    runtime = _runtime
    return get_status(
        Settings.from_env().database_path,
        runtime.status() if runtime is not None else None,
    )

Search indexed session history using full-text search and filters.

Source code in src/locallore/server/mcp.py
@mcp.tool()
def locallore_search(
    query: str,
    project: str | None = None,
    after: str | None = None,
    before: str | None = None,
    role: str | None = None,
    files: list[str] | None = None,
    limit: int = 8,
) -> SearchResponse:
    """Search indexed session history using full-text search and filters."""
    runtime = _runtime
    if runtime is None:
        raise RuntimeError("LocalLore HTTP runtime is not ready")
    with connect(Settings.from_env().database_path) as connection:
        return search_messages(
            connection,
            query,
            embedder=runtime.search_embedder,
            project=project,
            after=after,
            before=before,
            role=role,
            files=files,
            limit=limit,
        )

locallore_context(session_id, message_id, before=3, after=3)

Return bounded messages surrounding one search result.

Source code in src/locallore/server/mcp.py
@mcp.tool()
def locallore_context(
    session_id: str,
    message_id: str,
    before: int = 3,
    after: int = 3,
) -> ContextResponse:
    """Return bounded messages surrounding one search result."""
    with connect(Settings.from_env().database_path) as connection:
        return get_context(
            connection, session_id, message_id, before=before, after=after
        )

run_http_server()

Serve the persistent, multi-client Streamable HTTP transport.

Source code in src/locallore/server/mcp.py
def run_http_server() -> None:
    """Serve the persistent, multi-client Streamable HTTP transport."""
    import uvicorn

    app = mcp.streamable_http_app()
    app.state.locallore_original_lifespan = app.router.lifespan_context
    app.router.lifespan_context = _daemon_lifespan
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        log_level="info",
    )