DEV Community

daniel jeong
daniel jeong

Posted on • Originally published at manoit.co.kr

Backstage 1.49 Complete Guide — New Frontend System 1.0 RC by Default, Actions Registry, and mcp-actions-backend Make Your IDP AI-Native

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
Enter fullscreen mode Exit fullscreen mode

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: '...' };
          },
        });
      },
    });
  },
});
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)

  1. Enable OAuth2 DCR in the Backstage auth backend (experimentalDynamicClientRegistration: true).
  2. In Claude Code, run /mcp add backstage https://portal.example.com/api/mcp/catalog-readonly.
  3. Browser callback completes OAuth2 → long-lived token issued (longLivedTokens: true).
  4. Restart Claude Code (the tool catalog only loads at session start).
  5. Natural-language queries like "Group every tier-1 service by owner" translate into catalog:query-entities calls.

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 latest and regenerate the lockfile.
  • ③ Canary NFS opt-in — seed a new app (no --legacy) on staging; visually regress EntityPage / TechDocs / Scaffolder.
  • ④ EntityCard variant audit — grep for EntityAboutCard variant="gridItem" and migrate to BUI grid props.
  • ⑤ Actions Registry inventoryyarn backstage-cli actions list to discover unpermissioned actions.
  • ⑥ MCP server permission model — agree the externally-exposable action whitelist with security before configuring mcpActions.servers.
  • ⑦ Bitbucket / Slack split — replace single bitbucket key with bitbucketCloud / 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)