Integration_openproject: are the OCS routes a public API for other apps?

I maintain mcp_connector, an MCP-only ExApp that has been in the App Store since 0.1.0. It lets an assistant read Nextcloud data strictly on behalf of the signed-in user, over OAuth 2.1 as described in the MCP authorization spec.

I would like to extend that to OpenProject data, and integration_openproject already solves the hard part. Its appinfo/routes.php exposes 15 OCS routes under openProjectAPI#, and OpenProjectAPIController is an OCSController marked NoAdminRequired, so the call runs with the signed-in user’s own OpenProject connection.

Going through that app rather than opening a second OAuth client of my own would mean no additional secret inside my container, no second consent screen for the user, and no new outbound host from my side. That is clearly the better design, if it is allowed.

Hence my question: are those OCS routes intended as a public interface that other apps may call, or are they internal plumbing for the app’s own front end that may change without notice? I would rather ask now than build on them and have to walk it back later.

I would normally ask in the repository, but nextcloud/integration_openproject has issues disabled and points to community.openproject.org, which does not allow self-registration at the moment. So I am asking here, in the hope that someone from the team or someone who has built on these routes before can say.

One follow-up, if they are public: I can see search over work packages, file links, projects, notifications, statuses, types and configuration. I cannot see a route to read a single work package by id, one for comments, or one for work assigned to me. Is that deliberate, and would a read-only addition in that direction be welcome as a contribution?

I asked on the community chat room but got no answer so far.
I would (if I were in your shoes), I would apply or an account on the community…

Chris

Thanks, that is useful in itself: if the question did not get an answer in the community chat either, then it is not just me failing to find the documented answer. I will follow your advice and ask for an account in the OpenProject community.

Meanwhile I stopped guessing and measured, so I can narrow the question down. On a pinned local setup (Nextcloud 33.0.7, integration_openproject 3.1.1, OpenProject 17.7.2) the OCS surface does answer for an ExApp that acts as the signed-in user through AppAPI impersonation, with no cookie and no app password in the request: GET /api/v1/url returns the OCS envelope with the instance URL, and GET /api/v1/configuration returns 200 with real data for a connected account and 401 with an empty message for an account that never connected OpenProject, which is validatePreRequestConditions() doing exactly what it should. Permissions are the user’s own, not the app’s: searching for a work package that lives in a private project returns one hit for the member and zero hits for the other account, same call, same headers. In the oauth2 setup the server also refreshes the expired user token by itself, so the call keeps working without a browser session; in the oidc setup the same call drops to 401 once the cached token expires, because the token exchange in user_oidc reads the login token from the session and an impersonated request does not have one. Counted from appinfo/routes.php at tag v3.1.1 there are 17 OCS routes, and the three gaps I mentioned in my first post are still there at that tag: no route to read one work package by id, none for comments, and none for “work assigned to me”. The one route that takes a work package id at all is GET /api/v1/work-packages/{id}/file-links, which is the Nextcloud-facing part I care about most.

So the technical part works, and the only thing I still cannot answer is the one I opened with: are these OCS routes meant as an interface that other apps may call, or are they internal plumbing for your own front end that may change without notice? I am not asking for new routes here and not asking for a promise about the three gaps. I am asking whether building on the existing 17 would be building on something that is expected to stay, so that I know whether to design around it or not.

If anyone reading this knows where such a statement would live for a Nextcloud integration app in general, that would help too. I could not find a written rule for OCS routes of an app that is not the server itself.

The endpoints comply with the OpenAPI specification and are designed to serve as stable anchor points. That is, after all, the stated goal of Open Collaboration Services.
Should changes occur, the endpoints—then considered “legacy”—would continue to operate in parallel for an extended period; subsequently, and with sufficient advance notice, they would be marked as “deprecated” before finally being removed. Crucially, however, this would only happen after they had been fully replaced by new endpoints.
After all, it is specifically intended to serve as an endpoint for communication between applications and the server, and is not meant to be…

But that is the paradigm of REST APIs. Of course, I cannot guarantee the extent to which every app maintainer adheres to this. I have seen so many apps come and go. However, apps equipped with OCS endpoints generally tend to be of higher quality.

h.t.h.


ernolf

Hmm, I would not agree on this, to be honest (sorry, ernolf). This was a long-standing issue on the documentation that OCS and REST-based endpoints were treated in a kind of strange way resulting in the end to the advice not to use any of these methods for data exchange if you looked closely. :wink:
I thus took the time to discuss with some server devs and updated the docs and added a section related to OCS vs REST.

Yeah, OCS is intended to be version-stable. But REST is so as well, as you can see that many REST providers have a /v1/ in the path for example.

I would say that this is a question of app policy, as @street1983nk said: if the maintainers are well aware that 3rd party apps might depend on the API, they will avoid changing without a clear migration path. With the cookbook I do it exactly the same: keep any API endpoint until the corresponding server version is EOL. If version cookbook x.y.z was compatible with NC33, I would only remove an API from version x.y.z once NC33 is EOL. But this is my policy.

However, the API is typically rather stable. Bugs are in 99% of the cases in the implementation and not in the API. Yeah, there are cases where an extension of the API might be considered. But this will not happen too often.

I would get in touch with the maintainers and make them at least aware that there are 3rd party apps willing to use their API. They could react

  • Provide with a stable, dedicated API
  • Give you clear guarantees about stability of existing API
  • Set up a communication channel (or invite you into it) to communicate upcoming changes
  • Explain their API lifecycle management

Chris

Thank you both. Taken together this answers the general layer of my question: OCS versus REST is not the deciding factor, app policy is, and the authoritative answer has to come from the integration_openproject maintainers themselves.

@christianlupus thanks for taking the time to discuss this with the server devs and for the new OCS vs REST section in the docs; that removes exactly the ambiguity I kept running into. Your list of possible outcomes is what I will bring to the maintainers: awareness that a third party app wants to build on the API, and a request for either a stability statement, a description of their API lifecycle, or a channel where upcoming changes are announced. The account request on community.openproject.org is my next step, as you suggested earlier, and I will link this thread there.

@ernolf thank you for the OCS perspective and the ocs_api_viewer pointer, both went into my notes. Your description of the deprecation path (legacy in parallel, deprecated with notice, removed only after replacement) is the policy I would hope for; per Chris it just needs the maintainers to confirm it for this app.

Until they answer, I will design defensively: the OpenProject tools in mcp_connector stay behind a version check pinned to the surface I actually tested (integration_openproject 3.1.1, the 17 OCS routes), they degrade to a clear “not available” answer instead of failing halfway if a route changes, and nothing else in the app depends on them. If the maintainers consider the routes fair game and would welcome the three read-only additions from my first post (work package by id, comments, assigned to me), I would be glad to contribute them.

I will report back here once I have an answer from the OpenProject side, so the next person searching for this finds a conclusion rather than an open end.
Khaled