DSpace MCP Server
The DSpace MCP Server lets AI assistants search, authenticate, and manage items, files, and submissions in a DSpace 7+ repository via the REST API.
Authenticate (JWT or username/password), check auth status, and logout.
Search items, communities, and collections with full-text queries, filters, facets, scoping, and pagination.
Retrieve item metadata by UUID and browse communities/collections.
Create archived items directly (admin, bypasses workflow), update metadata via JSON Patch, and permanently delete items.
Upload local files as bitstreams/attachments to items (admin), auto-creating bundles.
Retrieve extracted full text or download original bitstream content.
Manage submissions: create, update, and list workspace items through the standard workflow.
Run via stdio (local) or HTTP (AWS Lambda) with OAuth 2.1 per-user auth on HTTP and env-based auth on stdio.
Click on "Deploy 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., "@DSpace MCP Server search DSpace for articles about open access publishing"
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.
DSpace MCP Server
An MCP (Model Context Protocol) server for DSpace 7+ digital repository platform.
Provides AI assistants with tools to search, authenticate, create and update items in DSpace repositories via the REST API.
Features
Search — Full-text search with filters, facets, and pagination
Authentication — OAuth 2.1 per-user auth on the HTTP transport (each caller acts as their own DSpace user, credentials never reach the model), or JWT/username-password from the environment for local stdio; CSRF-aware
Item Management (Admin) — Create archived items directly (bypasses workflow) and delete items
Item Updates — Patch metadata using JSON Patch (RFC 6902)
File Uploads (Admin) — Attach files (bitstreams) to items, auto-creating the target bundle
Content Retrieval — Read a document's extracted full text (TEXT bundle) or download the original file
Submissions — Create workspace items through the standard submission flow
Browse — List communities and collections
Related MCP server: Alfresco MCP Chat
Dual Runtime
Runs as:
Local Node.js — stdio transport for Claude Desktop, Cursor, etc.
AWS Lambda — HTTP transport via Lambda Web Adapter + API Gateway
Quick Start
Local (stdio)
npm install
npm run build
# Configure in Claude Desktop / Cursor (stdio auth comes from env):
# {
# "mcpServers": {
# "dspace": {
# "command": "node",
# "args": ["dist/transports/stdio.js"],
# "env": {
# "DSPACE_BASE_URL": "https://sandbox.dspace.org/server",
# "DSPACE_USER": "you@example.org",
# "DSPACE_PASSWORD": "secret"
# // or, instead of user/password: "DSPACE_TOKEN": "<dspace-jwt>"
# }
# }
# }
# }Local HTTP (dev)
The HTTP transport always runs with OAuth 2.1 enabled (see Authentication).
DSPACE_BASE_URL=https://sandbox.dspace.org/server \
DSPACE_MCP_PUBLIC_URL=http://127.0.0.1:8080 \
npm run dev:http
# MCP endpoint: POST http://localhost:8080/mcp (requires a bearer token)AWS Lambda
npm run build
docker build -t dspace-mcp .
# Push to ECR, deploy with API Gateway HTTP API v2Environment Variables
Variable | Default | Description |
|
| DSpace REST API base URL |
|
| HTTP server port (Lambda/dev) |
| (none) | stdio auth: a pre-existing DSpace JWT to authenticate the session at startup. Takes precedence over user/password |
| (none) | stdio auth: DSpace username/email (used with |
| (none) | stdio auth: DSpace password (used with |
|
| HTTP transport: externally reachable base URL of this MCP server. Used as OAuth issuer, resource identifier, and to build the metadata/authorize/token URLs. Must be the public URL (behind Lambda/ALB), not |
|
| Also enable the non-browser |
|
| Opaque access-token lifetime, seconds (10 min) |
|
| Refresh-token lifetime, seconds (20 min) |
|
| Authorization-code lifetime, seconds (5 min) |
Token lifetimes. These form a hierarchy: access token (10 min) < refresh token (20 min) < DSpace JWT (DSpace default ~30 min). A refresh renews the underlying DSpace JWT via DSpace's native mechanism, which only works while that JWT is still valid — so the refresh token is kept shorter than the DSpace JWT. If your DSpace uses a different JWT lifetime, adjust these accordingly (keep both below the DSpace JWT).
The OAuth variables affect the HTTP transport only. The stdio transport ignores them and authenticates from
DSPACE_TOKEN(orDSPACE_USER/DSPACE_PASSWORD) at startup, as the MCP spec recommends for stdio.
Authentication
There are two authentication models, one per transport.
stdio (local)
The local process holds a single DSpace session, authenticated from the environment at startup (the model the MCP spec recommends for stdio: credentials come from the local environment, not over the network and not through tool calls). Set either:
DSPACE_TOKEN— a pre-existing DSpace JWT (takes precedence), orDSPACE_USER+DSPACE_PASSWORD— a DSpace username/email and password.
// Claude Desktop / Cursor
{
"mcpServers": {
"dspace": {
"command": "node",
"args": ["dist/transports/stdio.js"],
"env": {
"DSPACE_BASE_URL": "https://sandbox.dspace.org/server",
"DSPACE_USER": "dspacedemo+admin@gmail.com",
"DSPACE_PASSWORD": "dspace"
// or, instead of user/password:
// "DSPACE_TOKEN": "<dspace-jwt>"
}
}
}
}The session established at startup persists for the process lifetime and is
reused for every tool call. If no credentials are set, the server starts
unauthenticated and only public/anonymous DSpace operations work. There is no
login/logout tool: credentials never pass through the model, and for security
the JWT is never returned in any tool response (error messages are scrubbed of
anything resembling a token). Use dspace_auth_status to check the session.
HTTP — OAuth 2.1, per user (recommended for remote/shared deployments)
The HTTP transport always runs with OAuth 2.1: the server acts as both an OAuth 2.1 authorization server and a resource server, using DSpace itself as the identity backend — no external OIDC/IdP is required. Each caller authenticates with their own DSpace credentials, so every DSpace call runs as that user rather than as a shared service account.
Key property: the DSpace JWT stays server-side. The MCP server mints its own
opaque access/refresh tokens and hands only those to the client; the client
sends them as Authorization: Bearer … at the transport layer. The DSpace JWT
therefore never enters a tool argument, a tool result, or the model's context.
Standards implemented (per the MCP authorization spec):
RFC 9728 Protected Resource Metadata —
GET /.well-known/oauth-protected-resource/mcpRFC 8414 Authorization Server Metadata —
GET /.well-known/oauth-authorization-serverRFC 7591 Dynamic Client Registration —
POST /registerPOST /mcprequires a valid bearer; a missing/invalid token returns401with aWWW-Authenticateheader pointing at the resource metadata, which is what triggers the OAuth flow in MCP clients. Once authenticated, every DSpace call runs as that user, using their DSpace JWT.
Authorization Code + PKCE (interactive, default)
The MCP client discovers the metadata, registers, and opens
/authorize.The server serves a small login page; the user types their DSpace credentials in the browser. They go straight to DSpace and are never seen by the MCP client or the model.
On success the server logs in to DSpace, issues a single-use authorization code, and redirects back to the client.
The client exchanges the code (with its PKCE
code_verifier) at/tokenfor an opaque access token + refresh token.Refreshing rotates the tokens and also refreshes the backing DSpace JWT, so long sessions stay alive transparently.
Headless fallback (optional, non-browser clients)
Enable with DSPACE_MCP_HEADLESS_FALLBACK=true. The /token endpoint then also
accepts the OAuth 2.1 password grant (discouraged by the spec — use only when
a browser is unavailable). It has two modes:
Login —
username+passwordare DSpace credentials. The server logs in to DSpace and stores the freshly minted JWT. That token is created inside the server from the credentials and is never returned to the client or the model.curl -X POST http://127.0.0.1:8080/token \ -d grant_type=password \ -d client_id=headless \ -d username='dspacedemo+admin@gmail.com' \ -d password='dspace'JWT passthrough — set
username=jwt-tokenand put an existing DSpace JWT in thepasswordfield. The server verifies the token against DSpace (/api/authn/status) and, if valid, stores it as-is.curl -X POST http://127.0.0.1:8080/token \ -d grant_type=password \ -d client_id=headless \ -d username=jwt-token \ -d password='<existing-dspace-jwt>'
Both return a standard OAuth response with an opaque access_token (and
refresh_token); use the opaque token as the bearer on /mcp.
Security note. A JWT supplied via passthrough has, by definition, already been handled by the client (and possibly the model context). The server does not attempt to invalidate it: DSpace's refresh only rotates the token and leaves the previous one valid until its own expiry, so refreshing cannot revoke a leaked token. The only true revocation is a DSpace logout, which destroys the whole session (new token included) and is therefore not done here. A passed-in JWT stays valid until its natural expiry; supply it knowingly. The
password-login mode does not have this exposure, since the token is born server-side — prefer it, and prefer the Authorization Code flow over both whenever a browser is available.
Because this grant routes credentials/tokens through the MCP client, it is off by default.
Note for AWS Lambda
The token store is in-memory by default, which is per-process. That is fine
for a long-lived local/HTTP server, but the Lambda HTTP transport is stateless
(a fresh process per invocation), so opaque tokens minted in one invocation will
not be found in the next. For Lambda, provide a persistent TokenStore
implementation (e.g. DynamoDB or Redis) — the code is written against the
TokenStore interface in src/auth/token-store.ts specifically to make that
swap without touching the provider.
Tools
There is no
dspace_login/dspace_logouttool. Authentication is handled by the transport — OAuth on HTTP, environment credentials on stdio — never through the model. On the HTTP transport every/mcprequest requires a valid bearer. Usedspace_auth_statusto check the current session.
Tool | Description |
| Check current authentication status |
| Search items, communities, collections |
| Get item by UUID with full metadata |
| List top-level communities |
| List collections (optionally filtered by community) |
| Create an archived item (admin, bypasses workflow) |
| Patch item metadata (JSON Patch) |
| Permanently delete an item by UUID (admin) |
| Upload a local file as a bitstream (attachment) to an item (admin) |
| Get an item's file text — extracted text (TEXT bundle) or a textual original |
| Download a bitstream by UUID — save to a local file ( |
| Create a submission workspace item |
| Update workspace item metadata |
| List current user's workspace items |
License
Copyright © 2026 4Science Spa
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
See the LICENSE file for the full license text.
No impact on the connected DSpace instance
dspace-mcp is independent software that communicates with a DSpace instance only through its public REST API, over the network. It is not a derivative work of DSpace, does not link against DSpace code, and does not embed or redistribute any part of DSpace.
For this reason, using dspace-mcp has no licensing impact on the DSpace instance it connects to. The AGPL-3.0 covers dspace-mcp itself only, and running or integrating it does not require you to release the connected DSpace instance — or its customizations, configuration, or infrastructure — under the AGPL-3.0 or any other license. Interacting with DSpace through its REST API is ordinary client/server communication and does not combine the two into a single program.
Commercial licensing
4Science Spa, as the copyright owner, also offers dspace-mcp under separate commercial terms for organizations that cannot comply with the AGPL-3.0 (for example, those integrating it into closed-source or SaaS products without releasing their source). Contact 4Science for commercial licensing options.
Contributing
Contributions are welcome. Please read CONTRIBUTING.md.
All contributions are subject to a Contributor License Agreement, which allows 4Science to distribute the project under the AGPL-3.0 and under commercial licenses (dual licensing):
Individuals: CLA.md
Companies / organizations: CLA-ENTITY.md
Available Tools
14 toolsdspace_auth_statusB
Check the current authentication status with the DSpace instance.
Inputs: no named parameters.
dspace_create_itemA
Create an archived item directly in DSpace (admin only, bypasses submission workflow). The item is immediately visible in the repository.
Inputs: metadata (required), owningCollectionUuid (required), discoverable.
dspace_create_workspace_itemA
Create a new workspace item (submission) in DSpace. This starts the standard deposit workflow. After creation, use dspace_update_workspace_item to add metadata, then submit for review.
Inputs: metadata, owningCollectionUuid.
dspace_delete_itemA
Permanently delete an item from DSpace by UUID (admin only). This is irreversible: the item and its bundles/bitstreams are removed from the repository.
Inputs: uuid (required).
dspace_get_itemB
Get a DSpace item by UUID, including all metadata.
Inputs: uuid (required).
dspace_list_collectionsB
List collections, optionally filtered to a specific community.
Inputs: page, size, communityUuid.
dspace_list_communitiesB
List top-level communities in the DSpace repository.
Inputs: page, size.
dspace_list_workspace_itemsB
List workspace items (submissions in progress) for the current user.
Inputs: page, size.
dspace_loginA
Authenticate with a DSpace instance. Provide EITHER a JWT token directly, OR username + password for password-based login. The session persists for subsequent tool calls.
Inputs: email, token, password.
dspace_logoutA
Logout from the DSpace instance, invalidating the current JWT token.
Inputs: no named parameters.
dspace_searchC
Search DSpace for items, communities, or collections. Supports full-text queries, type filtering, scoping to a container, and advanced filters.
Inputs: page, size, sort, query, +3 more.
dspace_update_item_metadataB
Update metadata on an existing DSpace item using JSON Patch (RFC 6902). Supports add, remove, replace, and move operations on metadata fields.
Inputs: uuid (required), operations (required).
dspace_update_workspace_itemB
Update metadata on a workspace item (submission in progress) using JSON Patch.
Inputs: id (required), operations (required).
dspace_upload_bitstreamA
Upload a local file as a bitstream (attachment) to a DSpace item (admin only). The file is added to the item's bundle (default "ORIGINAL", where DSpace stores primary files); the bundle is created automatically if it does not exist.
Inputs: filePath (required), itemUuid (required), name, mimeType, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Each tool has a clearly distinct target and action: auth tools (status/login/logout), hierarchy (list_communities, list_collections), retrieval (search, get_item), and mutation tools. The only potentially confusable pair — create_item vs create_workspace_item and update_item_metadata vs update_workspace_item — is explicitly disambiguated by the archived-vs-workspace distinction in the descriptions.
All 14 tools use a uniform snake_case convention with a consistent dspace_ prefix, and verbs (list/get/create/update/delete/upload/login/logout/search) are used predictably across resource nouns. No camelCase or mixed styles appear anywhere.
14 tools is well within the ideal 3-15 range and each one maps to a distinct capability (auth lifecycle, hierarchy browsing, item CRUD, bitstream upload, workspace workflow). Nothing feels redundant or padded.
Item CRUD plus bitstream upload and a read side (communities/collections/search) are covered, but the workspace workflow is a dead end: create_workspace_item's own description says to 'submit for review' yet no submit tool exists, and delete_workspace_item, bitstream download, and community/collection management are absent. These gaps will force agents to abandon the documented deposit flow.
Maintenance
Related MCP Connectors
Connect AI clients to biomedical data and tools.
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceConnects AI assistants to Obsidian vaults via the Local REST API to search notes, retrieve content, and perform semantic searches. It features self-healing multi-URL connectivity and supports both stdio and HTTP transports for flexible deployment.283 npm13MIT
- FlicenseNot gradedqualityDmaintenanceTurns hundreds of Alfresco MCP REST endpoints into a small set of tools for a local LLM, enabling natural language interaction with Alfresco while keeping everything local and secure.1-
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that enables natural language querying of DSpace 7+ repositories via the REST API, allowing users to search, retrieve items, and analyze repository data.2MIT

Compoid MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to search, download, create, and manage records and communities on Compoid repositories using natural language.42 PyPIMIT