Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ API_BASE_URL='http://X.X.X.X:APP_PORT' # Base URL of your FastAPI backe
# WEBSEARCH_TOP_K=5 # Number of web results to include (default: 5)
# WEBSEARCH_LANG=fr-FR # Search language/market (default: fr-FR)

# MCP SERVER
# Standalone Model Context Protocol server (openrag/api/mcp/server.py).
# OPENRAG_MCP_SERVER_NAME="OpenRAG MCP"
# OPENRAG_MCP_HOST=0.0.0.0
# OPENRAG_MCP_PORT=8081
# OPENRAG_MCP_PATH=/mcp
# OPENRAG_MCP_DEFAULT_TOP_K=5
# OPENRAG_MCP_MAX_TOP_K=50
# OPENRAG_MCP_SIMILARITY_THRESHOLD=0.8
# OPENRAG_MCP_DOWNLOAD_TIMEOUT=30.0
# OPENRAG_MCP_MAX_DOWNLOAD_BYTES=104857600 # 100 MiB

# LOGGING
LOG_LEVEL=DEBUG # See possible values https://loguru.readthedocs.io/en/stable/api/logger.html

Expand Down
16 changes: 16 additions & 0 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,19 @@ websearch:
fetch_timeout: 1.0
fetch_max_tokens: 500
fetch_verify_ssl: false

# --- MCP server ---
# Env: OPENRAG_MCP_SERVER_NAME, OPENRAG_MCP_HOST, OPENRAG_MCP_PORT,
# OPENRAG_MCP_PATH, OPENRAG_MCP_DEFAULT_TOP_K, OPENRAG_MCP_MAX_TOP_K,
# OPENRAG_MCP_SIMILARITY_THRESHOLD, OPENRAG_MCP_DOWNLOAD_TIMEOUT,
# OPENRAG_MCP_MAX_DOWNLOAD_BYTES
mcp:
server_name: OpenRAG MCP
host: 0.0.0.0
port: 8081
path: /mcp
default_top_k: 5
max_top_k: 50
similarity_threshold: 0.8
download_timeout: 30.0
max_download_bytes: 104857600 # 100 MiB
1 change: 1 addition & 0 deletions openrag/api/mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Standalone MCP (Model Context Protocol) server for OpenRAG."""
51 changes: 51 additions & 0 deletions openrag/api/mcp/auth_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Request-scoped auth context for the MCP server.

FastMCP tool callables receive only their declared arguments — there is no
FastAPI ``Request`` to thread the authenticated principal through. The
``MCPAuthContextMiddleware`` resolves the caller once per request and stashes
the principal here; the tool functions read it and forward it explicitly to
``MCPService`` (which never touches this module — it stays a pure
orchestrator).
"""

from __future__ import annotations

from contextvars import ContextVar, Token

_USER_ID: ContextVar[int | None] = ContextVar("openrag_mcp_user_id", default=None)
_IS_ADMIN: ContextVar[bool] = ContextVar("openrag_mcp_is_admin", default=False)
_ALLOWED_PARTITIONS: ContextVar[list[str] | None] = ContextVar("openrag_mcp_partitions", default=None)

AuthTokens = tuple[Token, Token, Token]


def set_auth_context(
*,
user_id: int | None,
is_admin: bool,
allowed_partitions: list[str] | None,
) -> AuthTokens:
return (
_USER_ID.set(user_id),
_IS_ADMIN.set(is_admin),
_ALLOWED_PARTITIONS.set(allowed_partitions),
)


def reset_auth_context(tokens: AuthTokens) -> None:
user_token, admin_token, partitions_token = tokens
_USER_ID.reset(user_token)
_IS_ADMIN.reset(admin_token)
_ALLOWED_PARTITIONS.reset(partitions_token)


def get_user_id() -> int | None:
return _USER_ID.get()


def is_admin() -> bool:
return _IS_ADMIN.get()


def get_allowed_partitions() -> list[str] | None:
return _ALLOWED_PARTITIONS.get()
Loading
Loading