with one click
onboard-dcr-mcp
Onboard a new DCR OAuth MCP catalog entry with provider-doc vetting and curl probes. Use when adding or changing `mode: dcr` entries in MCP_SERVERS. Abort if the provider requires whitelist or manual approval.
Onboard a new DCR OAuth MCP catalog entry with provider-doc vetting and curl probes. Use when adding or changing `mode: dcr` entries in MCP_SERVERS. Abort if the provider requires whitelist or manual approval.
Build terminal user interfaces (TUIs) using Ink (React for CLIs) and @inkjs/ui with a reactive, session-driven wizard pattern. Use when creating interactive CLI installation wizards, setup flows, or multi-step terminal applications in Node.js/TypeScript. Covers reactive screen resolution, declarative flow pipelines, overlay interrupts, session state management, Ink components, Flexbox terminal layout, and graceful degradation across terminal environments.
Create or update Novu environment variables in the user's project safely (never expose the secret key to the client). Complements the official Novu skills by covering project-level env configuration.
Critically triage pull request review comments against PR requirements and codebase reality, implement only valid fixes, and reply only when declining a suggestion. Use when the user asks to address PR comments, review feedback, CodeRabbit/Bugbot threads, or `/address-pr-review`.
Post-implementation PR prep for Novu feature branches — quality passes, commit/PR hygiene, CI triage, and review feedback. Use after feature work is done, when the user asks to prepare a PR, ship a branch, fix CI, address review comments, or babysit a pull request before merge.
**MANDATORY prerequisite** — you MUST invoke this skill BEFORE every `use_figma` tool call. NEVER call `use_figma` directly without loading this skill first. Skipping it causes common, hard-to-debug failures. Trigger whenever the user wants to perform a write action or a unique read action that requires JavaScript execution in the Figma file context — e.g. create/edit/delete nodes, set up variables or tokens, build components and variants, modify auto-layout or fills, bind variables to properties, or inspect file structure programmatically.
Run e2e tests for the API service. Use when the user wants to run API E2E tests.
| name | onboard-dcr-mcp |
| description | Onboard a new DCR OAuth MCP catalog entry with provider-doc vetting and curl probes. Use when adding or changing `mode: dcr` entries in MCP_SERVERS. Abort if the provider requires whitelist or manual approval. |
Use this checklist when adding a new mode: dcr entry to packages/shared/src/consts/providers/mcp-servers.ts.
Default goal: upgrade or add catalog entries — not re-audit providers already on dcr.
Read mcp-servers.ts and blocked-mcp-servers.md, then classify each target:
Catalog oauth.mode | Blocked list | Action |
|---|---|---|
provider-managed (or missing entry) | not listed | Onboard — docs gate + probes + catalog/blocker edits |
provider-managed | open blocker | Skip — already triaged; only re-probe if user says unblocked |
dcr | — | Skip — do not run full onboarding or assign batch agents |
novu-app / user-app | — | Skip — out of scope for this skill unless user asks |
Do not label work as VERIFY_ONLY in a batch onboarding run. That outcome is for explicit single-provider regression requests only (e.g. “re-probe Sentry after an outage”).
provider-managed (or net-new) + user’s category filter (e.g. category: 'code') − open blockers − already dcr.dcr entries.# Example: list provider-managed code MCPs not on the blocked list (adjust paths)
rg "id: '" packages/shared/src/consts/providers/mcp-servers.ts -A6 | rg -B5 "ProviderManaged" | rg "category: 'code'"
rg "^\| \`" .cursor/skills/onboard-dcr-mcp/blocked-mcp-servers.md
dcr entry is allowedOnly if the user explicitly requests verification or there is a production incident for that id. Then: probes + short report; no catalog mode change unless probes fail (downgrade to provider-managed + blocker row).
Before curl probes or catalog edits:
Abort onboarding and report back to the user if the provider requires any of:
client_id supplied by the provider) instead of RFC 7591 DCRInclude the doc link and the specific requirement that blocked onboarding. Do not add a catalog entry or run live probes for providers that fail this gate. Append the provider to blocked-mcp-servers.md (Open blockers table).
| Situation | Action |
|---|---|
| PRM + AS metadata + DCR + token exchange all follow RFC behavior | Catalog entry only |
AS downgrades auth method at DCR (e.g. returns none) | Generic flow already handles RFC 7591 §3.2.1 |
| Issuer / PRM / gateway mismatch (Clerk, Vercel, PlanetScale-style) | Extend mcp-oauth-issuer-match.ts (review-gated) |
| Token endpoint returns non-standard JSON | Extend mcp-oauth-callback/token-exchange-outcome.ts (review-gated) |
PRM advertises oversized scopes_supported (Slack URL limits) | Pin oauth.scopes on the catalog dcr entry |
Default rule: do not touch generate-mcp-oauth-url.usecase.ts or mcp-oauth-callback.usecase.ts for a new provider unless discovery or token parsing truly cannot express the quirk generically.
Replace placeholders before running. Paste command output into the PR body.
MCP_URL="https://mcp.example.com/mcp"
curl -sS "$MCP_URL/.well-known/oauth-protected-resource" | jq .
# Also try path-suffixed well-known if the MCP URL has a path:
curl -sS "$(python3 - <<'PY'
from urllib.parse import urlparse
u = urlparse("https://mcp.example.com/mcp")
print(f"{u.scheme}://{u.netloc}/.well-known/oauth-protected-resource{u.path.rstrip('/')}")
PY
)" | jq .
Confirm: authorization_servers is non-empty, scopes_supported or challenge scope is documented.
ISSUER="https://auth.example.com"
curl -sS "$ISSUER/.well-known/oauth-authorization-server" | jq .
Confirm:
authorization_endpoint, token_endpoint, registration_endpoint presentcode_challenge_methods_supported includes S256token_endpoint_auth_methods_supported documentedREGISTER_URL="https://auth.example.com/register"
REDIRECT_URI="https://api.novu.co/v1/agents/mcp/oauth/callback"
curl -sS -X POST "$REGISTER_URL" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d "{
\"redirect_uris\": [\"$REDIRECT_URI\"],
\"client_name\": \"Novu probe\",
\"application_type\": \"web\",
\"grant_types\": [\"authorization_code\", \"refresh_token\"],
\"response_types\": [\"code\"],
\"token_endpoint_auth_method\": \"client_secret_post\"
}" | jq .
Confirm:
client_idtoken_endpoint_auth_method if it differs from the requestRecord which scopes the PRM advertises and which scope string Novu should request on authorize. If PRM omits scopes, note that in the PR. If the list is huge, pin a curated subset on oauth.scopes in the catalog entry.
## DCR onboarding evidence
- MCP id:
- MCP URL:
- Issuer:
### PRM
(paste curl output)
### AS metadata
(paste curl output)
### DCR register probe
(paste curl output; redact client_secret if returned)
### Scope notes
(which scopes PRM advertises / which Novu will request)
### Code changes beyond catalog?
- [ ] No — catalog entry only
- [ ] Yes — discovery issuer matching because ...
- [ ] Yes — token-exchange-outcome because ...
oauth.mode: dcr (see Candidate selection)packages/shared/src/consts/providers/mcp-servers.tspnpm build --filter @novu/shared if shared types changedtoken-exchange-outcome.ts changes (review-gated)packages/shared/src/consts/providers/mcp-servers.spec.ts DCR schema test passesblocked-mcp-servers.md; if unblocked later, move the row to Resolved