ebongard

renfield-mcp-filesystem

Community ebongard
Updated

Watch-folder MCP server for Renfield: event-driven detection of new files on local/SMB shares, pushed in over REST.

renfield-mcp-filesystem

Watch-folder MCP server for Renfield: itwatches folders (local / SMB) for settled new files and pushes them intoRenfield over REST (POST /api/folder-ingest/document), which ingests them intothe knowledge base and Paperless.

This dedicated server is the sole access boundary to the shares — theRenfield backend never mounts them, and credentials/clients live only here. A newoff-cluster share or a per-user folder is added at runtime by editing theroots config — no redeploy, no static volume.

Principles

  • Event-driven, never polling. Local roots use watchdog (inotifyCLOSE_WRITE = the settle signal); SMB roots use SMB2 CHANGE_NOTIFY + anevent-debounce timer. No periodic filesystem scan. (One exception: a singleenumeration at startup catches files that already existed before the watchbegan — a one-shot catch-up, not a poll.)
  • Create-only. Acts on settled new files; ignores in-place rewrites of filesit has already handled.
  • The backend's 4-state response drives the move. ingested|duplicateprocessed/, failedfailed/, retry → left in place and re-attempted ona bounded backoff. 401/403 is a fatal token error (the file is never moved).
  • Local safety gates. Size ceiling + extension allowlist are enforcedbefore any push (an oversized / disallowed file goes straight to failed/).

Quickstart (local folder)

Point it at a local inbox and an existing Renfield backend:

mkdir -p ./inbox
cat > roots.yaml <<'YAML'
roots:
  - name: inbox
    type: local
    path: /watch/inbox
YAML

docker run --rm \
  -e RENFIELD_URL=http://renfield-backend:8000 \
  -e RENFIELD_INGEST_TOKEN=<token-from-POST-/api/folder-ingest/token> \
  -e FILES_ROOTS_YAML=/config/roots.yaml \
  -v "$PWD/roots.yaml:/config/roots.yaml:ro" \
  -v "$PWD/inbox:/watch/inbox" \
  -p 8080:8080 \
  registry.treehouse.x-idra.de/renfield/filesystem-mcp:latest

Drop a PDF into ./inbox → it appears in Renfield's /wissen and Paperless, thenmoves to ./inbox/processed/. A rejected file moves to ./inbox/failed/.

Mint the token on the backend (admin): POST /api/folder-ingest/token. Thebackend feature must be on (FOLDER_INGEST_ENABLED=true).

Configuration

Global settings come from the environment; the watch roots come from amounted roots.yaml (see config/roots.example.yaml).

Env var Default Meaning
RENFIELD_URL — (required) Renfield backend base URL
RENFIELD_INGEST_TOKEN — (required) folder-ingest Bearer token
FILES_ROOTS_YAML path to the mounted roots.yaml (reloaded on change)
FILES_ALLOWED_EXTENSIONS pdf,docx,... local extension allowlist
FILES_MAX_FILE_SIZE_MB 50 size ceiling (enforced before push)
FILES_SETTLE_SECONDS 2.0 SMB settle-debounce window
FILES_MCP_HOST / FILES_MCP_PORT 0.0.0.0 / 8080 MCP server bind
FILES_NOTIFY_WEBHOOK_URL / _TOKEN optional failure/disconnect webhook

roots.yaml (creds referenced by env-var name, never inlined):

roots:
  - name: documents
    type: smb
    server: nas.example.lan
    share: Documents
    path: Inbox
    username_env: DOCS_SMB_USER
    password_env: DOCS_SMB_PASS
  - name: local-inbox
    type: local
    path: /watch/inbox

Each root takes an optional processed_subdir / failed_subdir (defaultsprocessed / failed). After a file is handled it is moved out of the inbox:ingested/duplicate → processed, rejected → failed, retry → left in place.

Where the processed/failed dirs live differs by provider:

  • SMB — at the share root, as siblings of the watched path. A rootwith path: Inbox produces <share>/{Inbox, processed, failed} (not<share>/Inbox/processed). With path: "" (watch the share root) they aresimply the two top-level dirs. The watched inbox + both dirs are auto-createdon connect.
  • localnested inside the watched path (<path>/processed,<path>/failed), since a local root is self-contained.

Dry-run (preflight)

Validate config + credentials + the matched/skipped files before the daemontouches anything (pushes nothing, moves nothing):

renfield-mcp-filesystem-scan --dry-run
# root documents (smb):
#   would push (2): invoice.pdf (12345 bytes), letter.pdf (6789 bytes)
#   skipped (1): notes.exe (extension_not_allowed)

Interactive MCP tools

Registered as mcp.files.* (the files stanza in Renfield'sconfig/mcp_servers.yaml). The agent uses these to browse + ingest on demand(the watch loop is automatic + event-driven):

  • list_watch_folders() → roots + connected + last_error
  • list_files(root, pattern?) → files, each with a qualified path "<root>/<relpath>"
  • get_file_info(path) · read_file(path, truncate?) · move_file(path, subdir)

The Renfield agent tool internal.ingest_file({path}) pulls bytes viaread_file(path, truncate=False) and runs them through the same ingest bridge.

Deploy (k8s)

Manifests in k8s/ (ConfigMap roots + Secret creds + a single-replicaDeployment + Service). Single replica by design — two would double-push. Buildon the build box → Harbor → kubectl apply -f k8s/.

Develop

python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/python -m pytest

Core modules (config/contract/providers/pusher/engine/gate/daemon/tools/scan)are mcp-free and fully unit-tested; the live inotify/SMB CHANGE_NOTIFY wiring andthe cross-repo push are verified by the Renfield .159 E2E. NFS is deferred — ithas no native change-notification, so it cannot be event-driven without polling.

MCP Server · Populars

MCP Server · New

    DeusData

    codebase-memory-mcp

    High-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 159 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.

    Community DeusData
    joaoh82

    rustunnel

    Self-hosted, secure tunnel server in Rust. Expose local HTTP/HTTPS/TCP/UDP services to the public internet via TLS-encrypted WebSocket. Open-source, pay-as-you-go managed option, MCP server for AI agents.

    Community joaoh82
    GethosTheWalrus

    Temporal MCP Server

    MCP Server

    Community GethosTheWalrus
    SikamikanikoBG

    🛰️ HomeLab Monitor

    Plug-and-play homelab dashboard in one container — GPU, local-AI VRAM, Docker, systemd, host health. Built-in read-only MCP server so AI agents can explore it too.

    Community SikamikanikoBG
    w1ckedxt

    Cynical Sally

    Brutally honest senior-engineer code reviews for Claude Code, Cursor & Windsurf - and your terminal. Scores, evidence-backed issues, usable fixes.

    Community w1ckedxt