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.0.tar.gz (105.8 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.0-py3-none-any.whl (75.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ojs_mcp-0.2.0.tar.gz
  • Upload date:
  • Size: 105.8 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.0.tar.gz
Algorithm Hash digest
SHA256 21291dadf06090b3506f2f3f4a4a5c150494ecd10b18d1913980093469f7e196
MD5 127bb386d41bfe7c1d89b8a721aedff3
BLAKE2b-256 700aa23ba51c1cc1bc3dc09294ed85b1604cbdc3224d71ae778c814b4ca742f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for ojs_mcp-0.2.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: ojs_mcp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 75.8 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60e842ccea9ee62c5ea90bd96e0f91d8d34e8d0b1feb9f360048edb82e2790b8
MD5 7f98e2b124aeecce62d20805d3e907b9
BLAKE2b-256 8d5b33ba34b746b37720a3ec74c1f3758447046c9d0dddd0cf076ea3da66d71c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ojs_mcp-0.2.0-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

0.2.1

2 files

This release

0.2.0 This release

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