opendesk-mcp
Provides read-only access to files and folders in an openDesk Files (Nextcloud) instance, with tools for searching, listing, and reading files.
Provides read-only access to projects and work packages in an openDesk Projects (OpenProject) instance, with tools for listing projects, searching and retrieving work packages, and reading comments.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@opendesk-mcpShow me my recent files and open work packages"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
opendesk-mcp
A Model Context Protocol server for openDesk, the sovereign workplace suite that ZenDiS builds for German public administration on behalf of the Federal Ministry of the Interior.
It gives an MCP-capable assistant read-only access to the files, projects, knowledge pages, calendar, contacts, mail and chat of one openDesk instance.
Why this exists
openDesk publishes no MCP server, and there is no unified openDesk API to write one against. openDesk is a curated bundle of separate open-source products behind a shared Keycloak, and the architecture documentation lists one API per component rather than one for the suite.
That leaves every openDesk deployment, roughly 100,000 administrative workstations at the time of writing, without a way to point an assistant at its own content. This server closes that gap by talking to each bundled product directly.
Module | Product | Protocol | Default host |
Files | Nextcloud | WebDAV |
|
Projects | OpenProject | API v3, HAL+JSON |
|
Knowledge | XWiki | REST, |
|
Calendar | Open-Xchange | CalDAV |
|
Contacts | Open-Xchange | CardDAV |
|
Dovecot | IMAP | none, see below | |
Chat | Synapse / Matrix | client-server API |
|
The default hosts are openDesk's own deployment defaults, from
helmfile/environments/default/global.yaml.gotmpl, where every service gets its
own subdomain. Each one is overridable.
Calendar, contacts and mail are Open-Xchange, not Nextcloud. Nextcloud in openDesk serves files. Pointing a calendar tool at the Nextcloud host would read a different calendar, usually an empty one, and look like a data problem rather than a configuration one.
Related MCP server: AuroraDocs MCP Server
Scope and safety
Every tool in this server is read-only. There is no code path that creates, updates or deletes anything in openDesk, that sends a message or an email, and none that writes to disk or contacts a host other than the configured modules.
Each module authenticates as one account and therefore sees exactly what that account sees. openDesk's own permissions remain the access boundary; this server does not widen them.
Modules are independent. If your XWiki allows single sign-on only and rejects the password, the Knowledge tools are simply not registered and everything else keeps working. The server prints which modules it started with on stderr.
Responses are size-capped before they reach the assistant. A response body is
read up to a limit and then aborted, long text is truncated with an explicit
[truncated] marker, and a file above the read limit returns metadata with a
note instead of its contents.
Known limitations of openDesk itself
Two of these modules depend on things that are not this server's to fix. Read this before filing a bug.
Calendar and contacts may fail on your deployment. openDesk issue
#155, "openxchange CalDav & CardDav do not work",
has been open since February 2025, is assigned upstream to Open-Xchange and sits
in the backlog. It reports a broken ingress rewrite plus an unresolved "No
session created" authentication failure on /servlet/dav. On an affected
deployment these two modules cannot authenticate no matter which credentials you
supply. The error message from this server says so rather than leaving you to
suspect your password.
Check before configuring them:
curl -u 'username:password' 'https://dav.example.org/servlet/dav/'Mail needs IMAP to be exposed at all. IMAP is not HTTP, so it cannot travel
through the cluster's HTTP ingress that serves every other module. Whether
Dovecot is reachable from outside is a decision your operator makes, which is
why OPENDESK_MAIL_HOST has no default and must be set by hand.
Requirements
Node.js 20 or newer
An openDesk instance reachable from the machine running the server
Credentials for at least one module
Obtaining the credentials
Files, a Nextcloud app password
Open the Files app in openDesk.
Go to Settings, then Security.
Under "Devices & sessions", enter a name and choose "Create new app password".
Copy the generated password. It is shown once.
Projects, an OpenProject API key
Open the Projects app in openDesk.
Open your avatar menu and choose "My account".
Go to "Access tokens".
Under "API", choose "Generate" and copy the key.
Knowledge, calendar, contacts and mail: the account password
XWiki, the Open-Xchange DAV endpoints and IMAP have no app-password concept of
their own, so these modules use the account's credentials. Whether that works
depends on how your deployment configured single sign-on. Test each one with
curl (see above) before wiring it up.
Chat, a Matrix access token
Open the Chat app (Element) in openDesk.
Go to Settings, then Help & About.
Expand "Advanced" and copy the access token.
A Matrix access token is as powerful as the account. Treat it like a password.
Installation
git clone https://github.com/Nraitschew/opendesk-mcp.git
cd opendesk-mcp
npm install
npm run buildThe build writes an executable entry point to dist/index.js.
Configuration
The server is configured through environment variables. Only OPENDESK_DOMAIN
and the credentials of the modules you want are required.
Domain
Variable | Required | Meaning |
| yes | The domain of your openDesk instance, for example |
Every module URL is derived from it, and every one can be overridden.
Files, Nextcloud
Variable | Required | Default |
| for this module | |
| for this module | |
| no |
|
Projects, OpenProject
Variable | Required | Default |
| for this module | |
| no |
|
Knowledge, XWiki
Variable | Required | Default |
| for this module | |
| for this module | |
| no |
|
| no |
|
Calendar and contacts, Open-Xchange
One credential enables both, because in openDesk they are the same product on the same host.
Variable | Required | Default |
| for these modules | |
| for these modules | |
| no |
|
Mail, IMAP
Variable | Required | Default |
| for this module | none, deliberately |
| for this module | |
| for this module | |
| no |
|
| no |
|
Chat, Matrix
Variable | Required | Default |
| for this module | |
| no |
|
Limits
Variable | Default | Meaning |
|
| Per-request timeout in milliseconds. |
|
| Hard cap on a single response body. |
|
| Cap on text handed to the assistant. |
|
| Cap on bytes downloaded for one file read. |
Half a credential is an error rather than a silently disabled module: setting
OPENDESK_FILES_USERNAME without OPENDESK_FILES_APP_PASSWORD makes the server
exit with a message naming the missing variable.
Connecting a client
Claude Desktop
Edit the MCP configuration file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"opendesk": {
"command": "node",
"args": ["/absolute/path/to/opendesk-mcp/dist/index.js"],
"env": {
"OPENDESK_DOMAIN": "example.org",
"OPENDESK_FILES_USERNAME": "first.last",
"OPENDESK_FILES_APP_PASSWORD": "your-app-password",
"OPENDESK_PROJECTS_API_KEY": "your-api-key",
"OPENDESK_WIKI_USERNAME": "first.last",
"OPENDESK_WIKI_PASSWORD": "your-password",
"OPENDESK_DAV_USERNAME": "first.last",
"OPENDESK_DAV_PASSWORD": "your-password",
"OPENDESK_MAIL_HOST": "mail.example.org",
"OPENDESK_MAIL_USERNAME": "first.last",
"OPENDESK_MAIL_PASSWORD": "your-password",
"OPENDESK_CHAT_TOKEN": "your-matrix-token"
}
}
}
}Restart Claude Desktop afterwards. Leave out the variables of any module you do not want.
Claude Code
claude mcp add opendesk \
--env OPENDESK_DOMAIN=example.org \
--env OPENDESK_PROJECTS_API_KEY=your-api-key \
-- node /absolute/path/to/opendesk-mcp/dist/index.jsAny other MCP client
The server speaks MCP over stdio. Start it with node dist/index.js and the
environment set; any client that can spawn a stdio server will work.
Tools
Only the tools of the configured modules are registered.
Files
Tool | Purpose |
| Search the drive by file and folder name. Matches names, not contents. |
| List the immediate contents of one folder. |
| Read one file. Text is returned inline; other types return metadata with a note. |
Projects
Tool | Purpose |
| Identify the OpenProject account, for questions that say "my" or "me". |
| List visible projects, optionally filtered by name. |
| Full-text search over work packages, optionally scoped to a project or the current user. |
| One work package in full, including its description. |
| The comments on a work package. |
Knowledge
Tool | Purpose |
| Full-text search across page names, titles and content. |
| One page's content, with its version and syntax. |
| The spaces of the wiki. |
| The pages directly inside one space. |
Calendar
Tool | Purpose |
| The calendars this account can see. |
| Appointments across all calendars in a date range, default the next 30 days. |
Contacts
Tool | Purpose |
| Search address books by name, email, phone, job title or organisation. |
Tool | Purpose |
| The folders of the mailbox, with the paths to search in. |
| Search one mailbox by sender, subject, body text, date or unread state. |
| One message in full, with its body text and attachment list. |
Chat
Tool | Purpose |
| Identify the Matrix account, to tell own messages from others'. |
| The rooms this account has joined. |
| The most recent messages of one room. |
| Full-text search across the rooms this account can see. |
Tool results are JSON. OpenProject's HAL envelopes are flattened, so a work
package carries status, assignee and project as plain names.
Notes on the data
Recurring appointments are not expanded. A CalDAV time-range query returns
the recurring master object, and this server reports the appointment as it is
stored, with a recurring flag, rather than computing occurrences. Expanding
recurrence correctly is a calendar engine's worth of edge cases.
Times without a zone stay without one. An iCalendar value qualified with a
TZID is returned as a local wall-clock time rather than being converted, since
resolving the zone needs the VTIMEZONE component. Treating such a value as UTC
would shift half the appointments in the country by an hour.
Mail UIDs are per mailbox. A uid from mail_search is only valid in the
mailbox it came from, and it changes when a message moves. Pass the mailbox
along with the uid to mail_read.
Wiki page references
XWiki addresses a page as Space.PageName, and a nested space as
A.B.PageName. Two details are easy to get wrong, and this server handles both:
A literal dot inside a name is escaped as
\.. Splitting on every dot would break exactly the pages whose names contain one, such as release notes or dates.A reference may be fully qualified as
wiki:Space.Page. The wiki part is a separate REST path segment, not a dot-separated one.
A bare page name with no space is rejected rather than guessed at. Always pass a
reference that wiki_search or wiki_list_pages returned.
Errors
A failing tool call returns a result marked as an error whose text starts with a stable machine code and names the module, so a rejected OpenProject key does not read as a broken Nextcloud:
Code | Meaning |
| The module's credentials were rejected, or the instance requires single sign-on. |
| Authenticated, but not permitted to read that resource. |
| No such file, work package, page or message. |
| The module is rate limiting this client. |
| The module did not answer, or the request timed out. |
| A wiki page reference names no space. |
| The response was not the expected document. Usually a wrong module URL. |
| The response exceeded the configured byte limit. |
| Any other non-success status, with the status code in the message. |
Testing against your instance
npx @modelcontextprotocol/inspector node dist/index.jsThe MCP Inspector lists the tools and lets you call them by hand, which is the fastest way to confirm the domain and credentials are right. The server also prints the configured modules to stderr on startup.
Development
npm install
npm run typecheck
npm test
npm run buildThe unit tests cover configuration and URL derivation, the WebDAV multistatus parser and search-body escaping, the OpenProject filter grammar, the XWiki reference grammar, the iCalendar and vCard parsers, and the IMAP search criteria. They make no network requests, so they run anywhere.
Limitations
Read-only by design.
Video conferencing (Jitsi, NeoDateFix), collaborative documents (Collabora), CryptPad, Notes and the Nubus portal are not covered.
File contents are read for text files only. Office documents and PDFs return metadata.
Attachments are listed but never downloaded, in files, wiki pages and mail alike.
Searches page once with the requested limit rather than paging through a large result set.
Every tool call opens its own IMAP connection. That costs a connection setup per call, and buys not having to keep a session alive between questions.
Related
If you run only one of the bundled products rather than a whole openDesk instance, the standalone servers are a better fit:
For Nextcloud on its own, the community already has several servers, including cbcoutinho/nextcloud-mcp-server.
Contributing
Issues and pull requests are welcome, particularly:
Reports from real openDesk deployments about which modules accept password authentication, and whether CalDAV and CardDAV work on yours.
Corrections to the API assumptions documented in the source comments.
License
Apache License 2.0. See LICENSE.
This project is independent. It is not affiliated with or endorsed by ZenDiS GmbH, the German Federal Ministry of the Interior, Nextcloud GmbH, OpenProject GmbH, Open-Xchange, XWiki SAS or Element. "openDesk", "Nextcloud", "OpenProject", "Open-Xchange", "XWiki", "Element" and "Matrix" are trademarks of their respective owners and are used here only to describe what this software connects to.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Knowledge base MCP for AI agents on iknow.dev. Search, read, and maintain via OAuth.
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Make your knowledge agent-ready. One MCP endpoint, 5 connectors, 3 search modes.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables interaction with self-hosted OpenProject instances through the MCP protocol, supporting CRUD operations for projects and tasks (work packages) with pagination and filtering capabilities.8
- AlicenseNot gradedqualityAmaintenanceEnables local MCP clients to interact with an AuroraCloud workspace, supporting object listing, content reading, search, and task management through authenticated API calls.27Apache 2.0
- AlicenseAqualityCmaintenanceMCP server for OpenProject that enables AI agents to search and view work packages, add comments, upload attachments, log time, list projects, and search users via the REST API v3.10MIT

HireFrog MCPofficial
AlicenseNot gradedqualityBmaintenanceEnables MCP-compatible AI assistants to securely access a user's job-search account, letting them search and save jobs, analyze job fit, and retrieve job queue and profile summaries with links back to the web app.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nraitschew/opendesk-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server