Repository navigation
Feature: MCP server exposing REST API with identical authz (incl. MyOpenCRE) #1003
Description
Issue
What is the issue?
Add an MCP (Model Context Protocol) server for OpenCRE that exposes the same capabilities as the existing REST API (/rest/v1/..., documented in docs/api/openapi.yaml), with identical authentication and authorisation requirements.
Agents and IDEs should be able to call OpenCRE through MCP the same way clients call REST today — including authenticated surfaces such as MyOpenCRE (GET/PUT /rest/v1/user/resources), chat completion (POST /rest/v1/completion), and any other @login_required / feature-flagged routes — without a weaker or parallel auth model.
Expected Behaviour
-
Capability parity
- MCP tools (and resources/prompts where appropriate) map 1:1 (or via a thin, documented mapping) to OpenAPI operations under
/rest/v1. - Public endpoints remain callable without login (same as REST).
- Protected endpoints require the same login / feature gates as REST, e.g.:
- MyOpenCRE:
CRE_ENABLE_LOGIN+CRE_ENABLE_MYOPENCRE+ authenticated session (login_required) for/rest/v1/user/resources - Chat:
login_requiredon/rest/v1/completion - Admin import routes: same
login_required(and any admin checks) as today
- MyOpenCRE:
- Unauthenticated or unauthorized MCP calls fail with the same effective outcomes as REST (401 / feature-disabled defaults), not silent empty success unless REST already does that (see
feature_enabled_or_defaultbehaviour on MyOpenCRE).
- MCP tools (and resources/prompts where appropriate) map 1:1 (or via a thin, documented mapping) to OpenAPI operations under
-
Authn/authz
- Reuse the existing OAuth/session model (or an explicitly designed, equivalent token flow that maps to the same session/user identity).
- No separate “MCP bypass” or shared static secret that grants MyOpenCRE / chat / admin powers.
- Document how a Cursor/Claude/other MCP client obtains and supplies credentials for local and for hosted (opencre.org) use.
-
Delivery
- Runnable locally and (if in scope) against production/staging OpenCRE.
- Documented install/config for at least one common MCP client (e.g. Cursor).
- Tests covering: public tool, auth-required tool denied without credentials, auth-required tool succeeds with credentials, MyOpenCRE feature-flag off behaviour matches REST.
Actual Behaviour
There is no OpenCRE MCP server; agents must invent ad-hoc HTTP calls and cannot reliably share REST authz semantics (especially for MyOpenCRE and other login-gated routes).
Steps to reproduce
N/A (feature request).
Success criteria
- MCP server implements tools covering OpenAPI
/rest/v1operations (or an agreed phased subset with a tracked gap list ending in full parity). - Authn/authz for each tool matches the corresponding REST route (
login_required, feature flags, admin rules). - MyOpenCRE
user/resourcesGET/PUT work over MCP only when REST would allow them. - Docs: client setup, auth flow, tool ↔ REST mapping table.
- Automated tests for public vs authenticated vs feature-gated paths.
-
make lint/make mypy/make test(and any new MCP-specific checks) green.
Context
- REST surface / contract:
docs/api/openapi.yaml,application/web/web_main.py - Auth helpers:
login_required,feature_enabled_or_default,is_myopencre_enabled/is_login_enabled - Related auth cleanup tickets: Auth: migrate OAuth routes from /rest/v1/login to /rest/v1/auth/* #963 (OAuth route migration), Auth-wrap POST /rest/v1/cre_csv_import (deprecate anonymous MyOpenCRE import) #966 (auth-wrap CSV import)
- Spec: Model Context Protocol
Design questions (to resolve in planning)
- Transport: local stdio MCP proxy to REST vs remote HTTP MCP hosted with the app?
- Auth UX: browser OAuth + cookie/session forwarding vs device-code / PAT / API token bound to the same user record?
- Phasing: ship public read tools first, then MyOpenCRE + completion, then admin — or full parity in one release?
- Implementation home: in-repo Python package vs separate npm/Python MCP package that calls REST?
Constraints
- Must not weaken REST security for MCP convenience.
- Prefer reusing OpenAPI as the source of truth for tool schemas rather than hand-maintaining a divergent surface.
- No production DB destructive ops; MCP must not expose privileged internal scripts beyond what REST already exposes.
- Mocks: not for authz tests — exercise real Flask auth gates (or equivalent integration) where practical.
Out of scope (unless explicitly pulled in)
- Changing REST auth model itself (covered by Auth: migrate OAuth routes from /rest/v1/login to /rest/v1/auth/* #963 / Auth-wrap POST /rest/v1/cre_csv_import (deprecate anonymous MyOpenCRE import) #966).
- New product APIs that do not exist on REST.
- Replacing the web UI with MCP.
Activity
nolanefe commentedon Aug 3, 2026
Hi, I’d like to work on this issue if it is still available.
I’ll first trace the existing REST/OpenAPI surface in
docs/api/openapi.yaml, the Flask route registration inapplication/web/web_main.py, and the current auth helpers (login_required, feature gates, and MyOpenCRE checks). Then I’d like to build the MCP layer as a thin adapter over the existing REST contracts rather than creating a separate authorization model.My proposed implementation would:
/rest/v1operations with explicit documentation of each tool-to-REST relationshipuser/resourcesaccess so GET/PUT operations succeed over MCP only when the equivalent REST request would be authorizedmake lint,make mypy, andmake testchecks together with any MCP-specific testsSince the issue leaves transport, authentication UX, and rollout phasing open, which direction would you prefer for the first PR: a smaller local stdio MCP implementation exposing the public REST-backed tools first, or should the initial contribution include authenticated/MyOpenCRE tools and the full auth flow as well?
bhanu-prakash920 commentedon Aug 7, 2026
Hi @northdpole! I'd love to work on this issue. Could you please assign it to me if it's still available? Thank you!
shiwani42 commentedon Aug 9, 2026
Hi @northdpole, I’d like to take this if it’s still available.
I’ve traced the REST/OpenAPI surface (
docs/api/openapi.yaml,web_main.py) and the auth helpers (login_required,feature_enabled_or_default, MyOpenCRE flags). My intent is a thin MCP adapter over the existing REST contracts, not a parallel auth model.Proposed direction for the first PR
OPENCRE_BASE_URL(local Flask or hosted)./rest/v1reads first (skipuser/resourcesuntil auth lands).application/mcp/.make lint/make mypy/make testgreen.Follow-up PR (after ack)
GET/PUT /rest/v1/user/resourceswith the same outcomes as REST (including feature-flag-off empty200).I’d defer admin/CSV import tools until #966 lands, and treat hosted HTTP MCP as a later phase.
Questions before I start coding
POST /rest/v1/completion) needs login and is not in the OpenAPI file. Should the first auth PR include a chat MCP tool anyway, or leave chat for a later PR?Please assign me if this plan works.
northdpole commentedon Aug 12, 2026
Assigning to @nolanefe as the first volunteer — thanks for the clear plan.
@bhanu-prakash920 @shiwani42 thanks for offering as well! If this one is taken, please check other
good first issue/help wantedtickets, or coordinate with @nolanefe if you want to collaborate on a follow-up PR (e.g. more tools / remote transport).northdpole commentedon Aug 12, 2026
Quick direction for the first PR: no auth for MCP to start.
Ship a local stdio MCP that only exposes public REST-backed tools (reads that work without login today). Skip MyOpenCRE, chat/completion, admin, and any cookie/PAT/session forwarding for now.
Auth-gated tools can land in a follow-up once the public surface is solid. Prefer OpenAPI as the source of truth for tool schemas, no MCP bypass secrets (there should be nothing privileged to bypass in v1), docs for Cursor setup + tool↔REST mapping, and tests that public tools match the corresponding REST responses.
@nolanefe — that answers your phasing question: public/local stdio first, authenticated/MyOpenCRE later.
shiwani42 commentedon Aug 13, 2026
Thanks @northdpole for the clear direction.
@nolanefe if you want a hand on a follow-up after the public stdio PR (auth/MyOpenCRE, chat, or remote transport later), happy to split that with you. Just ping me here.
Pa04rth commentedon Sep 13, 2026
@nolanefe Whats the update ??
nolanefe commentedon Sep 15, 2026
Thanks for checking in! The first phase of #1003 is complete: PR #1013 was merged, adding the local stdio MCP server for public OpenCRE REST reads. The broader #1003 scope remains open, with authenticated MyOpenCRE functionality, chat, and other protected surfaces still planned as follow-up work. I’m happy to continue with the next phase based on the maintainer’s direction.
northdpole commentedon Sep 16, 2026
Closing as completed for v1.
Public stdio MCP (no auth, fixed public GET allowlist) shipped in #1013 (
python -m application.mcp,docs/api/mcp.md). Thanks @nolanefe.Remaining work from this ticket (MyOpenCRE, chat, identical REST authz) is tracked in #1108.