Skip to main content

ojs-mcp

tests PyPI License: MIT

An MCP server for the authenticated REST API of Open Journal Systems (OJS 3.5/3.6). Connected to an MCP client (Claude Desktop, Claude Code, and others), it gives the model access to a journal's submissions, reviews, issues, and editorial statistics — and, with writes explicitly enabled, also to making editorial decisions, publishing, and editing metadata.

Verified against a live OJS 3.5

Every tool has been exercised end-to-end against a real OJS 3.5.0-5 instance — the sixteen read tools, the ojs_request escape hatch, and all five write tools. The write tools were checked by reading back the state OJS actually ended up in, not by trusting the status code: an announcement created, publication metadata edited, a submission carried from the submission stage to production by two editorial decisions, then published and unpublished again.

That instance is reproducible. demo/ holds the Docker stack, the fictional seed content, and the two scripts that drive this server against it as a real MCP client — check_api.py for the read tools, check_writes.py for the write tools.

Three things have not been exercised against a live server, and still rest on what the PKP source (pkp-lib, pkp/ojs) says rather than on observed behavior: login/password authentication (OJS_USERNAME/OJS_PASSWORD), network mode (OJS_MCP_TRANSPORT=http), and OJS 3.6 — only 3.5 has been tested. The unit test suite likewise runs entirely against stubbed HTTP responses (via respx).

Writes change real journal data, which is why OJS_ALLOW_WRITES=1 is off by default. Verify each tool's effect on a test journal before pointing it at production.

Quick start

OJS_BASE_URL=https://journals.your-university.edu OJS_API_TOKEN=your-token uvx ojs-mcp

No separate install step needed — uv downloads and runs the package on first launch. In practice your MCP client calls this command for you, using the configuration format from the section below.

Before you start — this won't work without two things

The OJS REST API has no anonymous read access. For the server to be able to connect at all, both of these must be true on the OJS instance side:

  1. api_key_secret set in config.inc.php — without it, API tokens don't work at all (OJS responds with a 500 error to every request that carries a token). This must be done by the OJS server administrator; it can't be worked around from the outside.
  2. An account with a role in the specific journal — merely having an OJS account is not enough. Almost every API endpoint requires some role (manager, editor, reviewer...); an account with no role in the given journal gets denied (401) on almost every call.

A third condition applies to instances served by Apache — including the official pkpofficial/ojs Docker images: the web server must forward the Authorization header to PHP. Apache does not do that on its own, and when it doesn't, OJS answers 401 to every request carrying a token, with a response indistinguishable from an anonymous one. The one-line fix, and how to tell this case apart from a genuine permission problem, are in the authentication documentation.

Without these conditions the server will start, but every tool that reaches into OJS will return an authentication error. Details, including the login/password alternative and its limitations, are in docs/authentication.md.

Getting a token

A logged-in user generates an API token in their own OJS profile: User Profile → API Key (only available once the instance administrator has set api_key_secret — see above). The token acts with that account's permissions, so its scope is whatever roles that account holds in the given journal.

Example MCP client configuration

{
  "mcpServers": {
    "ojs": {
      "command": "uvx",
      "args": ["ojs-mcp"],
      "env": {
        "OJS_BASE_URL": "https://journals.your-university.edu",
        "OJS_JOURNAL": "my-journal",
        "OJS_API_TOKEN": "paste-your-ojs-profile-token-here"
      }
    }
  }
}

OJS_JOURNAL is optional — leave it out if the instance serves several journals and you'd rather pick one with the journal parameter on each call.

Where to actually paste this configuration

In Claude Desktop: Settings → Developer → Edit Config opens (and, on first use, creates) the claude_desktop_config.json file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Paste the snippet above under the mcpServers key — if the file already has other servers configured, add the "ojs" key alongside them, don't overwrite the whole file — save and restart Claude Desktop. Other desktop MCP clients have their own place for this configuration (e.g. Claude Code reads it via claude mcp add or from an .mcp.json file) — check their documentation; the shape of the env section above is the same across all of them.

This step disappears entirely when installing from the MCPB bundle (see below) — there, the instance address, journal, and token are filled in through a form in the client's UI, with no manual JSON editing at all. That's a good reason to reach for the bundle instead of uvx if editing a configuration file by hand isn't your thing.

Environment variables (summary)

Variable Required Description
OJS_BASE_URL yes The OJS instance address, exactly as it works in the browser.
OJS_JOURNAL no The journal shortcut — skips the journal parameter on every call.
OJS_API_TOKEN no* The token from a user's profile. Takes precedence over login/password.
OJS_USERNAME / OJS_PASSWORD no* Form-based login — won't work with reCAPTCHA/ALTCHA.
OJS_ALLOW_WRITES no 1 exposes the tools that modify journal data (hidden by default).

* — either OJS_API_TOKEN or the OJS_USERNAME/OJS_PASSWORD pair is required (in stdio mode). The full list, including the network-mode variables (OJS_MCP_TRANSPORT and others), is in docs/configuration.md.

Alternative to uvx: the MCPB bundle

For desktop MCP clients that support the MCP Bundle (.mcpb) format — the installer file is attached to every release under Releases. Installation happens through the client's UI, configuration through a form instead of manual JSON editing; no Python or uv installation required — the bundle pulls its own dependencies on first run.

Documentation

Full documentation (installation, configuration, authentication, tool list, multi-tenant hosting): https://mpasternak.github.io/ojs-mcp/

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ojs_mcp-0.2.1.tar.gz (107.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ojs_mcp-0.2.1-py3-none-any.whl (76.0 kB view details)

Uploaded Python 3

File details

Details for the file ojs_mcp-0.2.1.tar.gz.

File metadata

  • Download URL: ojs_mcp-0.2.1.tar.gz
  • Upload date:
  • Size: 107.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ojs_mcp-0.2.1.tar.gz
Algorithm Hash digest
SHA256 1d5a702055d7e0452f452c1a53998a0cba0d745903219b227f01f981737c551b
MD5 0c66fb6fd4a6c64295ec635de5df7d3e
BLAKE2b-256 84e2f63dc0963f2200f73a156fefd257c618e158255400205ad1a1e939a61614

See more details on using hashes here.

Provenance

The following attestation bundles were made for ojs_mcp-0.2.1.tar.gz:

Publisher: release.yml on mpasternak/ojs-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ojs_mcp-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: ojs_mcp-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 76.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ojs_mcp-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2d7a33a2861f1750cd998f1aa94b12254e6ea1a36a69e254d06cd6605ccddd92
MD5 a22da994f5f58dbfb3aac858bbf177f9
BLAKE2b-256 e764309f8b06a690b51828be60d72eaf6862997fa08ccbca57b6999808755f0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ojs_mcp-0.2.1-py3-none-any.whl:

Publisher: release.yml on mpasternak/ojs-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page