In the world of Generative AI, Large Language Models (LLMs) are transitioning from simple conversation partners to active, goal-oriented AI Agents. These agents need access to enterprise data stores—such as SharePoint sites, AWS S3 buckets, and local databases—to solve problems. However, giving AI models access to unstructured data creates a massive headache: how do you enforce enterprise document security boundaries?

If an employee asks an AI agent a question, the agent should only retrieve and synthesize information from files that the specific employee is authorized to see. Without query-time security checks, your AI system is highly susceptible to critical data leaks. Under typical RAG (Retrieval-Augmented Generation) architectures, prompt injection or broad search queries can lead to LLMs surfacing payroll details, partner agreements, or architectural blueprints to unauthorized users.

To solve this challenge, the OpenCrawling core team is excited to announce the release of the OpenCrawling® Secure MCP Server module, implemented via Spring AI and the Model Context Protocol (MCP).

1. What is the Model Context Protocol (MCP)?

Developed to standardize how LLMs connect to external data sources and tools, the Model Context Protocol (MCP) is an open-source standard designed by Anthropic and supported across the developer ecosystem. It establishes a protocol boundary between AI models (MCP Clients) and data resources (MCP Servers).

Rather than writing custom, fragile API integrations for every AI client or plugin framework, MCP allows servers to expose unified resources, prompts, and tools that any MCP-compliant LLM or IDE (like Claude Desktop, Cursor, or Antigravity) can call dynamically.

By exposing ingestion data through an MCP server, OpenCrawling provides a clean, secure channel for AI agents to query enterprise knowledge stores.

2. Architecture: Zero-Trust Context Retrieval

The OpenCrawling MCP implementation enforces Zero-Trust context retrieval. When an AI client requests context from the MCP Server, the query is not simply passed to the vector store. Instead, the server acts as an active security filter, validating the caller's identity (user principal and roles) and modifying the vector database query on the fly.

graph TD subgraph AI Client Context LLM[LLM Agent / Client] end subgraph OpenCrawling Runtime MCP[McpVectorServer] Auth[Authority Service] VecStore[PgVectorStore] end subgraph Security Boundary PG[(PostgreSQL + pgvector)] end LLM -->|1. secureVectorSearch - query, principal, roles| MCP MCP -->|2. Check/Map Access Token| Auth MCP -->|3. Build Filter Expression| VecStore VecStore -->|4. SQL Query with WHERE acl IN list| PG PG -->|5. Authorized Vector Chunks| VecStore VecStore -->|6. Chunks - Only Permitted Content| MCP MCP -->|7. Secure Context JSON| LLM

3. Inside the Code: Server-Side ACL Filtering

At the heart of the MCP implementation is the McpVectorServer component, built using Spring AI 2.0. The server exposes three core MCP tools using the standard @McpTool annotation:

  • secureVectorSearch: Performs similarity searches on vectorized enterprise documents, filtering results based on the caller's principal and roles.
  • getDocumentContent: Fetches the full text and metadata of a specific file, ensuring the caller has access permissions.
  • listAccessibleSources: Lists all indexed documents that are accessible to the caller.

Here is a snippet of how the server builds the security filters dynamically using the FilterExpressionBuilder:

@McpTool(description = "Perform a secure similarity search on vectorized enterprise knowledge documents.")
public List secureVectorSearch(
        @McpToolParam(description = "The query to search for", required = true) String query,
        @McpToolParam(description = "The user principal identity", required = true) String userPrincipal,
        @McpToolParam(description = "Roles/groups the caller belongs to", required = false) String userRoles
) {
    FilterExpressionBuilder b = new FilterExpressionBuilder();
    
    // 1. Always allow public documents
    var securityExpression = b.eq("acl", "public");

    // 2. Allow documents matching the user principal
    if (userPrincipal != null && !userPrincipal.trim().isBlank()) {
        securityExpression = b.or(securityExpression, b.eq("acl", userPrincipal.trim()));
    }

    // 3. Allow documents matching the user's active LDAP/OAuth groups
    if (userRoles != null && !userRoles.trim().isBlank()) {
        List rolesList = Arrays.stream(userRoles.split(","))
                .map(String::trim)
                .toList();
        securityExpression = b.or(securityExpression, b.in("acl", rolesList));
    }

    // 4. Submit secure search request to pgvector
    SearchRequest searchRequest = SearchRequest.builder()
            .query(query)
            .filterExpression(securityExpression.build())
            .topK(5)
            .build();

    return vectorStore.similaritySearch(searchRequest).stream()
            .map(doc -> new DocumentSearchResult(...))
            .toList();
}

Because this logic is executed entirely on the server side within the secure boundary of the Spring Boot runtime, the LLM client can never bypass the filter or gain access to raw database items that are unauthorized.

4. Configuring the MCP Server in Your Project

To enable the MCP server in your OpenCrawling runtime instance, you just need to include the spring-ai-starter-mcp-server-webmvc dependency in your Maven configuration:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
    <version>2.0.0</version>
</dependency>

Then, define the server name in your application.yml:

spring:
  ai:
    mcp:
      server:
        name: "opencrawling-secure-vector-mcp"
        transport: webmvc

Once you run the bootstrap runtime via mvn spring-boot:run, the MCP endpoints are exposed over HTTP/SSE, ready to be configured inside your Claude Desktop or custom AI agent configurations!

5. Why This Matters for the Future of Enterprise AI

As organizations move past basic chat applications and deploy fully autonomous AI agents that schedule meetings, write code, and query databases, context security must be absolute. The OpenCrawling® Secure MCP Server acts as an intelligent security guard: it ensures that while AI models are given the freedom to query database repositories, they are only given access to information the user is legally permitted to see.

Join the Discussion

We are actively developing repository connectors and security mappings. We'd love to hear your feedback:

Let's make enterprise AI secure, standard-driven, and open! 🛡️