Connector Release October 27, 2026 • 9 min read

Metadata-Driven Knowledge Work Automation Meets Enterprise RAG: Announcing the M-Files Repository Connector

Across legal, accounting, life sciences, engineering, and financial services, M-Files empowers enterprises with metadata-driven Knowledge Work Automation—organizing critical content by what it is rather than where it is stored. Today, we are thrilled to announce the official M-Files Repository Connector (oc-mfiles-repository-connector)! Crawl M-Files vaults via the M-Files Web Service (MFWS) REST API and Vault Application Framework (VAF) change feeds, overcome search truncation with recursive binary time-window splitting, preserve Single-File and Multi-File Document (MFD) lineage, normalize typed MFDataType properties, and enforce fail-closed Zero-Trust ACL component intersections across every vector store and MCP agent. 🚀🗂️

M-Files MFWS & VAF Enterprise Ingestion Pipeline Architecture
M-Files Vault (MFWS /REST & VAF)
→
MFilesRepositoryConnector (Time-Window Splitter)
→
Java 25 StructuredTaskScope + TempFileInputStream
→
Claim-Check Store (Ozone / S3)
→
OIS Document + Fail-Closed ACL Intersection
→
Vector Stores & Secure MCP Server

1. Why Metadata-Driven ECM Needs Purpose-Built RAG Ingestion

Unlike traditional folder-centric content repositories, M-Files organizes enterprise knowledge around rich object graphs—linking Documents, Customers, Projects, Matters, and Workflows through typed property definitions (PropertyDef) and dynamic views. Bridging an M-Files vault to an enterprise Retrieval-Augmented Generation (RAG) pipeline presents unique architectural challenges:

The new oc-mfiles-repository-connector was engineered from the ground up on the OpenCrawling SPI and Java 25 to solve each of these requirements natively while emitting standardized Open Ingestion Standard (OIS) documents and deletion tombstones.

⚠️

Licence & Session Policy: The connector requires a licensed, running M-Files Server (or M-Files Cloud vault) with the M-Files Web Service (REST API) enabled and an account with read access to the vault. OpenCrawling does not include M-Files or any M-Files licence. Each crawl scan holds one MFWS session and always terminates it cleanly via DELETE /session (automatically falling back to POST /session?_method=DELETE when IIS blocks HTTP DELETE).

2. Native MFWS Client, Triple Authentication & Host Pinning

At the transport layer, MFilesClient communicates directly with <server>/REST over native Java 25 HttpClient with zero heavyweight SDK dependencies. It supports three authentication modes configured via auth-type:

If a session token expires mid-crawl (HTTP 401 or 403), MFilesClient automatically re-authenticates once and retries the request. Transient rate limits (HTTP 429) and gateway errors (502–504) are retried with exponential backoff. Furthermore, when following file download URLs supplied by VAF payloads, the client enforces strict host pinning so authentication headers are never forwarded to external hosts.

3. Four Crawl Modes & Recursive Binary Time-Window Splitting

Enterprises organize M-Files vaults in different ways, so MFilesRepositoryConnector provides four distinct crawl modes via crawl-mode:

1. Class & Condition Search (search, default) & All Objects (all_objects)

Queries GET /objects per configured class (class-ids, passed as p100=<id>), restricted to object-type (0 = Document, or -1 to crawl all object types) and optional MFWS search conditions (search-query, such as p1020=5&q=contract, or plain text for quick search). Setting crawl-mode: all_objects crawls the entire vault without class or query restrictions.

2. Recursive View Traversal (view)

Traverses a configured M-Files view (view-id, e.g., 101 or v101/L5) via GET /views/<path>/items, recursively descending into sub-views, lookup/text property folders, and traditional folders up to depth 32. Because an object can appear under multiple property folders in a view, the connector tracks visited object keys and emits each object exactly once.

3. Vault Application Framework Change Feed (vaf)

Consumes the change feed (<vaf-base-path>/changes?since=<cursor>) and normalized object endpoint (<vaf-base-path>/object/{objType}/{objId}/{version}/normalized) of an M-Files VAF application—matching the protocol used by the Apache ManifoldCF M-Files connector—where effective permissions (including metadata-driven pseudo-users) are resolved server-side inside the vault.

Overcoming the MFWS Truncation Limit with Recursive Time-Window Splitting

Because MFWS truncates GET /objects responses at limit (batch-size, default 500) and offers no offset pagination, how do you guarantee 100% recall across millions of vault objects?

Whenever a search returns MoreResults: true, MFilesRepositoryConnector automatically switches to recursive last-modified time-window splitting using MFWS property 21 (LastModified, p21>= and p21<=). Starting from the lower bound (modified-after, the incremental watermark, or 1970-01-01T00:00:00Z) up to the scan start timestamp, the connector recursively bisects time intervals in half until every sub-window returns MoreResults: false, deduplicating objects that fall on window boundaries.

💡

Ad-Hoc Scan Path Overrides: Passing a custom job scan-path overrides the configured selection for that run without touching the incremental state file—paths starting with v<digits> (e.g., v101/L5) crawl that view, while MFWS conditions containing = or plain text execute an ad-hoc search.

4. Single-File, Multi-File (MFD), Non-File Objects & Version Modes

MFilesDocumentBuilder maps every M-Files object type and attachment topology into clean, canonical OIS URIs:

5. Typed Property Normalization (MFilesValues)

At connection time, the connector loads the vault's property definitions from GET /structure/properties. For each object, MFilesValues normalizes every property value according to its MFDataType under <property-prefix><camelCaseName> (default prefix: mfiles_prop_):

M-Files MFDataType Example Raw MFWS Input Normalized OIS Metadata Value OIS Metadata Key Example
Date (5) 2026-05-01T00:00:00Z 2026-05-01 (ISO local date) mfiles_prop_effectiveDate
Timestamp (7) 2026-09-27T17:20:00+02:00 2026-09-27T15:20:00Z (UTC instant) mfiles_prop_signedAt
Integer (2), Integer64 (11), Floating (3) 150000.00 150000 (stripped trailing zeroes) mfiles_prop_contractValue
Boolean (8) true / 1 true / false mfiles_prop_autoRenew
Lookup (9) {"Item": 5, "DisplayValue": "Cyberdyne Systems"} Cyberdyne Systems + ID 5 mfiles_prop_customer & mfiles_prop_customer_id
MultiSelectLookup (10) Array of Lookup items All non-deleted display values & IDs mfiles_prop_tags & mfiles_prop_tags_id
Text (1), MultiLineText (13), Time (6) String value Trimmed string value mfiles_prop_notes

6. Fail-Closed Zero-Trust Security & Restrictive Component Intersection

In an enterprise RAG system, security cannot be an afterthought. MFilesSecurityMapper evaluates object permissions from GET /objects/{type}/{id}/{version}/permissions (or VAF aclTokens / denyTokens) on a strict fail-closed basis:

7. Java 25 Virtual Threads, TempFileInputStream & Incremental Tombstones

High-throughput vault ingestion combines concurrent I/O with strict resource hygiene:

✅

Granular Deletion Tombstones: By querying MFWS with d=include and comparing current file attachments against MFilesCrawlState, OpenCrawling emits OIS action: "DELETE" tombstones both when an entire object is deleted in M-Files and when an individual file is removed from a Multi-File Document! Downstream vector stores automatically purge the stale chunks.

8. Sample OIS Document & Tombstone Payloads

Below is a real example of an ingested M-Files NDA document mapped to an OIS UPSERT payload, complete with normalized properties and Zero-Trust permissions:

{
  "id": "mfiles://C0B3B52E-6512-4BD8-8F2B-2A8E9A349201/objects/0/48192",
  "action": "UPSERT",
  "acl": "mfiles:user:12,mfiles:group:5",
  "metadata": {
    "name": ["Global Vendor NDA - Final Signed.pdf"],
    "title": ["Global Vendor NDA - Final Signed"],
    "mimeType": ["application/pdf"],
    "mfiles.vaultGuid": ["C0B3B52E-6512-4BD8-8F2B-2A8E9A349201"],
    "mfiles.vaultName": ["Contracts"],
    "mfiles.objType": ["0"],
    "mfiles.objId": ["48192"],
    "mfiles.version": ["3"],
    "mfiles.isLatestVersion": ["true"],
    "mfiles.title": ["Global Vendor NDA - Final Signed"],
    "mfiles.classId": ["14"],
    "mfiles.className": ["Non-Disclosure Agreement"],
    "mfiles.singleFile": ["true"],
    "mfiles.fileCount": ["1"],
    "mfiles.fileId": ["7"],
    "mfiles.fileName": ["Global Vendor NDA - Final Signed.pdf"],
    "mfiles.fileSize": ["1482910"],
    "mfiles.created": ["2026-04-10T10:30:00Z"],
    "mfiles.createdBy": ["sarah.connor"],
    "mfiles.lastModified": ["2026-09-27T15:20:00Z"],
    "mfiles.lastModifiedBy": ["alex.vance"],
    "mfiles.state": ["Approved"],
    "mfiles_identity_users": ["mfiles:user:12"],
    "mfiles_identity_groups": ["mfiles:group:5"],
    "mfiles_prop_customer": ["Cyberdyne Systems"],
    "mfiles_prop_customer_id": ["5"],
    "mfiles_prop_contractValue": ["150000"],
    "mfiles_prop_effectiveDate": ["2026-05-01"],
    "mfiles_prop_tags": ["Legal", "Vendor"]
  },
  "security": {
    "inheritanceEnabled": false,
    "permissions": [
      { "identity": "mfiles:user:12", "identityType": "user", "access": "read" },
      { "identity": "mfiles:group:5", "identityType": "group", "access": "read" },
      { "identity": "mfiles:user:9", "identityType": "user", "access": "deny" }
    ]
  }
}

And when an object or attached file is deleted in the vault, the connector dispatches a lightweight OIS DELETE tombstone:

{
  "id": "mfiles://C0B3B52E-6512-4BD8-8F2B-2A8E9A349201/objects/0/48192",
  "action": "DELETE",
  "metadata": {
    "mfiles.vaultGuid": ["C0B3B52E-6512-4BD8-8F2B-2A8E9A349201"],
    "mfiles.objType": ["0"],
    "mfiles.objId": ["48192"],
    "mfiles.status": ["DELETED"]
  }
}

9. Configuration, CLI Diagnostics & 9-Step Decoupled Verification

Configure the M-Files Repository Connector via Spring Boot properties (spring.opencrawling.connector.mfiles.*), Admin UI (oc-admin-ui), or connectors.json:

Spring Property (spring.opencrawling.connector.mfiles.*) connectors.json Key Default Description
url url http://localhost/REST MFWS base URL, including /REST
vault-guid vaultGuid — Required. Target vault GUID (with or without braces)
auth-type authType token Authentication mode: token, basic, or oauth2
username / password / domain username / password / domain — Credentials for token and basic auth
crawl-mode crawlMode search Mode: search, view, all_objects, or vaf
object-type / class-ids objectType / classIds 0 / empty Object type ID (0 = Document, -1 = all) and optional class ID filter
version-mode versionMode latest_only latest_only or all_versions
principal-format / qualify-principals principalFormat / qualifyPrincipals token / false token (mfiles:user:<id>) or name; optional <vaultGuid>/ prefix
incremental-enabled / emit-deletes incrementalEnabled / emitDeletes false / true Track watermarks in data/mfiles-state and emit DELETE tombstones
batch-size / parallelism batchSize / parallelism 500 / 4 MFWS search limit and concurrent Java 25 Virtual Thread workers

End-to-End Verification with the Stateful MFWS Mock & Secure MCP Server

We ship a comprehensive test suite including a stateful Python MFWS emulator (oc-mfiles-repository-connector/mfiles-mock/mfws_mock.py) that serves a deterministic generated vault with real PDF, DOCX, and TXT files, multi-component ACLs, and live mutation endpoints:

# 1. Verify vault connectivity via OpenCrawling CLI
$ oc connector check --name mfiles-vault --type repository

# 2. Run standalone unit + MockWebServer + stateful MFWS mock tests
$ ./scripts/test-mfiles-repository-connector.sh

# 3. Run the 9-step full decoupled Docker Compose pipeline (Kafka, pgvector, Ollama, Secure MCP Server)
$ ./scripts/test-mfiles-decoupled.sh

The 9-step decoupled test script (test-mfiles-decoupled.sh) boots the complete microservice topology, reconciles indexed chunks against the mock vault's ground truth (/mock/stats), verifies Zero-Trust ACL component intersection and explicit deny rules through the Secure MCP Server (secureVectorSearch, getDocumentContent, and listAccessibleSources over Streamable HTTP /mcp), triggers live vault mutations (removing an exhibit from a multi-file document, deleting a document, and adding a new NDA), and confirms that an incremental crawl updates pgvector and purges deleted chunks via tombstones.

Ready to Connect M-Files to Enterprise RAG?

Explore the M-Files Repository Connector documentation on the OpenCrawling Wiki, test drive the interactive simulator, or star the project on GitHub.