Secure Model Context Protocol (MCP) Server
Give AI models and agents direct access to enterprise knowledge databases while enforcing strict, server-side Access Control Lists (ACLs). Prevent prompt injection leaks and unauthorized document retrieval.
Server-Side Security Filtering
Dynamic pre-filtering inside database queries (PostgreSQL/pgvector) guarantees LLMs never receive raw data matching unauthorized ACLs, eliminating context boundary bypasses.
Identity & Role Propagation
Accepts user principal identities (email, username) and LDAP/Active Directory group roles at query time. Seamlessly maps caller tokens to repository Security SIDs.
Spring AI 2.0 Native
Built directly into the oc-runtime module using Spring AI standard `@McpTool` annotations and WebMVC/SSE transport protocols for seamless Java ecosystem integration.
Zero-Trust Retrieval Pipeline
How OpenCrawling intercepts AI client requests to enforce document permissions before vector store search execution.
Exposed MCP Tools Specification
The standard tools made dynamically available to connected LLMs and AI agent frameworks.
Performs semantic vector similarity search on indexed enterprise documents, pre-filtering results on the server using the caller's identity and group permissions.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | String | Yes | Natural language search phrase or keywords. |
| userPrincipal | String | Yes | User email or principal identity performing the query. |
| userRoles | String | Optional | Comma-separated roles/groups (e.g. finance,engineering). |
| maxResults | Integer | Optional | Maximum top-K results to return (default: 5). |
| minScore | Double | Optional | Minimum vector similarity threshold (0.0 - 1.0). |
| dimensions | Integer | Optional | Target vector dimension store (384, 768, or 1024). |
Retrieves complete document content and metadata for a specific URI, verifying caller authorization prior to payload retrieval.
| Parameter | Type | Required | Description |
|---|---|---|---|
| documentUri | String | Yes | Target document URI (e.g. file:///data/reports/q3.pdf). |
| userPrincipal | String | Yes | User principal identity verifying access rights. |
| userRoles | String | Optional | Comma-separated group memberships of caller. |
Returns a list of all indexed documents and knowledge sources accessible to the specified user identity.
| Parameter | Type | Required | Description |
|---|---|---|---|
| userPrincipal | String | Yes | User principal identity for ACL enumeration. |
| userRoles | String | Optional | Comma-separated group memberships. |
Client Integration Setup
Configure your preferred AI environment to talk directly to the OpenCrawling Secure MCP Server.
Add the server entry to your local claude_desktop_config.json:
{
"mcpServers": {
"opencrawling-secure-vector-mcp": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/client-cli",
"sse",
"http://localhost:8080/mcp/sse"
]
}
}
}
Add entry in workspace or global ~/.cursor/mcp.json:
{
"mcpServers": {
"opencrawling-secure-vector-mcp": {
"url": "http://localhost:8080/mcp/sse"
}
}
}
Add entry to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"opencrawling-mcp": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/client-cli",
"sse",
"http://localhost:8080/mcp/sse"
]
}
}
}
Add SSE server provider in ~/.continue/config.json:
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "sse",
"url": "http://localhost:8080/mcp/sse"
}
}
]
}
}
Register via agy CLI or ~/.gemini/antigravity-cli/mcp.json:
# Command line setup:
agy mcp add opencrawling-mcp http://localhost:8080/mcp/sse --transport sse
# Configuration JSON:
{
"mcpServers": {
"opencrawling-mcp": {
"transport": "sse",
"url": "http://localhost:8080/mcp/sse"
}
}
}
Query the MCP server asynchronously using the Python mcp library:
import asyncio
from mcp import ClientSession
from mcp.client.sse import sse_client
async def main():
async with sse_client("http://localhost:8080/mcp/sse") as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"secureVectorSearch",
arguments={
"query": "Q3 Financial Growth Strategy",
"userPrincipal": "alice@company.com",
"userRoles": "finance,executives",
"maxResults": 5
}
)
print(result.content)
asyncio.run(main())
Consumer settings & Service injection in Spring Boot Java microservices:
# application.yml:
spring:
ai:
mcp:
client:
enabled: true
name: opencrawling-client
sse:
opencrawling-server:
base-url: http://localhost:8080
sse-endpoint: /mcp/sse
// Java Service Code:
@Autowired
private McpClient mcpClient;
public String searchKnowledge(String userEmail, String query) {
var response = mcpClient.callTool("secureVectorSearch", Map.of(
"query", query,
"userPrincipal", userEmail,
"userRoles", "engineering"
));
return response.content().toString();
}
Direct manual SSE listening and JSON-RPC execution via cURL:
# 1. Listen to SSE Stream:
curl -N -H "Accept: text/event-stream" http://localhost:8080/mcp/sse
# 2. Call Tool via JSON-RPC POST (use sessionId from SSE output):
curl -X POST "http://localhost:8080/mcp/message?sessionId=YOUR_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "secureVectorSearch",
"arguments": {
"query": "Kubernetes cluster security",
"userPrincipal": "devops@company.com",
"userRoles": "engineering"
}
}
}'
Run the dedicated MCP microservice using docker container build:
docker build -f docker/Dockerfile.mcp-server -t opencrawling-mcp-server .
docker run -p 8080:8080 \
-e OPENCRAWLING_MCP_SERVER_ENABLED=true \
-e SPRING_AI_MCP_SERVER_ANNOTATION_SCANNER_ENABLED=true \
opencrawling-mcp-server