1. Conduid
  2. AI
  3. Raglight
MCP server · AI

Raglight

RAGLight is a modular framework for Retrieval-Augmented Generation (RAG). It makes it easy to plug in different LLMs, embeddings, and vector stores, and now includes seamless MCP integration to connect external tools and data sources.

81Excellent

Scored 6 hours ago · breakdown

About Raglight

Raglight is an MCP server published by Bessouat40 in the AI category: rAGLight is a modular framework for Retrieval-Augmented Generation (RAG). It makes it easy to plug in different LLMs, embeddings, and vector stores, and now includes seamless MCP integration to connect external tools and data sources.

The repository has 673 stars and 102 forks, with the last commit yesterday. Recent commit activity is the strongest signal that reported issues will get attention.

Install

From source
git clone https://github.com/Bessouat40/RAGLight

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Raglight

Powered by Claude · Grounded in docs

I know everything about Raglight. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 6 hours ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

Releases

3.4.7v3.4.7 · 24 Mar 2026What's Changed Add streaming support for all LLM providers by @Bessouat40 in https://github.com/Bessouat40/RAGLight/pull/138 Add Bedrock Provider Add tests for RAG pipeline, streaming, document processors, and scrapper by @Bessouat40 in…
3.2.0v3.2.0 · 12 Mar 2026What's Changed Improve/UI by @Bessouat40 in https://github.com/Bessouat40/RAGLight/pull/131 add reformulation by @Bessouat40 in https://github.com/Bessouat40/RAGLight/pull/133 improve history management by @Bessouat40 in…
3.1.1v3.1.1 · 5 Mar 2026Fix CLI bug
3.1.0v3.1.0 · 5 Mar 2026Added `raglight serve --ui` — launches a Streamlit chat interface alongside the REST API `--ui-port` option to configure the Streamlit port (default: `8501`) Chat tab with full conversation history and markdown rendering Upload tab to…
3.0.0v3.0.0 · 4 Mar 2026New Features REST API Server (https://github.com/Bessouat40/RAGLight/pull/126) New raglight serve CLI command to deploy a RAG pipeline as a REST API without writing any Python code Built on FastAPI with automatic Swagger UI at /docs Fully…

README

RAGLight

RAGLight 4 is a small, typed Python toolkit for composing classic and agentic retrieval-augmented generation pipelines. The core package has no third-party runtime dependency: applications inject an LLM, an embedding model, a vector store, and optional behavior through public structural protocols.

RAGLight 4 is a breaking release. The v3 builder, global settings, API server, CLI, UI, and legacy agentic runtime were removed instead of being carried as compatibility layers. The v4 agentic API is a new implementation.

Requirements

  • Python 3.11 or newer
  • One optional integration extra when using a built-in provider
pip install raglight
pip install "raglight[ollama,chroma,documents]"

Available extras are openai, ollama, mistral, gemini, bedrock, huggingface, documents, chroma, qdrant, langfuse, and agentic-mcp.

Copy-paste examples

The examples index contains complete runnable workflows for classic RAG with Ollama, OpenAI, and OpenAI-compatible endpoints; recursive directory ingestion; Agentic RAG; MCP tools; custom agents; and custom components. Each provider example includes its exact installation and execution commands, while offline examples require no credentials or external services.

Public API

The stable core is deliberately narrow:

from raglight import PipelineConfig, RAGPipeline
from raglight.contracts import (
    DocumentProcessor,
    EmbeddingModel,
    IngestionVectorStore,
    LLM,
    Reranker,
    VectorStore,
)
from raglight.models import (
    And,
    Document,
    Eq,
    ExecutionEvent,
    FolderSource,
    In,
    MatchNone,
    Or,
    RAGResponse,
    RetrievalFilter,
)

The contracts are structural protocols. Custom components do not inherit from RAGLight classes and do not need registry entries.

from raglight import PipelineConfig, RAGPipeline
from raglight.models import Document, RetrievalFilter


class MyLLM:
    def generate(self, input: dict[str, object]) -> str:
        return "RAGLight is extended through structural component contracts."


class MyEmbeddings:
    def embed_documents(self, texts: list[str]) -> list[list[float]]:
        return [[float(len(text))] for text in texts]

    def embed_query(self, text: str) -> list[float]:
        return [float(len(text))]


class MyVectorStore:
    def similarity_search(
        self,
        question: str,
        k: int = 5,
        *,
        retrieval_filter: RetrievalFilter | None = None,
    ) -> list[Document]:
        if retrieval_filter is not None:
            raise NotImplementedError("this store does not support filtering")
        return [Document(page_content="RAGLight uses dependency injection.")][:k]

    def add_documents(self, documents: list[Document]) -> None:
        pass


pipeline = RAGPipeline(
    llm=MyLLM(),
    embeddings=MyEmbeddings(),
    vector_store=MyVectorStore(),
    config=PipelineConfig(top_k=3),
)

response = pipeline.generate("How is RAGLight extended?")
print(response.answer)
print(response.sources)
print(response.events)

generate() returns an immutable RAGResponse. Its answer, sources, structured execution events, per-stage timings, metadata, and trace_id can be consumed directly or converted into transport-friendly values with response.to_dict(). Streaming continues to yield text chunks through pipeline.stream(...).

Use provider-neutral filters when retrieval must stay inside an application scope. Qdrant and Chroma translate the same filter tree at their integration boundaries:

from raglight.models import And, Eq, In

scope = And(
    Eq("workspace_id", "ws-123"),
    In("file_id", ["file-a", "file-b"]),
)
response = pipeline.generate("Summarize these files", retrieval_filter=scope)

None keeps trusted standalone retrieval unrestricted. MatchNone() always returns no sources without querying a backend. Applications must calculate authorization scopes server-side; RAGLight does not implement users or ACLs.

The pipeline itself is stateless and safe to share between users. Pass history explicitly for stateless requests, or create an isolated session when RAGLight should retain completed turns:

response = pipeline.generate("One-off question", history=[])

session = pipeline.create_session(session_id="user-123")
first = session.generate("Remember this question")
chunks = list(session.stream("What did I ask?"))

print(session.history)
session.clear()

Conversational query reformulation is opt-in and uses the configured LLM only when history is present:

pipeline = RAGPipeline(
    llm=llm,
    embeddings=embeddings,
    vector_store=vector_store,
    config=PipelineConfig(top_k=5, reformulate_queries=True),
)

The rewritten value is used for retrieval and reranking; generation still sees the original question and history. Successful responses expose the rewritten query in response.metadata["retrieval_query"] and add a reformulation event.

A session commits a turn only after generation or streaming completes. Failed or abandoned streams do not leave partial conversation state behind. Separate sessions share configured components without sharing history.

See examples/extending/custom_components.py for a complete executable example.

Agentic RAG

Agentic execution has a deliberately separate public namespace and does not change the deterministic RAGPipeline:

from raglight.agentic import AgenticPipeline, FunctionTool

pipeline = AgenticPipeline(
    llm=llm,
    embeddings=embeddings,
    vector_store=vector_store,
    tools=[
        FunctionTool(
            "weather",
            "Return weather for a city.",
            lambda arguments: weather_client.lookup(arguments["city"]),
            {"type": "object", "required": ["city"]},
        )
    ],
    max_steps=4,
)

response = pipeline.generate("Use the knowledge base and weather tool to answer")

The built-in retrieve tool uses the injected vector store and optional reranker. The default planner asks the injected LLM for strict JSON decisions. Pass agent=my_agent to replace it with any object implementing the structural Agent.decide(context) contract; no inheritance or framework adapter is required. Tool failures become observations that the agent can recover from, while an unfinished loop raises AgentStepLimitError at the configured budget.

Use pipeline.create_session(...) for isolated agentic history. Async tools are supported through await pipeline.agenerate(...). MCP is an optional adapter:

pip install "raglight[agentic-mcp]"

raglight.agentic.mcp.MCPTool wraps a tool on a caller-managed, connected MCP client. See the Agentic RAG examples and the public API guide for complete examples.

Directory ingestion

Directory ingestion belongs to the public pipeline, not to a vector-store adapter. Inject the lazy document-processor registry, then pass one or more folder sources:

from raglight.integrations import default_registries
from raglight.models import FolderSource

pipeline = RAGPipeline(
    llm=llm,
    embeddings=embeddings,
    vector_store=vector_store,
    document_processors=default_registries.document_processors,
)
result = pipeline.ingest([FolderSource(path="./knowledge")])

print(result.processed_count, result.indexed_count)
print(result.skipped, result.failures)

Traversal is recursive and deterministic by default. Common generated directories and symlinks are skipped, unsupported extensions are reported, and one failed file does not discard successful files. Use ignored_directories, recursive, chunk_size, and chunk_overlap on each FolderSource to customize discovery and processing. See examples/classic/directory_ingestion.py for a local Ollama and Chroma example.

Built-in integrations

Import integrations explicitly so importing raglight never loads an optional provider SDK:

from raglight.integrations.ollama import OllamaEmbeddings, OllamaLLM
from raglight.integrations.chroma import ChromaVectorStore
from raglight.integrations import default_registries

embeddings = OllamaEmbeddings(model_name="nomic-embed-text")
vector_store = ChromaVectorStore(
    collection_name="knowledge",
    embeddings_model=embeddings,
    persist_directory="./raglight-db",
)
llm = OllamaLLM(model_name="llama3.1:8b")

pipeline = RAGPipeline(
    llm=llm,
    embeddings=embeddings,
    vector_store=vector_store,
    document_processors=default_registries.document_processors,
)

Provider modules and public classes:

Module Classes
raglight.integrations.openai OpenAILLM, OpenAIEmbeddings
raglight.integrations.ollama OllamaLLM, OllamaEmbeddings
raglight.integrations.gemini GeminiLLM, GeminiEmbeddings
raglight.integrations.bedrock BedrockLLM, BedrockEmbeddings
raglight.integrations.mistral MistralLLM
raglight.integrations.lmstudio LMStudioLLM
raglight.integrations.huggingface HuggingFaceEmbeddings, HuggingFaceReranker
raglight.integrations.chroma ChromaVectorStore
raglight.integrations.qdrant QdrantVectorStore
raglight.integrations.documents TextProcessor, CodeProcessor, PDFProcessor, VlmPDFProcessor
raglight.integrations.langfuse LangfuseTracer

Native Langfuse tracing

pip install "raglight[langfuse]"
from raglight.integrations.langfuse import LangfuseTracer

tracer = LangfuseTracer()
pipeline = RAGPipeline(
    llm=llm,
    embeddings=embeddings,
    vector_store=vector_store,
    tracer=tracer,
)

The SDK reads its standard LANGFUSE_* environment variables. Classic RAG creates nested reformulation, retrieval, reranking, and generation observations. Agentic RAG creates decision and tool observations through the same tracer= argument. Call tracer.flush() before a short-lived process exits.

Registry-backed configuration

Direct component injection remains the primary API. Registries provide an optional path for serializable JSON or TOML configuration without provider-specific branches in the pipeline:

top_k = 3
reformulate_queries = true

[llm]
name = "ollama"
[llm.options]
model_name = "llama3.1:8b"
preload_model = false

[embeddings]
name = "ollama"
[embeddings.options]
model_name = "nomic-embed-text"

[vector_store]
name = "chroma"
[vector_store.options]
collection_name = "knowledge"
persist_directory = "./raglight-db"
from raglight import PipelineConfig, RAGPipeline
from raglight.integrations import default_registries

config = PipelineConfig.from_file("raglight.toml")
pipeline = RAGPipeline.from_config(config, registries=default_registries)

Custom factories may opt into named configuration:

default_registries.llms.register("my-llm", MyLLM)

Registration is never required when passing a component instance directly. See examples/extending/registry_configuration.py for an offline custom-registry example.

Architecture

Dependencies point inward:

integrations -> registry/contracts/models <- pipeline
                                      ^---- agentic
  • registry primitives, contracts, and models are dependency-free.
  • pipeline and agentic are separate sibling application layers.
  • neither application layer imports concrete integrations or the other layer.
  • built-in integrations own their optional SDK dependencies.
  • agentic orchestration is intentionally separate from the classic RAG API.

The detailed boundaries are documented in docs/architecture.md, and the v3 migration table is in docs/migration-v3-to-v4.md.

Development

The project follows test-driven development. Every behavior change starts with a failing test, then the smallest implementation, then refactoring while the suite remains green.

make install-dev
make check

make check runs formatting, linting, type checking, architecture rules, unit tests, integration tests, end-to-end tests, and an isolated wheel validation. See docs/testing.md and docs/development.md for the contribution workflow.

License

RAGLight is distributed under the MIT License.

README fetched from the repository 6 hours ago. The original is authoritative.

Questions

About Raglight

How do I install Raglight?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Raglight safe to use with an AI agent?

Its trust score is 81 out of 100 (excellent). It passes 5 of the 6 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Raglight still maintained?

Yes — the last commit was yesterday. The repository has 673 stars and 102 forks and 16 open issues.