Skip to content

[EPIC][INTEGRATION]: Backstage integration - MCP/A2A federation, catalog sync, and developer portal experienceΒ #2809

@crivetimihai

Description

@crivetimihai

πŸ”Œ Epic: Backstage Integration - MCP/A2A federation, catalog sync, and developer portal experience

Goal

Deliver a bidirectional integration between Backstage and ContextForge that positions ContextForge as the MCP federation, A2A agent gateway, and governance layer behind Backstage's developer portal experience. This includes a Backstage backend plugin, a frontend plugin, a catalog entity provider, and ContextForge-side API extensions β€” enabling developers to discover, manage, invoke, and govern MCP tools, A2A agents, and federated services directly from their Backstage portal.

Why Now?

The Internal Developer Platform (IDP) space and the AI tooling ecosystem are converging rapidly, but the integration seam between them remains underserved:

  1. Backstage Has MCP β€” But No Registry: Backstage shipped @backstage/plugin-mcp-actions-backend in v1.40 (mid-2025), exposing Backstage actions as MCP tools. However, the community MCP Registry proposal (backstage/community-plugins #4034) remains open and stalled. There is no built-in way to discover, register, or govern MCP servers at scale within Backstage.

  2. Backstage Has No A2A Support: There is zero A2A protocol integration in Backstage β€” no plugins, no proposals, no community efforts. As agentic AI adoption accelerates, this becomes a significant gap. ContextForge already supports A2A agent registration, invocation, team scoping, and metrics.

  3. Federation Gap: Organisations deploying multiple MCP servers across teams need a federation layer that aggregates, governs, and exposes them through a single endpoint. Backstage alone cannot federate upstream MCP servers β€” ContextForge can.

  4. Governance and Multi-Tenancy: Backstage's permission framework handles UI-level access control. ContextForge adds wire-level governance: RBAC, team-scoped visibility, rate limiting, plugin-based policy enforcement, and audit logging for every tool invocation. Together they cover the full stack.

  5. Market Positioning: Spotify Portal (commercial Backstage) already registers MCP servers as catalog API entities. Red Hat Developer Hub has shipped MCP integration. An open-source ContextForge integration fills this space for the broader Backstage community β€” and does more by adding A2A, federation, and policy enforcement.

  6. Developer Experience: Engineers should not need to leave their portal to manage AI tools, agents, and service integrations. Surfacing ContextForge capabilities inside Backstage reduces context-switching and makes governed AI tooling a first-class part of the developer workflow.


πŸ“– User Stories

US-1: Platform Engineer β€” Register ContextForge as a Backstage Integration

As a Platform Engineer
I want to connect my Backstage instance to a ContextForge gateway
So that all federated MCP tools, A2A agents, and resources appear in our developer portal

Acceptance Criteria:

Given the ContextForge Backstage backend plugin is installed
When I configure app-config.yaml:
  contextforge:
    baseUrl: https://contextforge.internal.example.com
    auth:
      method: bearer
      token: ${CONTEXTFORGE_TOKEN}
    sync:
      intervalSeconds: 300
      entityKinds:
        - tools
        - resources
        - prompts
        - servers
        - a2a-agents
        - gateways
Then the plugin should:
  - Connect to the ContextForge API on startup
  - Authenticate using the configured method
  - Begin periodic sync of entities into the Backstage catalog
  - Expose ContextForge health status on the plugin's health endpoint
  - Log sync results with entity counts and any errors

Technical Requirements:

  • Backstage backend plugin using createBackendPlugin() (New Backend System)
  • Support bearer, basic, and OAuth authentication to ContextForge
  • Configurable sync interval with jitter to prevent thundering herd
  • Health check endpoint for monitoring
  • Graceful degradation if ContextForge is unreachable
US-2: Developer β€” Discover MCP Tools in the Backstage Catalog

As a Developer
I want to browse all available MCP tools from ContextForge in the Backstage software catalog
So that I can find and understand AI tools available to my team without leaving the portal

Acceptance Criteria:

Given ContextForge has 50 federated tools across 5 upstream gateways
When the catalog entity provider syncs
Then each tool should appear as a Backstage catalog entity:
  apiVersion: backstage.io/v1alpha1
  kind: API
  metadata:
    name: contextforge-tool-customer-lookup
    description: "Look up customer details by ID"
    annotations:
      contextforge.io/tool-id: "abc-123"
      contextforge.io/gateway-id: "gateway-456"
      contextforge.io/gateway-name: "crm-service"
      contextforge.io/transport: "STREAMABLEHTTP"
      contextforge.io/visibility: "team"
      contextforge.io/team-id: "engineering"
    tags:
      - mcp-tool
      - contextforge
      - crm
    links:
      - url: https://contextforge.internal/tools/abc-123
        title: "View in ContextForge"
  spec:
    type: mcp-tool
    lifecycle: production
    owner: group:engineering
    system: contextforge-crm-gateway
    definition:
      $text: |
        name: customer-lookup
        description: Look up customer details by ID
        inputSchema:
          type: object
          properties:
            customer_id:
              type: string
              description: The customer identifier
          required:
            - customer_id
And tools should be searchable by name, tag, gateway, and team
And team-scoped tools should respect Backstage group membership

Technical Requirements:

  • Catalog entity provider implementing EntityProvider interface
  • Map ContextForge tools β†’ kind: API with spec.type: mcp-tool
  • Map ContextForge resources β†’ kind: API with spec.type: mcp-resource
  • Map ContextForge prompts β†’ kind: API with spec.type: mcp-prompt
  • Map ContextForge servers β†’ kind: Component with spec.type: mcp-server
  • Map ContextForge gateways β†’ kind: Component with spec.type: mcp-gateway
  • Map ContextForge A2A agents β†’ kind: Component with spec.type: a2a-agent
  • Preserve ContextForge team scoping via Backstage group ownership
  • Include input schemas in API definitions for documentation rendering
  • Incremental sync (delta updates) to avoid catalog churn
US-3: Developer β€” Invoke MCP Tools from Backstage

As a Developer
I want to invoke an MCP tool directly from its Backstage catalog page
So that I can test and use tools without switching to a separate UI or CLI

Acceptance Criteria:

Given I am viewing an MCP tool entity in the Backstage catalog
And the tool has an input schema with required parameters
When I click "Invoke Tool" on the entity page
Then I should see:
  - A form generated from the tool's input schema
  - Pre-populated defaults where available
  - A "Run" button to execute the tool
When I submit the form
Then the backend plugin should:
  - Forward the invocation to ContextForge: POST /tools/{tool_id}/invoke
  - Pass my Backstage identity for ContextForge RBAC evaluation
  - Display the tool result in a formatted output panel
  - Show execution time, status, and any errors
  - Log the invocation in ContextForge's audit trail

Technical Requirements:

  • Frontend card component for tool invocation on API entity pages
  • JSON Schema form renderer for tool input schemas
  • Backend proxy route to ContextForge tool invocation endpoint
  • Identity forwarding: map Backstage user β†’ ContextForge JWT claims
  • Result rendering with syntax highlighting for JSON/text/markdown
  • Error handling with user-friendly messages
  • Rate limiting awareness (show 429 status clearly)
US-4: Developer β€” Interact with A2A Agents from Backstage

As a Developer
I want to discover and invoke A2A agents registered in ContextForge from Backstage
So that I can interact with AI agents without managing direct API integrations

Acceptance Criteria:

Given ContextForge has 3 A2A agents registered:
  - "code-review-agent" (anthropic, team: engineering)
  - "test-generator-agent" (openai, team: engineering)
  - "docs-agent" (custom, team: documentation)
When I navigate to the A2A Agents section in Backstage
Then I should see agents available to my team
And each agent card should show:
  - Agent name, type, and description
  - Capabilities and supported models
  - Team ownership and visibility
  - Health status and response time metrics
  - Last invocation timestamp
When I click "Chat" on an agent
Then I should see a conversational interface
And messages should be proxied through ContextForge: POST /a2a-agents/{id}/invoke
And the conversation should respect ContextForge RBAC and rate limits

Technical Requirements:

  • A2A agent entities in catalog (kind: Component, spec.type: a2a-agent)
  • Frontend page: /contextforge/agents with agent cards
  • Conversational UI component for agent interaction
  • Backend proxy to ContextForge A2A invocation API
  • Streaming response support (SSE) for long-running agent tasks
  • Agent metrics display (invocations, success rate, avg response time)
US-5: Platform Engineer β€” Manage ContextForge Gateways from Backstage

As a Platform Engineer
I want to view and manage ContextForge's federated gateways from Backstage
So that I can monitor upstream MCP server health and manage federation from the portal

Acceptance Criteria:

Given ContextForge has 8 upstream gateways registered
When I navigate to the ContextForge Gateways page in Backstage
Then I should see each gateway with:
  - Name, URL, and transport type (SSE, STREAMABLEHTTP, STDIO)
  - Health status (healthy, unhealthy, disabled)
  - Last refresh timestamp
  - Count of tools, resources, and prompts provided
  - Team ownership and visibility scope
When I click on a gateway
Then I should see:
  - Detailed gateway configuration
  - List of tools/resources/prompts it provides
  - Health check history
  - Dependency graph showing which virtual servers use this gateway
When I click "Refresh"
Then the plugin should call POST /gateways/{id}/refresh
And update the catalog entities with any new or removed capabilities

Technical Requirements:

  • Gateway management page: /contextforge/gateways
  • Real-time health status via polling or SSE
  • Gateway β†’ tool/resource dependency visualization
  • Refresh capability with progress indication
  • Gateway registration form (for platform engineers with admin RBAC)
US-6: Platform Engineer β€” Sync Backstage Groups with ContextForge Teams

As a Platform Engineer
I want Backstage groups to sync with ContextForge teams
So that team-scoped visibility in ContextForge aligns with our organisational structure in Backstage

Acceptance Criteria:

Given Backstage has groups:
  - group:engineering (members: alice, bob)
  - group:security (members: carol)
  - group:platform (members: dave)
And ContextForge has teams:
  - engineering (members: alice@corp.com, bob@corp.com)
  - security (members: carol@corp.com)
When team sync runs
Then ContextForge teams should match Backstage groups
And team-scoped tools visible to "engineering" in ContextForge
  should appear owned by "group:engineering" in Backstage
And a developer in group:engineering should see engineering-scoped
  tools but not security-scoped tools in their catalog view

Technical Requirements:

  • Configurable group β†’ team mapping (name-based or explicit mapping)
  • Sync direction: Backstage β†’ ContextForge (Backstage as source of truth for org structure)
  • Member email resolution from Backstage user entities
  • Conflict resolution strategy for mismatched memberships
  • Dry-run mode for validating sync before applying
US-7: AI Assistant β€” Use ContextForge Tools via Backstage MCP Endpoint

As an AI Assistant (Claude, Cursor, ChatGPT) connected to Backstage's MCP endpoint
I want to discover and invoke ContextForge's federated tools through Backstage
So that I can access the full tool ecosystem without direct ContextForge connectivity

Acceptance Criteria:

Given Backstage's MCP Actions backend is running at /api/mcp-actions/v1
And the ContextForge plugin registers federated tools as Backstage actions
When an MCP client connects to Backstage's MCP endpoint
And calls tools/list
Then the response should include ContextForge tools alongside native Backstage actions
And each tool should have:
  - Correct name and description from ContextForge
  - Input schema matching the original tool definition
  - Annotations indicating ContextForge origin
When the MCP client calls tools/call for a ContextForge tool
Then Backstage should proxy the call to ContextForge
And return the result to the MCP client
And ContextForge's plugin chain (PII filter, rate limiter, etc.) should execute

Technical Requirements:

  • Register ContextForge tools as Backstage Actions via ActionsRegistryService
  • Map ContextForge tool schemas to Backstage Action schemas (Zod)
  • Proxy tool invocations through ContextForge's /tools/{id}/invoke endpoint
  • Honour ContextForge plugin chain (pre/post hooks execute server-side)
  • Handle tool pagination (ContextForge may have hundreds of tools)
  • Respect team scoping: only register actions visible to the requesting user
US-8: Security Engineer β€” Audit ContextForge Activity from Backstage

As a Security Engineer
I want to view ContextForge audit logs and access metrics from within Backstage
So that I can monitor AI tool usage and governance compliance from a single pane

Acceptance Criteria:

Given ContextForge has observability and audit logging enabled
When I navigate to the ContextForge Observability page in Backstage
Then I should see:
  - Tool invocation counts by team, user, and tool
  - A2A agent usage metrics
  - Plugin violation summary (blocked requests, policy hits)
  - Gateway health overview
  - Recent audit log entries with filtering
And I should be able to filter by:
  - Time range
  - Team / user
  - Tool / agent
  - Decision (allow / deny / violation)

Technical Requirements:

  • Observability dashboard page: /contextforge/observability
  • Backend proxy to ContextForge metrics and log search APIs
  • Chart components for usage trends (time series)
  • Audit log table with pagination and filtering
  • Export capability (CSV/JSON) for compliance reporting

πŸ— Architecture

Integration Overview

graph TB
    subgraph "Developer Experience"
        IDE[IDE / AI Assistant]
        BS_UI[Backstage Frontend]
    end

    subgraph "Backstage"
        BS_FE[Frontend Plugin<br/>@contextforge/backstage-plugin]
        BS_BE[Backend Plugin<br/>@contextforge/backstage-plugin-backend]
        BS_CAT[Catalog Entity Provider<br/>@contextforge/backstage-plugin-catalog-module]
        BS_ACT[MCP Actions Bridge<br/>registers CF tools as actions]
        BS_MCP[MCP Actions Backend<br/>@backstage/plugin-mcp-actions-backend]
        CATALOG[(Backstage Catalog)]
    end

    subgraph "ContextForge"
        CF_API[ContextForge API<br/>REST + MCP + A2A]
        CF_PLUG[Plugin Chain<br/>PII, Rate Limit, RBAC]
        CF_FED[Federation Layer]
        CF_REG[(Service Registry<br/>Tools, Resources,<br/>Prompts, Agents)]
    end

    subgraph "Upstream Services"
        MCP1[MCP Server 1<br/>SSE]
        MCP2[MCP Server 2<br/>Streamable HTTP]
        A2A1[A2A Agent<br/>Claude]
        A2A2[A2A Agent<br/>Custom]
        REST1[REST API<br/>via Reverse Proxy]
    end

    IDE -->|MCP Protocol| BS_MCP
    BS_UI --> BS_FE
    BS_FE -->|REST| BS_BE
    BS_BE -->|REST| CF_API
    BS_CAT -->|Periodic Sync| CF_API
    BS_ACT -->|Register Actions| BS_MCP
    BS_CAT -->|Write Entities| CATALOG
    BS_MCP -->|tools/call| BS_ACT
    BS_ACT -->|Proxy Invoke| CF_API

    CF_API --> CF_PLUG
    CF_PLUG --> CF_FED
    CF_FED --> CF_REG
    CF_FED --> MCP1
    CF_FED --> MCP2
    CF_API --> A2A1
    CF_API --> A2A2
    CF_API --> REST1
Loading

Entity Mapping

graph LR
    subgraph "ContextForge Entities"
        CF_T[Tool]
        CF_R[Resource]
        CF_P[Prompt]
        CF_S[Virtual Server]
        CF_G[Gateway]
        CF_A[A2A Agent]
        CF_TM[Team]
    end

    subgraph "Backstage Catalog Entities"
        BS_API_T["kind: API<br/>spec.type: mcp-tool"]
        BS_API_R["kind: API<br/>spec.type: mcp-resource"]
        BS_API_P["kind: API<br/>spec.type: mcp-prompt"]
        BS_COMP_S["kind: Component<br/>spec.type: mcp-server"]
        BS_COMP_G["kind: Component<br/>spec.type: mcp-gateway"]
        BS_COMP_A["kind: Component<br/>spec.type: a2a-agent"]
        BS_GRP["kind: Group"]
    end

    CF_T --> BS_API_T
    CF_R --> BS_API_R
    CF_P --> BS_API_P
    CF_S --> BS_COMP_S
    CF_G --> BS_COMP_G
    CF_A --> BS_COMP_A
    CF_TM --> BS_GRP
Loading

Sync Flow

sequenceDiagram
    participant Scheduler as Backstage Scheduler
    participant Provider as Catalog Entity Provider
    participant CF as ContextForge API
    participant Catalog as Backstage Catalog

    Scheduler->>Provider: Trigger sync (every N seconds)

    Provider->>CF: GET /tools?visibility=public,team
    CF-->>Provider: Tool list (paginated)

    Provider->>CF: GET /a2a-agents?visibility=public,team
    CF-->>Provider: Agent list (paginated)

    Provider->>CF: GET /gateways
    CF-->>Provider: Gateway list

    Provider->>CF: GET /servers
    CF-->>Provider: Virtual server list

    Provider->>Provider: Transform CF entities β†’ Backstage entities
    Provider->>Provider: Compute delta (added, updated, removed)

    Provider->>Catalog: Apply delta mutations
    Catalog-->>Provider: Mutation result

    Provider->>Provider: Log sync summary

    Note over Provider,Catalog: Next sync in N seconds...
Loading

Tool Invocation Flow

sequenceDiagram
    participant Dev as Developer
    participant BS_FE as Backstage Frontend
    participant BS_BE as Backstage Backend Plugin
    participant CF as ContextForge API
    participant Plugins as CF Plugin Chain
    participant GW as CF Gateway Service
    participant Upstream as Upstream MCP Server

    Dev->>BS_FE: Click "Invoke Tool" on catalog page
    BS_FE->>BS_FE: Render form from input schema
    Dev->>BS_FE: Fill parameters and submit

    BS_FE->>BS_BE: POST /api/contextforge/tools/{id}/invoke
    Note over BS_FE,BS_BE: Backstage auth token included

    BS_BE->>BS_BE: Map Backstage identity β†’ CF JWT claims
    BS_BE->>CF: POST /tools/{id}/invoke (CF bearer token)

    CF->>Plugins: tool_pre_invoke hooks
    Note over Plugins: RBAC check, rate limit,<br/>PII filter, clearance check

    alt Plugin violation
        Plugins-->>CF: Blocked (violation)
        CF-->>BS_BE: 403 / 429 with violation details
        BS_BE-->>BS_FE: Error with user-friendly message
        BS_FE-->>Dev: Display error
    else Allowed
        Plugins-->>CF: Continue
        CF->>GW: Route to source gateway
        GW->>Upstream: Forward invocation
        Upstream-->>GW: Tool result
        GW-->>CF: Result
        CF->>Plugins: tool_post_invoke hooks
        Plugins-->>CF: Result (possibly modified)
        CF-->>BS_BE: Tool result
        BS_BE-->>BS_FE: Formatted result
        BS_FE-->>Dev: Display output
    end
Loading

πŸ“‹ Implementation Tasks

Phase 1: Backstage Backend Plugin β€” Core

  • Project Scaffolding

    • Create @contextforge/backstage-plugin-backend package
    • Set up TypeScript project with Backstage backend plugin dependencies
    • Implement createBackendPlugin() with core services (Config, Logger, Database, HTTP Router, Discovery, Auth)
    • Add configuration schema for app-config.yaml (contextforge.baseUrl, contextforge.auth, contextforge.sync)
    • Implement ContextForge API client class with authentication, retry, and error handling
  • ContextForge API Client

    • Typed client for ContextForge REST endpoints
    • Methods: listTools(), listResources(), listPrompts(), listServers(), listGateways(), listA2AAgents()
    • Methods: invokeTool(), invokeAgent(), refreshGateway()
    • Methods: getMetrics(), searchAuditLogs()
    • Pagination handling (ContextForge uses offset/limit)
    • Authentication: bearer token, basic auth, OAuth 2.0 client credentials
    • Connection pooling and timeout configuration
    • Circuit breaker for ContextForge unavailability
  • Backend API Routes

    • GET /api/contextforge/health β€” Connection and sync status
    • GET /api/contextforge/tools β€” Proxied tool listing
    • POST /api/contextforge/tools/:id/invoke β€” Proxied tool invocation
    • GET /api/contextforge/agents β€” Proxied A2A agent listing
    • POST /api/contextforge/agents/:id/invoke β€” Proxied agent invocation
    • GET /api/contextforge/gateways β€” Proxied gateway listing
    • POST /api/contextforge/gateways/:id/refresh β€” Proxied gateway refresh
    • GET /api/contextforge/metrics β€” Proxied metrics/observability
    • GET /api/contextforge/audit β€” Proxied audit log search

Phase 2: Catalog Entity Provider

  • Entity Provider Implementation

    • Implement EntityProvider interface for Backstage catalog
    • Periodic sync with configurable interval (default 300s)
    • Delta detection: compare current catalog state vs ContextForge state
    • Entity mapping: ContextForge tools β†’ kind: API, spec.type: mcp-tool
    • Entity mapping: ContextForge resources β†’ kind: API, spec.type: mcp-resource
    • Entity mapping: ContextForge prompts β†’ kind: API, spec.type: mcp-prompt
    • Entity mapping: ContextForge servers β†’ kind: Component, spec.type: mcp-server
    • Entity mapping: ContextForge gateways β†’ kind: Component, spec.type: mcp-gateway
    • Entity mapping: ContextForge A2A agents β†’ kind: Component, spec.type: a2a-agent
    • Emit providesApi / dependsOn relations between servers and their tools
    • Emit ownedBy relations to Backstage groups based on ContextForge team IDs
  • Catalog Backend Module

    • Create @contextforge/backstage-plugin-catalog-module package
    • Register entity provider as a catalog backend module via createBackendModule()
    • Wire into catalog's extension point for entity providers
    • Support entity removal when ContextForge entities are deleted or disabled
  • Team β†’ Group Mapping

    • Configurable team-to-group mapping in app-config.yaml
    • Default: match by name (ContextForge team name = Backstage group name)
    • Override: explicit mapping table for mismatched names
    • Fallback: assign to a default group when no mapping found

Phase 3: MCP Actions Bridge

  • Action Registration

    • Register ContextForge tools as Backstage Actions via ActionsRegistryService
    • Convert ContextForge tool input schemas (JSON Schema) to Zod schemas
    • Generate action IDs: contextforge:tool:<tool-name>
    • Include tool description and metadata in action registration
    • Handle schema updates on re-sync (unregister stale, register new)
  • Action Execution

    • Implement action handler that proxies to ContextForge /tools/{id}/invoke
    • Map Backstage user identity to ContextForge auth context
    • Return structured results compatible with MCP tool result format
    • Handle errors and timeouts gracefully
  • MCP Client Compatibility

    • Verify tools appear in tools/list for MCP clients connecting to Backstage
    • Verify tools/call correctly proxies through ContextForge
    • Test with Claude Desktop, Cursor, and ChatGPT as MCP clients
    • Verify ContextForge plugin chain executes (PII filter, rate limiting, etc.)

Phase 4: Backstage Frontend Plugin

  • Plugin Scaffolding

    • Create @contextforge/backstage-plugin frontend package
    • Set up React components with Backstage frontend plugin API
    • Register routes: /contextforge, /contextforge/agents, /contextforge/gateways, /contextforge/observability
    • Add navigation sidebar item with ContextForge icon
  • Tool Invocation Card

    • Entity page card component for spec.type: mcp-tool entities
    • JSON Schema-driven form renderer for tool input parameters
    • Execute button with loading state
    • Result display panel with syntax-highlighted JSON/text/markdown output
    • Error display with ContextForge violation details
    • Invocation history (last 10 calls) stored in browser
  • A2A Agent Page

    • Agent list page with cards showing name, type, team, health, metrics
    • Agent detail page with capabilities, configuration, and invocation history
    • Conversational chat interface for agent interaction
    • Streaming response support for long-running agent tasks
    • Agent metrics charts (invocations over time, success rate, response time)
  • Gateway Management Page

    • Gateway list with health status indicators (green/yellow/red)
    • Gateway detail: configuration, transport type, auth method, provided tools/resources
    • Refresh button with progress indication
    • Gateway β†’ tool dependency visualization (simple tree or graph)
    • Register new gateway form (for admin users)
  • Observability Dashboard

    • Tool invocation counts (bar chart by tool, line chart over time)
    • Agent usage metrics (invocations, success rate)
    • Plugin violation summary (blocked requests by plugin, violation type)
    • Gateway health overview (uptime percentages)
    • Audit log table with pagination, search, and time range filtering
    • Export to CSV/JSON
  • Entity Page Enhancements

    • For mcp-tool entities: invocation card, metrics card, gateway info card
    • For mcp-gateway entities: health card, provided tools list, refresh button
    • For a2a-agent entities: chat card, metrics card, capabilities card
    • For mcp-server entities: associated tools/resources list, status card

Phase 5: Identity and RBAC Bridge

  • Identity Mapping

    • Map Backstage userEntityRef to ContextForge user email
    • Map Backstage group membership to ContextForge token_teams JWT claims
    • Generate scoped ContextForge JWT tokens for proxied requests
    • Configurable claim mapping for non-standard identity providers
  • Permission Integration

    • Define Backstage permissions: contextforge.tool.invoke, contextforge.agent.invoke, contextforge.gateway.manage, contextforge.audit.view
    • Integrate with Backstage permission framework (@backstage/plugin-permission-backend)
    • Map Backstage permissions to ContextForge RBAC roles (viewer, developer, team_admin, platform_admin)
    • Conditional permissions based on entity ownership (team-scoped)
  • Team Sync Service

    • Backstage group β†’ ContextForge team sync (configurable direction)
    • Member email resolution from Backstage user entities
    • Sync on schedule and on-demand via API
    • Dry-run mode for validation
    • Conflict logging and resolution strategy

Phase 6: ContextForge-Side Extensions

  • Backstage Webhook Notifications

    • New ContextForge API endpoint: POST /webhooks for registering notification targets
    • Emit events on: tool created/updated/deleted, gateway health change, agent status change
    • Backstage plugin subscribes to webhooks for real-time catalog updates
    • Reduces polling frequency and improves sync latency
  • Catalog Metadata Endpoint

    • New ContextForge API endpoint: GET /catalog/backstage returning pre-formatted Backstage entity descriptors
    • Eliminates client-side entity transformation
    • Includes relations, annotations, and ownership pre-computed
    • Supports If-Modified-Since for efficient delta sync
  • Identity Federation Endpoint

    • New ContextForge API endpoint: POST /auth/backstage/token-exchange
    • Accept Backstage service-to-service token
    • Return ContextForge JWT with mapped claims (email, teams, roles)
    • Eliminates need for shared static tokens

Phase 7: Testing

  • Backend Plugin Unit Tests

    • ContextForge API client: authentication, pagination, error handling
    • Entity provider: mapping correctness for all 6 entity types
    • Delta sync: additions, updates, removals
    • Team mapping: name-based, explicit, fallback
    • API routes: request validation, proxy behavior, error propagation
  • Frontend Plugin Tests

    • Component rendering: tool invocation card, agent chat, gateway list
    • Form generation from JSON Schema
    • API call mocking and error states
    • Permission-based UI element visibility
  • Integration Tests

    • Full sync cycle: ContextForge β†’ entity provider β†’ Backstage catalog
    • Tool invocation end-to-end: Backstage UI β†’ backend β†’ ContextForge β†’ upstream
    • MCP client via Backstage: connect, list tools, call tool
    • A2A agent invocation via Backstage proxy
    • Team sync: create group in Backstage, verify team in ContextForge
    • RBAC: verify team-scoped tools only visible to correct groups
  • Compatibility Tests

    • Backstage versions: v1.40+, latest
    • ContextForge versions: current release, previous release
    • MCP clients: Claude Desktop, Cursor, VS Code Copilot
    • Browsers: Chrome, Firefox, Safari

Phase 8: Documentation

  • Installation Guide

    • Prerequisites (Backstage version, ContextForge version, Node.js)
    • Package installation (yarn add)
    • Backend plugin registration in packages/backend/src/index.ts
    • Frontend plugin registration in packages/app/src/App.tsx
    • app-config.yaml configuration reference
    • Authentication setup (bearer token, OAuth)
  • User Guide

    • Browsing MCP tools in the catalog
    • Invoking tools from entity pages
    • Interacting with A2A agents
    • Viewing gateway health and metrics
    • Understanding team-scoped visibility
  • Administrator Guide

    • Sync configuration and tuning
    • Team-to-group mapping
    • Permission setup
    • Troubleshooting connectivity and sync issues
    • Monitoring plugin health
  • Architecture Decision Record

    • Entity kind mapping rationale (API vs Component)
    • Sync strategy (polling vs webhook)
    • Identity mapping approach
    • Why catalog entity provider over static location

Phase 9: Quality and Polish

  • Code Quality

    • ESLint + Prettier for TypeScript packages
    • Backstage CLI lint and test pass
    • No any types in TypeScript
    • Comprehensive JSDoc for public APIs
  • Performance

    • Sync completes in <30s for 500 entities
    • Tool invocation adds <100ms overhead vs direct ContextForge call
    • Frontend renders tool list in <2s for 200 tools
    • Catalog entity provider uses incremental delta (not full replace)
  • Security Review

    • No secrets in configuration (use environment variable references)
    • Token exchange does not leak ContextForge credentials to frontend
    • Proxy routes validate input before forwarding to ContextForge
    • CORS configuration for frontend-to-backend communication
  • Packaging and Release

    • Publish to npm: @contextforge/backstage-plugin, @contextforge/backstage-plugin-backend, @contextforge/backstage-plugin-catalog-module
    • Version aligned with Backstage release compatibility
    • Changeset entries for all packages
    • README with badges (npm version, Backstage compatibility, license)

βš™οΈ Configuration Example

app-config.yaml

contextforge:
  # ContextForge gateway connection
  baseUrl: https://contextforge.internal.example.com

  # Authentication to ContextForge API
  auth:
    method: bearer  # bearer | basic | oauth
    token: ${CONTEXTFORGE_BEARER_TOKEN}
    # For OAuth:
    # method: oauth
    # clientId: ${CF_CLIENT_ID}
    # clientSecret: ${CF_CLIENT_SECRET}
    # tokenUrl: https://contextforge.internal.example.com/oauth/token

  # Catalog sync configuration
  sync:
    enabled: true
    intervalSeconds: 300        # Sync every 5 minutes
    entityKinds:                # Which CF entities to sync
      - tools
      - resources
      - prompts
      - servers
      - gateways
      - a2a-agents
    teamMapping:
      strategy: name            # name | explicit
      # For explicit mapping:
      # strategy: explicit
      # map:
      #   cf-engineering: group:engineering-team
      #   cf-security: group:infosec
      defaultGroup: group:default

  # Proxy settings
  proxy:
    timeout: 30000              # 30s timeout for proxied requests
    retries: 2                  # Retry failed requests

  # Feature flags
  features:
    toolInvocation: true        # Enable tool invocation from UI
    agentChat: true             # Enable A2A agent chat interface
    gatewayManagement: true     # Enable gateway management UI
    observabilityDashboard: true # Enable observability page
    mcpActionsBridge: true      # Register CF tools as Backstage MCP Actions

# Register the entity provider
catalog:
  providers:
    contextforge:
      # Uses settings from contextforge.baseUrl and contextforge.auth above
      schedule:
        frequency:
          minutes: 5
        timeout:
          minutes: 3

Backend Registration

// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

// ... other plugins ...

// ContextForge integration
backend.add(import('@contextforge/backstage-plugin-backend'));
backend.add(import('@contextforge/backstage-plugin-catalog-module'));

backend.start();

Frontend Registration

// packages/app/src/App.tsx
import { contextforgePlugin, ContextForgePage } from '@contextforge/backstage-plugin';

// In routes:
<Route path="/contextforge" element={<ContextForgePage />} />

// Entity page cards (in EntityPage.tsx):
import {
  ContextForgeToolInvocationCard,
  ContextForgeAgentCard,
  ContextForgeGatewayHealthCard,
} from '@contextforge/backstage-plugin';

// On API entity pages (for mcp-tool type):
<EntitySwitch.Case if={isContextForgeTool}>
  <ContextForgeToolInvocationCard />
</EntitySwitch.Case>

βœ… Success Criteria

  • Catalog Sync: ContextForge tools, resources, prompts, servers, gateways, and A2A agents appear in Backstage catalog within configured sync interval
  • Entity Mapping: All 6 entity types correctly mapped with annotations, tags, ownership, and relations
  • Tool Invocation: Developers can invoke MCP tools from Backstage entity pages with schema-driven forms and formatted results
  • A2A Agents: Developers can discover and interact with A2A agents via conversational interface in Backstage
  • MCP Bridge: AI assistants connected to Backstage's MCP endpoint can discover and invoke ContextForge tools
  • Gateway Management: Platform engineers can view gateway health, refresh capabilities, and register new gateways
  • Team Scoping: ContextForge team visibility is respected through Backstage group ownership mapping
  • RBAC: Backstage permissions correctly gate access to ContextForge operations
  • Observability: Audit logs, metrics, and plugin violation data visible from Backstage dashboard
  • Performance: Sync <30s for 500 entities; invocation overhead <100ms
  • Testing: Unit, integration, and compatibility tests pass across supported Backstage versions
  • Documentation: Installation guide, user guide, administrator guide, and ADR complete

🏁 Definition of Done

  • Three npm packages published: @contextforge/backstage-plugin, @contextforge/backstage-plugin-backend, @contextforge/backstage-plugin-catalog-module
  • Catalog entity provider syncs all 6 entity types with delta detection
  • Backend proxy routes handle tool invocation, agent invocation, gateway management, and audit queries
  • MCP Actions bridge registers ContextForge tools as Backstage actions
  • Frontend plugin provides: tool invocation card, agent chat, gateway management, observability dashboard
  • Identity mapping bridges Backstage users/groups to ContextForge users/teams
  • Backstage permission integration gates ContextForge operations
  • ContextForge-side endpoints for webhook notifications and pre-formatted catalog export
  • Token exchange endpoint eliminates static shared secrets
  • Unit tests for backend and frontend with >80% coverage
  • Integration tests for full sync cycle, tool invocation, and MCP client compatibility
  • Tested against Backstage v1.40+ and current ContextForge release
  • Installation, user, and administrator documentation complete
  • Architecture Decision Record documented
  • Code passes lint, format, and type checks for all packages
  • Security review completed (no credential leakage, input validation, CORS)
  • Published to npm with Backstage compatibility badges

πŸ“ Additional Notes

πŸ”Ή Backstage MCP Ecosystem Context:

  • Backstage v1.40+ ships @backstage/plugin-mcp-actions-backend β€” exposes Backstage actions as MCP tools via Streamable HTTP/SSE
  • Spotify Portal (commercial) registers MCP servers as kind: API with spec.type: mcp-server
  • Community MCP Registry proposal (#4034) is open but inactive
  • Red Hat Developer Hub has shipped basic MCP integration
  • No A2A protocol support exists anywhere in the Backstage ecosystem

πŸ”Ή Why Not Just Use Backstage's Built-In MCP Plugin?:

  • Backstage's MCP plugin exposes Backstage actions as tools β€” it does not federate external MCP servers
  • It has no concept of upstream gateways, multi-transport proxying, or tool governance
  • It cannot discover or aggregate tools from multiple MCP server instances
  • It has no plugin chain (PII filtering, rate limiting, content moderation) for tool invocations
  • It has no A2A agent support
  • ContextForge fills these gaps while Backstage provides the developer portal experience

πŸ”Ή Entity Mapping Rationale:

  • Tools, resources, and prompts map to kind: API because they are interfaces that components consume β€” consistent with Backstage's system model where APIs are "boundaries between components"
  • Servers, gateways, and A2A agents map to kind: Component because they are running software that provides APIs
  • spec.type uses mcp-tool, mcp-resource, mcp-prompt, mcp-server, mcp-gateway, a2a-agent β€” prefixed for namespace clarity

πŸ”Ή Sync Strategy:

  • Phase 1 uses polling (configurable interval, default 5 minutes) for simplicity
  • Phase 6 adds webhook-driven sync for real-time updates
  • Delta detection prevents catalog churn (entities only updated when changed)
  • Tombstone handling: disabled or deleted ContextForge entities are removed from catalog

πŸ”Ή Security Considerations:

  • ContextForge bearer tokens must be stored as environment variable references, never inline
  • Backend plugin proxies all requests β€” frontend never contacts ContextForge directly
  • Token exchange (Phase 6) eliminates long-lived shared secrets
  • Tool invocation audit trail maintained in ContextForge regardless of entry point (direct API, Backstage, MCP client)

πŸ”Ή Future Enhancements:

  • Backstage Scaffolder Integration: Generate catalog-info.yaml with ContextForge annotations from software templates
  • TechDocs Integration: Auto-generate tool/agent documentation pages from ContextForge metadata
  • Cost Attribution: Surface ContextForge tool invocation costs alongside cloud spend in Backstage cost dashboards
  • Backstage Search Integration: Index ContextForge tools and agents in Backstage's federated search
  • Event-Driven Architecture: Replace polling with CloudEvents for sub-second sync
  • Multi-Instance Support: Connect multiple ContextForge gateways from a single Backstage instance
  • ContextForge Plugin for Backstage Catalog: A ContextForge plugin that reads Backstage catalog and auto-registers Backstage components as ContextForge resources

πŸ”— Related Issues


πŸ“š References

Metadata

Metadata

Assignees

No one assigned

    Labels

    SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releasea2aSupport for A2A protocolenhancementNew feature or requestepicLarge feature spanning multiple issuesfrontendFrontend development (HTML, CSS, JavaScript)mcp-protocolAlignment with MCP protocol or specificationpluginspythonPython / backend development (FastAPI)typescriptTypeScript programming language

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions