Backstage 1.49 Complete Guide — New Frontend System 1.0 RC by Default, Actions Registry, and mcp-actions-backend Make Your IDP AI-Native
As of January 2026, Backstage powers internal developer platforms (IDPs) at 3,400+ organizations and 2 million+ developers outside Spotify, commanding 89% market share among IDP frameworks. From that summit, the Spotify and CNCF community has shipped its largest architectural shift in five years. Backstage 1.49 promotes the New Frontend System (NFS) to 1.0 Release Candidate and makes it the default for new apps. It ships the Actions Registry as a first-class governance layer and adds @backstage/plugin-mcp-actions-backend, which exposes every registered action as a tool through the Model Context Protocol. In other words: Claude Code, Cursor, and ChatGPT can now query your catalog, run scaffolder tasks, and grant GitLab group permissions in one natural-language step. This guide walks through the NFS migration, Actions Registry governance, MCP server splitting, and the BUI breaking changes from a production-platform perspective.
1. Why Backstage 1.49 is the Inflection Point
The IDP debate "should we even build a portal?" effectively ended in 2026 — Backstage's 67% overall adoption and 89% framework share answered it. The remaining question is how to operate one, and 1.49 rewrites the operating model on three axes simultaneously.
| Axis | ≤ 1.48 | 1.49 | Operational Impact |
|---|---|---|---|
| Frontend system | Legacy + --next opt-in |
NFS 1.0 RC default, --legacy opt-out |
New apps forced onto NFS, existing apps need 6–12 month migration |
| Action governance | Scaffolder actions + custom hooks scattered | Single Actions Registry | Unified action catalog, permissions, audit logging |
| AI integration | External chatbots, separate search index |
mcp-actions-backend built in |
Claude / Cursor drive the IDP directly |
| BUI transition | MUI-based EntityCards | BUI (Backstage UI) migration in flight |
variant prop removed, silent layout regressions possible |
| Catalog query | Equality filters | Predicate filters ($all, $any, $not, $exists, $in, $hasPrefix, $contains) |
Massive expressiveness for large catalogs |
The takeaway is that 1.49 is not a feature drop but the first industry-standard release where platform engineering formally adopts AI. BackstageCon Europe 2026 (Amsterdam, March 26) made the same point: N26, Spotify, and Roadie all argued that Actions Registry plus MCP will define IDP design for the next 18 months.
2. New Frontend System 1.0 RC — --next is Gone, --legacy is Born
NFS reached 1.0 Release Candidate in 1.49 after alpha (2024) and beta (2025). The most visible change is that the CLI defaults flipped: npx @backstage/create-app now scaffolds an NFS-based app without the --next flag, and you must pass --legacy explicitly to opt back into the old system.
# 1.49 new app — defaults to NFS 1.0 RC
npx @backstage/create-app@latest --path my-portal
# Stay on the legacy MUI system
npx @backstage/create-app@latest --path my-portal --legacy
# Bump existing apps
yarn backstage-cli versions:bump --release latest
# New: Actions Registry CLI
yarn backstage-cli actions list
yarn backstage-cli actions execute scaffolder:catalog:register --input '{"url":"..."}'
yarn backstage-cli actions sources
The essence of NFS is that plugin extension points and routing are decided at app-config time, not at code-build time. Sidebar entries, pages, and catalog widgets toggle on or off purely from app-config.yaml's app.extensions block, which means you can ship the same binary to multiple environments and let configuration decide the plugin surface. In 1.49, PluginWrapperApi graduates from alpha to stable, and a new @backstage/frontend-dev-utils package gives you createDevApp() for spinning up plugin-only dev environments in a single line.
2.1 BUI (Backstage UI) — The Quiet Retirement of MUI Cards
In parallel with NFS 1.0 RC, Spotify is migrating the design system to BUI, a React Aria–based component layer. The 1.49 major bump of @backstage/plugin-catalog rebuilt EntityAboutCard, EntityLinksCard, EntityLabelsCard, GroupProfileCard, and UserProfileCard on BUI, and removed the variant prop in the process. ⚠️ Caution: if your code uses variant="gridItem" it will still compile but quietly break the EntityPage layout. Visual regression on EntityPage must be on the PR review checklist.
3. Actions Registry — Beyond Scaffolder, Toward IDP-Wide Automation Governance
Actions Registry arrived as beta in 1.48 and solidifies in 1.49 as a first-class platform-engineering primitive. The pre-1.48 model only allowed action invocation inside Scaffolder templates, which meant permissions, auditing, and reusability were all tied to template scope. Actions Registry lifts those concerns into a standard action type that plugins register, the permission system governs, and CLI / UI / MCP can all invoke identically.
// plugins/my-platform-backend/src/actions/registerService.ts
import { createBackendModule } from '@backstage/backend-plugin-api';
import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha';
import { z } from 'zod';
export const registerServiceModule = createBackendModule({
pluginId: 'platform',
moduleId: 'register-service',
register(reg) {
reg.registerInit({
deps: { registry: actionsRegistryServiceRef },
async init({ registry }) {
registry.register({
name: 'platform:register-service',
title: 'Register a new microservice',
description: 'Creates the catalog entry, GitHub repo, and ArgoCD app in one shot',
schema: {
input: z => z.object({
name: z.string().min(3),
owner: z.string(),
tier: z.enum(['tier-1', 'tier-2', 'tier-3']),
}),
output: z => z.object({ catalogRef: z.string(), repoUrl: z.string() }),
},
// New: who is allowed to invoke this action
visibilityPermission: { resourceType: 'platform-action', allow: 'platform-admins' },
async action({ input, credentials, logger }) {
logger.info(`Registering service: ${input.name}`);
// ... create GitHub repo, register in catalog, render Argo app
return { catalogRef: `component:default/${input.name}`, repoUrl: '...' };
},
});
},
});
},
});
That single block delivers a major leverage point: a Scaffolder template can call it as action: platform:register-service, a platform engineer can invoke it standalone via yarn backstage-cli actions execute, and mcp-actions-backend exposes it verbatim as an MCP tool. Write the action once, and humans, the CLI, and AI agents all consume it with identical semantics.
3.1 New Built-in Actions in 1.49
-
backstage:who-am-i— returns the caller's identity and permission context. Critical for AI agents to introspect their own permissions. -
catalog:query-entities— predicate-filter catalog queries ($all,$any,$not,$exists,$in,$hasPrefix,$contains). -
scaffolder:list-actions— Scaffolder action self-introduction. -
scaffolder:get-task-logs— stream logs of running or completed Scaffolder tasks. -
scaffolder:list-tasks— list tasks visible under the caller's permissions.
These five compose the meta-toolset an AI agent uses to bootstrap itself the first time it meets an IDP. At session start, calling who-am-i → list-actions → query-entities lets Claude Code learn what the IDP can do and what permissions it has — without human intervention.
4. mcp-actions-backend — The Standard Way to Expose an IDP Over MCP
@backstage/plugin-mcp-actions-backend is the most attention-grabbing addition in 1.49. Its job summarizes in one line: "Expose every action registered in the Actions Registry over the MCP protocol automatically." No additional translation code, no schema mapping. The schema.input/output you already defined in Zod is serialized straight to the MCP tool descriptor.
# app-config.yaml
mcpActions:
# 1.49 lets you split actions across multiple servers
servers:
- name: catalog-readonly
description: Read-only catalog — safe for external LLMs
include:
- catalog:query-entities
- backstage:who-am-i
authentication:
type: oauth2
clientRegistration: dynamic # DCR enabled
- name: platform-admin
description: Platform admins only — internal Claude Code sessions
include:
- platform:*
- scaffolder:*
exclude:
- scaffolder:delete-task # block dangerous actions
authentication:
type: bearer
longLivedTokens: true
The real strength of 1.49's mcp-actions is server-by-purpose splitting. From a single Backstage instance you can declaratively expose a read-only catalog endpoint to an external SaaS LLM and a full Scaffolder endpoint to authenticated internal Claude Code clients. Combined, include/exclude, dotted-wildcard names (plugin.action), and visibilityPermission give Backstage a small but real API gateway role for AI traffic.
4.1 Hooking Up Claude Code via DCR (Dynamic Client Registration)
- Enable OAuth2 DCR in the Backstage
authbackend (experimentalDynamicClientRegistration: true). - In Claude Code, run
/mcp add backstage https://portal.example.com/api/mcp/catalog-readonly. - Browser callback completes OAuth2 → long-lived token issued (
longLivedTokens: true). - Restart Claude Code (the tool catalog only loads at session start).
- Natural-language queries like "Group every tier-1 service by owner" translate into
catalog:query-entitiescalls.
ManoIT's platform team wired this into a Tier-1 on-call triage bot. PagerDuty alert → Claude → catalog:query-entities to identify affected services → scaffolder:get-task-logs to inspect recent deployments → first-pass diagnosis report. Mean response time dropped from 11 minutes to 2 minutes 40 seconds.
5. Catalog and Scaffolder Changes — Migration Checklist
Beyond NFS and the Actions Registry, 1.49 ships substantive updates to catalog and scaffolder.
| Area | Change | Migration Action |
|---|---|---|
| Catalog | Predicate filters ($all, $any, $not, $exists, $in, $hasPrefix, $contains) |
Existing simple filters keep working; adopt incrementally |
| Catalog Processor |
AnnotateScmSlugEntityProcessor and CodeOwnersProcessor moved to community plugin |
Add @backstage-community/plugin-catalog-backend-module-scm
|
| Scaffolder |
secrets.schema validation introduced, new gitlab:group:access action |
Add a schema to templates that consume secrets |
| Scaffolder API |
retry, listTasks, listTemplatingExtensions, dryRun, autocomplete are now required methods |
Implement these on any custom ScaffolderApi class |
| Bitbucket |
integrations.bitbucket removed, BitbucketUrlReader removed |
Migrate to bitbucketCloud / bitbucketServer
|
| Slack notifications | Channel DMs deprecated — DMs now only target user entity recipients | Route channel messages through Webhook channels |
| BUI Provider |
BUIProvider routing context now mandatory |
Wrap custom-page entry points with the provider |
5.1 ManoIT Internal IDP Migration Checklist
- ① Node 20.19 / 22.12+ — verify Yarn Berry + corepack environment.
-
② Bulk dependency bump — run
yarn backstage-cli versions:bump --release latestand regenerate the lockfile. -
③ Canary NFS opt-in — seed a new app (no
--legacy) on staging; visually regress EntityPage / TechDocs / Scaffolder. -
④ EntityCard
variantaudit — grep forEntityAboutCard variant="gridItem"and migrate to BUI grid props. -
⑤ Actions Registry inventory —
yarn backstage-cli actions listto discover unpermissioned actions. -
⑥ MCP server permission model — agree the externally-exposable action whitelist with security before configuring
mcpActions.servers. -
⑦ Bitbucket / Slack split — replace single
bitbucketkey withbitbucketCloud/bitbucketServer; route Slack channels through Webhooks. - ⑧ Catalog Processor reinforcement — explicitly install the community SCM Slug / CODEOWNERS processors that left core.
- ⑨ Rollback plan — keep previous-version lockfiles on a dedicated branch with a 24-hour rollback window.
6. Competitive Landscape — How Does Backstage Hold 89% Against Port, Cortex, and Roadie?
The 2026 IDP market has SaaS-first players (Port, Cortex), managed-Backstage providers (Spotify Portal, Roadie), and the self-hosted Backstage core community all pulling in different directions.
| Product | Model | Strength | Relationship to 1.49 | Best Fit |
|---|---|---|---|---|
| Backstage (self-host) | OSS framework | Fastest path to NFS / Actions Registry / MCP | The core itself | Platform teams that can self-operate |
| Spotify Portal | Managed Backstage | Spotify in-house plugins + DX Insights | NFS / MCP GA delivered in lockstep | Buyers who trust Spotify's lineage |
| Roadie | Managed Backstage | Automated upgrades, plugin curation | 1.49 compatibility shipped automatically | Teams without dedicated platform headcount |
| Port | Independent SaaS | Low-code data model and blueprints | Not compatible — separate stack | Orgs that include non-developer departments |
| Cortex | Independent SaaS | Service catalog + scorecards | Not compatible | SRE-led, governance-heavy organizations |
The headline is that Actions Registry + MCP put Backstage somewhere Port and Cortex cannot easily reach. Independent SaaS players have to define proprietary protocols and SDKs to expose their data models to AI; Backstage already publishes every action over the standard MCP. On the new evaluation axis of "AI-native IDP compatibility," 1.49 is effectively running unopposed.
7. Conclusion — H2 2026 Forces a Rewrite of Every IDP Operating Model
Backstage 1.49 is not a minor release; it is a turning point in IDP operating models. NFS 1.0 RC becomes the foundation for every new portal. Actions Registry collapses scattered automation into a single governance layer. mcp-actions-backend lifts the IDP into infrastructure that AI agents call routinely. ManoIT's recommendation is twofold. First, align every internal Backstage instance to 1.49 by Q3 2026 and break the NFS migration into PR-sized units to preserve a safety net. Second, agree the MCP-exposed action whitelist with security in advance. Catalog queries surfaced to external LLMs become objects of permissions, audit, and logging — policy precedes code. AI-native IDPs are not a tool change, they are an operating-model change, and Backstage 1.49 is the first release to industrialize that change.
This article was authored by ManoIT's engineering team with assistance from Anthropic Claude AI. Facts and code are based on Backstage's official documentation, the 1.49 release notes, and BackstageCon Europe 2026 sessions; some performance / operational figures and ManoIT internal measurements vary by environment. Validate in your own environment before adoption. — ManoIT (manoit.co.kr)
Originally published at ManoIT Tech Blog.
Top comments (0)