Skip to content

v0.5.0 — two profiles, and a link that actually opens

Latest

Choose a tag to compare

@mpasternak mpasternak released this 25 Jul 01:11

The mode this server runs in is now its identity, not its state. Whether you configure an account picks one of two profiles, and the profile shapes the server's name, the description the assistant reads at startup, the tool list, and the tool signatures.

This started as a report from use: the assistant kept losing track of which mode it was in, and got it wrong in both directions — talking about "the logged-in account" on an installation that had none, and handing over embargoed material without mentioning it was not public.

Breaking

  • continue_anonymously is gone, along with the whole decision state machine behind it. It existed so a failed login could be negotiated mid-conversation, which turned out to be a question nobody could answer usefully — including the person who had configured the server.
  • A failed login now stops the process (exit code 3) instead of blocking every tool and asking. Fix the credentials and restart, or remove them to run the public profile deliberately. The choice belongs to configuration, not to a conversation.
  • The MCP server reports a new name: dspace-mcp-public or dspace-mcp-account. Your client's own registration name is unaffected.

Two profiles

public account
tools 11 13
as_anonymous absent from every schema and description present where it means something
extra tools compare_access, get_download_link

The server now sends instructions at startup, so the assistant knows whose eyes it is looking through before it calls anything. Previously that was discoverable only by calling get_repository_info and noticing.

In the public profile the as_anonymous argument is not merely unused — it is untrue, because it implies an account to contrast with. It is now absent from the schemas entirely, so an anonymous installation neither sees it nor pays tokens for it.

A new dspace-mcp-public command guarantees the public profile: given credentials through a flag or the environment, it refuses to start rather than ignore them. Register the server twice to have both views side by side — the README shows the configuration.

Getting a restricted file to a person

The server could already read restricted files. What did not work was the link it handed over: the bare /content address is refused in a browser even when you are logged into the website.

get_download_link fixes that, and measures before it acts:

  1. ask anonymously for the plain address — if it answers, the file is public and you get a clean, permanent link, with no token minted at all;
  2. only on refusal, try again with an authentication token in the URL;
  3. if that fails too, hand back the item's page instead.

Since most files in a repository are public, step 1 usually ends it and no credential ever leaves the process. When one does, the tool says plainly what it is: the URL carries a credential for the whole account, not for one file, and it expires.

Two limits stated in the README rather than hidden: the check reflects what the server can reach from its own network position, so an instance granting access by IP range may still refuse your browser; and httpx logs full URLs at INFO level, so a debug-logging MCP client will write the token to its log.

Also

  • Files in listings now carry item_url, and an item without a handle finally gets a /items/<uuid> address instead of null.
  • A URL never reaches an error message with its query string attached — it could be carrying that token.
  • Fixed: the version-consistency test failed to collect on Python 3.10 (tomllib is 3.11+), which had left CI red on main for several commits.