# Roadie - fully customizable Context Layer & Internal Developer Portal built on Backstage > Roadie is a customizable Context Layer & Internal Developer Portal with scorecards, self-service workflows, and actionable insights. This file contains the full content of key pages for LLM consumption. For a lighter index of all pages, see [/llms.txt](/llms.txt). ## Documentation ### [Authorization of the API](https://roadie.io/docs/api/authorization.md) Roadie supports two types of API tokens: **User Tokens** and **Service Tokens**. Both use bearer token authentication and provide the same API access. ## User Tokens User tokens are tied to your personal Roadie account. They're ideal for local development, personal scripts, and MCP server connections from your IDE. ### Prerequisites You need to have the "Roadie API Key Access" policy assigned to your user in Roadie to create a user token. ### Generate a User Token 1. Go to **Administration → Account** 2. Navigate to the **Roadie API Access** section 3. Add a token description 4. Click **Generate Token** 5. Copy and store the token securely — it won't be shown again ## Service Tokens Service tokens are not tied to any individual user account. They're designed for automated systems like CI/CD pipelines, shared integrations, and team tooling where you don't want the token to depend on a specific person's account. ### Generate a Service Token 1. Go to **Administration → Service Tokens** 2. Click **Create Service Token** 3. Add a description for the token 4. Click **Generate** 5. Copy and store the token securely — it won't be shown again ## Using Your Token ```shell curl \ -X GET \ -H 'Accept: application/json' \ -H "Authorization: bearer ${ROADIE_API_TOKEN}" \ https://api.roadie.so/api/catalog/entities ``` For write operations using PUT, POST, or PATCH requests with a request body, we expect a JSON structure. You should modify your calls to include the `Content-Type` header. ```shell curl \ -X POST \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -H "Authorization: bearer ${ROADIE_API_TOKEN}" \ -d '{ "key": "value" }' https://api.roadie.so/api/catalog/fragments ``` Both user tokens and service tokens work identically in API requests. --- ### [Entity Push API](https://roadie.io/docs/api/entity-push-api.md) # Catalog your AWS accounts In this tutorial we are going to show you how to ingest your organization's AWS accounts into your Roadie catalog as Resource entities. For this we will use Roadie's Entity Push API. You can check out the API docs [here](/docs/api/catalog/) in the Roadie Provider section. This tutorial will hopefully serve as an example around how you might apply this same pattern to other cloud providers or other resources that you cannot currently manage with the providers available with Roadie out of the box. ## Authentication First to be able to use the Roadie entity push API we will need to get an authentication token. You can generate your own token by going to the `Administration` -> `Account` (`/administration/account`) page. Here go to the `Roadie API Access` section. Give a name to your token and press the `GENERATE TOKEN` button. Make sure you copy your token and put it in a secure place. You can test out your token by hitting the api. For example: ```bash curl \ -X GET \ -H 'Accept: application/json' \ -H "Authorization: bearer ${ROADIE_API_TOKEN}" \ https://api.roadie.so/api/catalog/entities ``` ## Fetch your AWS accounts Using the AWS CLI make sure you have it setup and configured. You can read more [here](https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-welcome.html) ```bash aws organizations list-accounts ```
Errors If you encounter the following error make sure you have the proper permissions configured for yourself and check if you are using your correct AWS_PROFILE `An error occurred (AccessDeniedException) when calling the ListAccounts operation: You don't have permissions to access this resource.`
This will result in a response like ```json { "Accounts": [ { "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111", "JoinedMethod": "INVITED", "JoinedTimestamp": 1481830215.45, "Id": "111111111111", "Name": "Master Account", "Email": "bill@example.com", "Status": "ACTIVE" }, { "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/222222222222", "JoinedMethod": "INVITED", "JoinedTimestamp": 1481835741.044, "Id": "222222222222", "Name": "Production Account", "Email": "alice@example.com", "Status": "ACTIVE" }, { "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333", "JoinedMethod": "INVITED", "JoinedTimestamp": 1481835795.536, "Id": "333333333333", "Name": "Development Account", "Email": "juan@example.com", "Status": "ACTIVE" }, { "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/444444444444", "JoinedMethod": "INVITED", "JoinedTimestamp": 1481835812.143, "Id": "444444444444", "Name": "Test Account", "Email": "anika@example.com", "Status": "ACTIVE" } ] } ``` Now you can use either this list directly and send the data into the Roadie Catalog via your preferred way, using plain curl command or any programming language you prefer. In the next section I'll show you a full example with node.js. ### Listing the accounts and sending the entities to Roadie - We will use the official AWS JavaScript SDK. Make sure you have it available in your system - Make sure you have your `ROADIE_API_TOKEN` available in your shell - Make sure you are authenticated towards your AWS. - Make sure you are using your correct `AWS_PROFILE` We are going to fetch the available AWS accounts and then pick the data we want to put in the Resource entities and finally send these into Roadie. We are going to use the `PUT /api/catalog/roadie-entities/sets/${setId}` endpoint. To use this we have to provide a set id, which should be something descriptive. This provides the ability to issue subsequent requests towards the same set id and it will update all of the entities provided in the request body. This performs a full mutation, every entity in the set will be replaced by the new incoming entities in the new requests. If you would like to remove some of the entities provided in this set you will need to issue a new request without the entity you want to delete, so the whole set will be replaced by the new array of entities you send to Roadie. ```bash npm i @aws-sdk/client-organizations ``` In this example I'll use the native `node:https` package, this can be substituted by your preferred way of making an http request. (axios, node-fetch, etc..) ```js const https = require('node:https'); const { OrganizationsClient, ListAccountsCommand } = require('@aws-sdk/client-organizations'); const client = new OrganizationsClient(); const command = new ListAccountsCommand({}); const response = client.send(command); response.then((r) => { const accounts = r.Accounts; if (!accounts) { throw new Error('No AWS Accounts found'); } const templateResourceEntity = ({ name, arn }) => ({ apiVersion: 'backstage.io/v1alpha1', kind: 'Resource', metadata: { name, description: 'AWS accounts', annotations: { 'aws-account/arn': arn, }, }, spec: { owner: 'dx-team', type: 'aws-account', }, }); const entities = accounts.map((a) => templateResourceEntity({ name: a.Name, arn: a.Arn })); const body = JSON.stringify({ items: entities }); const req = https.request( { hostname: 'api.roadie.so', port: 443, path: '/api/catalog/roadie-entities/sets/aws-accounts', method: 'PUT', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body), Authorization: `bearer ${process.env.ROADIE_API_TOKEN}`, }, }, (res) => { res.on('data', (chunk) => { console.log(chunk); }); } ); req.on('error', (e) => { console.log(e); }); req.write(body); req.end(); }); ``` You will see the following response body on a successful request: ```json { "set": "aws-accounts", "items": [ { "id": "cf71aba4-c2c5-4ba8-b274-c94c097d74be", "entity": { "kind": "Resource", "spec": { "type": "aws-account", "owner": "dx-team" }, "metadata": { "name": "development", "annotations": { "update-me": "me", "aws-account/arn": "arn", "roadie.io/entity-set": "aws-accounts", "backstage.io/managed-by-location": "roadie-api:/api/catalog/roadie-entities/entities/by-ref/resource%3Adefault%2Fdevelopment", "backstage.io/managed-by-origin-location": "roadie-api:/api/catalog/roadie-entities/entities" }, "description": "AWS accounts" }, "apiVersion": "backstage.io/v1alpha1" }, "entityRef": "resource:default/development", "rawData": { "kind": "Resource", "spec": { "type": "aws-account", "owner": "dx-team" }, "metadata": { "name": "development", "annotations": { "update-me": "me", "aws-account/arn": "arn", "roadie.io/entity-set": "aws-accounts", "backstage.io/managed-by-location": "roadie-api:/api/catalog/roadie-entities/entities/by-ref/resource%3Adefault%2Fdevelopment", "backstage.io/managed-by-origin-location": "roadie-api:/api/catalog/roadie-entities/entities" }, "description": "AWS accounts" }, "apiVersion": "backstage.io/v1alpha1" }, "set": "aws-accounts", "updatedBy": "user:default/guest", "source": "api-entity", "updatedAt": "2024-02-16T11:26:16.685+00:00" } ] } ``` Go to your catalog page (`Catalog` -> `Resource`) and you will immedietly see these `Resource` entities in your catalog. ## Keep it syncing To continuously update your catalog with the changes in your AWS accounts you will need to run this script on a schedule. I advise you to use your organization's best practice to run these scheduled jobs. Alternatively you can use the pull based `roadie-agent` library if you want Roadie to automatically schedule pulling these entities from your developed Roadie Agent service. Regardless how it will run you will need to be sure that environment has the correct tokens to be able to fetch from your organization's AWS and to be able to push to your Roadie API. Do not forget to configure your `ROADIE_API_TOKEN` and your `AWS_PROFILE`. --- ### [Roadie API & MCP Servers](https://roadie.io/docs/api/overview.md) ## Overview Roadie provides both a REST API and Model Context Protocol (MCP) servers to read and write information from a Roadie instance. These enable you to integrate Roadie with your existing tools, automate workflows, and build custom integrations. ## Roadie API The Roadie API provides programmatic access to your Backstage catalog and other Roadie features. You can use it to automate catalog management, integrate with CI/CD pipelines, or build custom tooling. Some uses of the API include: - **Catalog management** - Create, update, and delete entities in your catalog from external systems - **Entity sets** - Manage batches of entities idempotently, perfect for syncing resources from internal systems - **Tech Insights** - Access fact data and scorecard results programmatically To get started with the API, you'll need to [generate an API token](/docs/api/authorization/). ### API Base URL ``` https://api.roadie.so/api/ ``` ### Example: List catalog entities ```bash curl \ -X GET \ -H 'Accept: application/json' \ -H "Authorization: bearer ${ROADIE_API_TOKEN}" \ https://api.roadie.so/api/catalog/entities ``` For more details, see the [API Authorization](/docs/api/authorization/) documentation and the specific API documentation for [Catalog](/docs/api/catalog), [Tech Insights](/docs/api/techinsights), [Templates](/docs/api/templates), and [Plugins](/docs/api/plugins). ## MCP Server(s) You can also connect to your Roadie instance via an LLM client of your choice (provided it supports third party MCP servers). [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) enables AI assistants to interact with your Backstage catalog using structured data. Some uses of the MCP servers include: - **AI-powered catalog exploration** - Ask natural language questions about your software catalog and/or allow Agents to access rich metadata about your software. - **Automated scaffolding** - find, validate, and execute scaffolder templates - **Security and compliance insights** - Query vulnerability data, branch protection status, and compliance metrics - **Documentation search** - Search and retrieve TechDocs content across your catalog - **Catalog decoration** - Manage entity fragments and decorators via AI assistants ### Available MCP Servers | Server | Description | Endpoint | | ---------------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------ | | [API Docs Query](/docs/api/roadie-mcp/api-docs-query/) | Discover and retrieve API documentation and specifications | `https://api.roadie.so/api/mcp/v1/api-docs-query` | | [Backend Config](/docs/api/roadie-mcp/backend-config/) | Manage proxy settings and secrets | `https://api.roadie.so/api/mcp/v1/backend-config` | | [Catalog Decorators](/docs/api/roadie-mcp/catalog-decorators/) | Manage catalog entity decorators and fragments | `https://api.roadie.so/api/mcp/v1/catalog-decorators` | | [Rich Catalog Entity](/docs/api/roadie-mcp/rich-catalog-entity/) | Access catalog entity data, relationships, and documentation | `https://api.roadie.so/api/mcp/v1/rich-catalog-entity` | | [Scaffolder](/docs/api/roadie-mcp/scaffolder/) | Find, validate, and execute scaffolder templates | `https://api.roadie.so/api/mcp/v1/scaffolder-use` | | [Tech Insights Facts](/docs/api/roadie-mcp/tech-insights-facts/) | Access operational metrics, security data, and compliance information | `https://api.roadie.so/api/mcp/v1/tech-insights-facts` | ### Supported AI Tools MCP servers work with popular AI development tools including: - **VS Code with Copilot** - **Cursor IDE** - **Claude Desktop** For detailed setup instructions, see the [Roadie MCP Getting Started](/docs/api/roadie-mcp/) documentation. ## Authentication Both the REST API and MCP servers use bearer token authentication. Roadie supports two types of API tokens: ### User Tokens User tokens are tied to your personal Roadie account. Use these for: - Local development and testing - Personal scripts and automation - MCP server connections from your IDE To generate a user token: **Administration → Account → Roadie API Access** ### Service Tokens Service tokens are not tied to any individual user. Use these for: - CI/CD pipelines - Automated systems and integrations - Shared tooling across teams To generate a service token: **Administration → Service Tokens** See [API Authorization](/docs/api/authorization/) for detailed setup instructions. --- ### [Roadie MCP AI Servers (Beta)](https://roadie.io/docs/api/roadie-mcp.md) ## Introduction Roadie exposes a number of [Model Context Protocol Servers (MCP)](https://modelcontextprotocol.io/introduction) via our authenticated API that can provide AI tools like agents and LLMs with structured data to answer complex questions about your catalog and powerful workflow capabilities using the scaffolder. ## Available MCP Servers Roadie currently provides six MCP servers that enable AI assistants to interact with your Backstage catalog: - **[API Docs Query Server](api-docs-query)** - Discover and retrieve API documentation and specifications - https://api.roadie.so/api/mcp/v1/api-docs-query - **[Backend Config Server](backend-config)** - Manage and query backend configuration including proxy settings and secrets - https://api.roadie.so/api/mcp/v1/backend-config - **[Catalog Decorators Server](catalog-decorators)** - Manage catalog entity decorators and fragments - https://api.roadie.so/api/mcp/v1/catalog-decorators - **[Rich Catalog Entity Server](rich-catalog-entity)** - Access catalog entity data, relationships, and documentation - https://api.roadie.so/api/mcp/v1/rich-catalog-entity - **[Scaffolder Server](scaffolder)** - Find, validate, and execute Backstage scaffolder templates - https://api.roadie.so/api/mcp/v1/scaffolder-use - **[Tech Insights Facts Server](tech-insights-facts)** - Access operational metrics, security data, and compliance information - https://api.roadie.so/api/mcp/v1/tech-insights-facts ## Managing MCP Servers Administrators can enable or disable individual MCP servers from the Roadie administration screen. This allows you to control which servers are available to users in your organization. To disable or enable an MCP server: 1. Go to **Administration**, then **Integrations & Plugins**, then **MCP Servers** 2. Toggle the specific MCP servers you want to enable or disable 3. Disabled servers will no longer accept connections or respond to requests This can be useful for limiting the surface area of AI interactions. For example, disabling the Scaffolder server if you don't want AI assistants to execute templates. ## Prerequisites - Roadie tenant with populated catalog - Active Roadie API token - AI assistant or MCP client configured to use Roadie's MCP servers ## Tool Integration Setup ### Setting up MCP Servers in Popular AI Tools
VS Code with Copilot VS Code supports [MCP servers](https://code.visualstudio.com/docs/copilot/chat/mcp-servers). Here's how to configure Roadie's for use with Copilot: #### Configure MCP Servers Add the following configuration to your settings (`~/.vscode/mcp.json`): ```json { "servers": { "roadie-api-docs": { "url": "https://api.roadie.so/api/mcp/v1/api-docs-query", "headers": { "Authorization": "Bearer " } }, "roadie-backend-config": { "url": "https://api.roadie.so/api/mcp/v1/backend-config", "headers": { "Authorization": "Bearer " } }, "roadie-catalog-decorators": { "url": "https://api.roadie.so/api/mcp/v1/catalog-decorators", "headers": { "Authorization": "Bearer " } }, "roadie-scaffolder": { "url": "https://api.roadie.so/api/mcp/v1/scaffolder-use", "headers": { "Authorization": "Bearer " } }, "roadie-catalog": { "url": "https://api.roadie.so/api/mcp/v1/rich-catalog-entity", "headers": { "Authorization": "Bearer " } }, "roadie-insights": { "url": "https://api.roadie.so/api/mcp/v1/tech-insights-facts", "headers": { "Authorization": "Bearer " } } } } ``` #### Get Your API Token 1. Log into your Roadie instance 2. Go to Settings → API Keys 3. Create a new API key with appropriate permissions 4. Replace `` with your actual token #### Check your Settings - In settings, ensure `chat.mcp.enabled` is set to `enabled`. - Occassionally your organisation will manage these settings (you will see something like "managed by organization" next to a given setting). If this is the case and `chat.mcp.enabled` is not set to enabled you will need to talk to whomever manages those settings. #### Test the Integration Open VS Code and try asking Copilot questions like: - "What APIs are available for user management?" - "Who owns the payment-service component?" - "Create a fragment to add team ownership to the auth-service" #### Skipping steps - VSCode omits some information-only steps and/or auto-completes various actions our MCP tools request. That is due to a permissive interpretation of the protocols `readOnlyHint: true` flag, which is best practice to use on MCP servers [based on the protocol specification](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations). The flag represents non-destructive tools which only return information and do not alter the MCP clients environment. VSCode interprets `readOnlyHints` as default permissable to execute, whereas most other MCP clients require user consent or a flag to be set in config before they autocomplete. - More information can be found here [https://code.visualstudio.com/updates/v1_100#\_mcp-tool-annotations](https://code.visualstudio.com/updates/v1_100#_mcp-tool-annotations)
Cursor IDE Cursor supports MCP servers through its AI integration. Here's the setup: #### Configure MCP Servers Create or edit your Cursor MCP configuration file (`.cursor/mcp.json` in your project or home directory): ```json { "mcpServers": { "roadie-api-docs": { "url": "https://api.roadie.so/api/mcp/v1/api-docs-query", "headers": { "Authorization": "Bearer " } }, "roadie-backend-config": { "url": "https://api.roadie.so/api/mcp/v1/backend-config", "headers": { "Authorization": "Bearer " } }, "roadie-catalog-decorators": { "url": "https://api.roadie.so/api/mcp/v1/catalog-decorators", "headers": { "Authorization": "Bearer " } }, "roadie-scaffolder": { "url": "https://api.roadie.so/api/mcp/v1/scaffolder-use", "headers": { "Authorization": "Bearer " } }, "roadie-catalog": { "url": "https://api.roadie.so/api/mcp/v1/rich-catalog-entity", "headers": { "Authorization": "Bearer " } }, "roadie-insights": { "url": "https://api.roadie.so/api/mcp/v1/tech-insights-facts", "headers": { "Authorization": "Bearer " } } } } ``` #### Restart Cursor After configuring the MCP servers, restart Cursor to load the new configuration. #### Test Integration Use Cursor's AI chat to test the integration: - "Show me security metrics for user-service" - "What scaffolder templates are available?" - "Find APIs related to payment processing" - "List all fragments for the payment-service component"
Claude Desktop (Anthropic) Claude Desktop supports MCP servers natively: #### Configure MCP Servers Edit your Claude Desktop configuration file (`~/.config/claude-desktop/claude_desktop_config.json`): ```json { "mcpServers": { "roadie-api-docs": { "url": "https://api.roadie.so/api/mcp/v1/api-docs-query", "headers": { "Authorization": "Bearer " } }, "roadie-backend-config": { "url": "https://api.roadie.so/api/mcp/v1/backend-config", "headers": { "Authorization": "Bearer " } }, "roadie-catalog-decorators": { "url": "https://api.roadie.so/api/mcp/v1/catalog-decorators", "headers": { "Authorization": "Bearer " } }, "roadie-scaffolder": { "url": "https://api.roadie.so/api/mcp/v1/scaffolder-use", "headers": { "Authorization": "Bearer " } }, "roadie-catalog": { "url": "https://api.roadie.so/api/mcp/v1/rich-catalog-entity", "headers": { "Authorization": "Bearer " } }, "roadie-insights": { "url": "https://api.roadie.so/api/mcp/v1/tech-insights-facts", "headers": { "Authorization": "Bearer " } } } } ``` #### Restart Claude Desktop Restart the application to load the new MCP server configuration. #### Test Functionality Test with queries like: - "What documentation exists for auth-service?" - "Show me GitHub metrics for all payment services" - "Add monitoring annotations to the user-service component"
### Authentication Setup You will need an API token for your user to connect with these MCP servers. See [API Token docs here](/docs/api/authorization/). You may need an admin user to provide you with a Roadie API Token. ### Troubleshooting Setup **Common Issues:** 1. **Authentication Errors**: - Verify your API token is correct and not expired - Check that the token has appropriate permissions 2. **Connection Failures**: - Verify network connectivity to your Roadie instance - Check that the MCP API endpoints are accessible 3. **Permission Denied**: - Review your API token permissions - Contact your Roadie administrator for access 4. **MCP Server Configuration Issues**: - Verify the URL format is correct: `https://api.roadie.so/api/mcp/v1/` - Check that all required headers are included in the configuration - Ensure environment variables are properly set 5. **Global IDE Settings can Block MCP Server Access**: - Verify that access to remote authenticated MCP servers is enabled. For example, in VSCode the setting `chat.mcp.enabled` should be set to `enabled`. - Occassionally your organisation will manage these settings and if they are not enabled you will need to talk to your support team or whomever manages those settings. For example, in VSCode you will see something like "managed by organization". ## Best Practices ### API Discovery - Start with broad search terms and refine based on results ### Template Execution - Always validate inputs before execution to catch errors early - Provide clear, descriptive names for generated projects ### Error Handling - Check validation results before proceeding with template execution - Monitor task status for long-running templates - Review error messages for troubleshooting guidance - Ensure proper permissions are in place before execution ## Support and Troubleshooting ### Common Issues **Authentication Errors** - Verify your Roadie API credentials are configured correctly - Ensure your MCP client is properly authenticated **Permission Denied** - Check that you have the necessary permissions for catalog access and scaffolder execution - Contact your Roadie administrator if you need additional permissions **Template Execution Failures** - Use `validate-template-values` to check inputs before execution - Review template requirements and ensure all parameters are provided - Check `get-scaffolder-task` for detailed error information For additional support, please refer to the Roadie documentation or contact our support team. --- ### [API Docs Query Server](https://roadie.io/docs/api/roadie-mcp/api-docs-query.md) ## Overview The API Docs Query Server provides AI assistants with comprehensive access to your organization's API documentation and specifications stored in your Backstage catalog. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/api-docs-query` ## Capabilities - **API Discovery**: Search for APIs using natural language queries - **Specification Retrieval**: Get complete OpenAPI, GraphQL, or AsyncAPI specifications - **Intelligent Search**: Find APIs by domain, technology, or business context - **Metadata Access**: Retrieve API descriptions, ownership, and categorization ## Available Tools ### Find API Specs Search for available API specifications using a query string that supports partial matching across API names, descriptions, and metadata. **Parameters:** - `queryString` (string): Search term for finding API specs **Example Usage:** ```json { "queryString": "payment" } ``` **Return Schema:** ```typescript { results: { type: string, document: { kind: string, text: string, type: string, owner: string, title: string, keywords: string, location: string, lifecycle: string, namespace: string, componentType: string } }[] } ``` This will return all APIs related to payments, including services like "payment-gateway", "payment-processor", or "billing-api". ### Retrieve API Spec Get the complete specification for a specific API, including full OpenAPI/Swagger definitions, schemas, and endpoint documentation. **Parameters:** - `name` (string): API name - `namespace` (string, optional): API namespace (defaults to "default") **Example Usage:** ```json { "name": "user-service-api", "namespace": "backend" } ``` **Return Schema:** ```typescript { entityRef: string, spec: string } ``` #### Required Permissions - **Catalog entity read (\*)** - Access to catalog entities and API specifications ## Common Use Cases ### API Integration Planning - Ask your AI assistant: "What payment APIs are available?" - Get detailed endpoint information for integration planning - Compare different APIs to choose the best fit ### Documentation Exploration - "Show me the schema for creating a user account" - "What authentication does the order API require?" - "List all the endpoints in the inventory service" ### Development Assistance - Generate client code from API specifications - Create automated tests based on API schemas - Validate API requests and responses ## Examples ### Example AI Conversation **User:** "I need to integrate with our user management system" **AI Response using MCP:** 1. Searches for user-related APIs using `find-api-specs` 2. Retrieves specifications for relevant APIs 3. Explains available endpoints, authentication, and schemas 4. Provides integration guidance and code examples ### Practical Usage ```json // Finding payment-related APIs { "tool": "find-api-specs", "arguments": { "queryString": "payment processing" } } // Getting complete specification { "tool": "retrieve-api-spec", "arguments": { "name": "payment-gateway-api", "namespace": "payments" } } ``` ## Best Practices - Start with broad search terms and refine based on results - Use domain-specific language (e.g., "payment", "authentication", "notification") - Check multiple namespaces if APIs aren't found in default - Review complete specifications before starting integration --- ### [Backend Config Server](https://roadie.io/docs/api/roadie-mcp/backend-config.md) ## Overview The Backend Config Server provides specialized MCP tools for managing and querying backend configuration in Roadie. It focuses on administrative tasks like proxy configuration. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/backend-config` ## Capabilities - **Proxy Configuration Management**: List, create, and update proxy configurations for external service access - **Secrets Management**: List available secrets that can be used in proxy configurations ## Available Tools ### Get Proxy Config List Retrieve the current proxy configuration from the app-config plugin, including both custom proxy entries and default proxy entries. **Parameters:** - `random_string` (string): Dummy parameter for no-parameter tools **Example Usage:** ```json { "random_string": "dummy" } ``` **Returns:** List of configured proxy routes including: - Both custom proxy entries and default proxy entries - Proxy paths, targets, and advanced settings like headers and methods #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Backend config read** - Access to backend configuration ### Create Proxy Config Create or update proxy entries in Roadie for secure access to external services from the Roadie backend using secrets stored in Roadie for authentication if necessary. **Parameters:** - `proxies` (array): Array of proxy configurations with path, target, and optional advanced settings **Example Usage:** ```json { "proxies": [ { "path": "/github", "target": "https://api.github.com", "advancedSettings": { "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }, "allowedMethods": ["GET", "POST"] } } ] } ``` **Proxy Configuration Schema:** ```typescript { proxies: { path: string, // Path at which the proxy is mounted (must start with /) target: string, // Target URL for the proxy advancedSettings?: { allowedHeaders?: string[], allowedMethods?: string[], changeOrigin?: boolean, headers?: Record, noHeaders?: boolean, noMethods?: boolean, pathRewrite?: Record, target?: string } }[] } ``` #### Required Permissions: - **Backend config write** - Permission to create and update backend configuration ### Get Secrets List Retrieve the list of available secrets that can be used in proxy configurations and other backend integrations. **Parameters:** - `random_string` (string): Dummy parameter for no-parameter tools **Example Usage:** ```json { "random_string": "dummy" } ``` **Returns:** List of available secrets including: - Secret names that can be referenced in proxy configurations - Masked secret values (showing only last 4 characters for security) - Secret descriptions and usage information - Current status (Available, Updating, or Not Set) - Optional help URLs with additional information **Return Schema:** ```typescript { secrets: { name: string, // Secret name (e.g., "GITHUB_TOKEN") value: string, // Hidden value showing only last 4 characters description?: string, // Description of what the secret is for status: 'Available' | 'Updating' | 'Not Set', // Current status of the secret helpUrl?: string // Optional URL with help information for this secret }[] } ``` #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Backend config read** - Access to backend configuration and secrets ## Common Use Cases ### Proxy Management - "What backend proxies are configured in Roadie?" - "Show me the proxy configuration for my custom plugin" - "List all backend proxy endpoints in Roadie" ### Proxy Creation and Updates - "Create a proxy for the GitHub API at /github with target https://api.github.com" - "Add a proxy entry for my service at /my-service pointing to https://my-api.com" - "Set up a proxy with custom headers for authentication" - "Create multiple proxy entries for different external services" - "Update the Snyk proxy to only allow GET methods" ### Service Integration - "Add a proxy entry for Wiz security API" - "Configure a proxy for our internal monitoring service" - "Set up authenticated access to external documentation APIs" ### Secrets Management - "What secrets are available for use in proxy configurations?" - "List all available secrets in Roadie and their current status" - "Show me which secrets are configured and which need to be set" - "What authentication tokens can I use for my proxy setup?" - "Which secrets are currently updating or not set?" - "Show me help information for configuring specific secrets" ## Security Considerations ### Authentication and Secrets - Proxy routes allow secure access to external services using secrets stored in Roadie - Authentication headers can reference stored secrets using `${SECRET_NAME}` syntax - Secrets are managed separately and securely in Roadie's secret management system ### Access Control - **Method Restrictions**: Configure allowed HTTP methods for security - **Header Control**: Specify allowed headers and custom authentication headers - **Path Management**: Control routing and path rewriting for security ### Best Practices for Secrets - Use `get-secrets-list` to discover available secrets and check their status before configuring proxies - Verify secrets show "Available" status rather than "Not Set" or "Updating" - Review masked values to confirm secrets contain expected data patterns - Always reference secrets using the `${SECRET_NAME}` syntax rather than hardcoding values - Utilize help URLs from the secrets list for service-specific configuration guidance - Test secret authentication manually before deploying proxy configurations - Regularly audit which secrets are being used in proxy configurations ## Example Workflows ### Setting Up External API Access **User:** "I need to integrate with the Travis API from my custom plugin" **AI Response using MCP:** 1. Uses `create-proxy-config` to set up a Travis API proxy 2. Configures authentication using stored Travis token 3. Sets appropriate method restrictions for security 4. Provides the proxy endpoint for plugin use ### Reviewing Current Configuration **User:** "What external services do we currently have proxies for?" **AI Response using MCP:** 1. Uses `get-proxy-config-list` to fetch all configured proxies 2. Analyzes proxy targets and paths 3. Identifies external services and their access patterns 4. Provides summary of current integrations ### Secrets Discovery and Configuration **User:** "I want to set up a proxy for GitHub API but I'm not sure what authentication tokens are available" **AI Response using MCP:** 1. Uses `get-secrets-list` to fetch all available secrets 2. Identifies GitHub-related secrets (e.g., `GITHUB_TOKEN`) 3. Checks secret status - whether they're Available, Updating, or Not Set 4. Shows masked values to confirm secrets are configured 5. Provides help URLs if available for additional setup guidance 6. Uses `create-proxy-config` to configure the proxy with the appropriate secret reference ## Advanced Configuration ### Headers and Authentication ```json { "path": "/external-api", "target": "https://api.external-service.com", "advancedSettings": { "headers": { "Authorization": "Bearer ${EXTERNAL_API_TOKEN}", "Content-Type": "application/json" }, "allowedMethods": ["GET", "POST"], "changeOrigin": true } } ``` ### Path Rewriting ```json { "path": "/legacy-api", "target": "https://new-api.service.com", "advancedSettings": { "pathRewrite": { "^/legacy-api": "/v2/api" } } } ``` ## Troubleshooting ### Common Issues 1. **Authentication Failures**: - Verify secret names match exactly (case-sensitive) - Ensure secrets are properly configured in Roadie - Ensure secrets like tokens work by testing them - Check header formatting and syntax 2. **Connection Issues**: - Verify target URLs are accessible from Roadie's infrastructure - Check for network restrictions or firewall rules 3. **Method Restrictions**: - Review `allowedMethods` configuration - Ensure required HTTP methods are included - Check if `noMethods` is incorrectly set to true 4. **Path Issues**: - Verify proxy paths start with `/` - Check for path conflicts with existing routes - Review `pathRewrite` rules for correctness 5. **Secrets Issues**: - Use `get-secrets-list` to verify secret names, status, and availability - Check that secrets show "Available" status rather than "Not Set" or "Updating" - Review masked values to confirm secrets contain data - Ensure secrets are properly set in Roadie (see [Setting Secrets](/docs/details/setting-secrets/)) - Check that secret references use the correct `${SECRET_NAME}` syntax - Use help URLs from the secrets list for service-specific setup guidance - Verify that secrets have the required permissions for the target service --- ### [Catalog Decorators Server](https://roadie.io/docs/api/roadie-mcp/catalog-decorators.md) ## Overview The Catalog Decorators Server provides MCP tools for managing catalog entity decorators/fragments in Roadie. It enables AI assistants to retrieve, create and update fragments that enhance catalog entities with additional metadata. Fragments are partial entity data that are "decorated" onto an existing entity in the catalog to enrich its metadata. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/catalog-decorators` ## Capabilities - **Fragment Discovery**: List all entity fragments or fragments for a specific entity - **Fragment Creation**: Create new fragments to decorate entities with additional metadata - **Fragment Updates**: Add and change data in existing fragments for an entity - **Entity Enhancement**: Add specifications, metadata, and other information to catalog entities ## Available Tools ### List Fragments Retrieve a list of all entity fragments with optional filtering capabilities. **Parameters:** - `entityRef` (string, optional): Filter fragments for a specific entity - `limit` (number, optional): Maximum number of results to return (default: 100) - `offset` (number, optional): Pagination offset for results (default: 0) **Example Usage:** ```json { "entityRef": "component:default/user-service", "limit": 20, "offset": 0 } ``` **Alternative Usage (List All):** ```json { "limit": 100 } ``` **Returns:** List of fragments including: - Fragment identifiers and metadata - Associated entity references - Fragment content and specifications - Creation and modification timestamps **Return Schema:** ```typescript { fragments: { id: string, // Fragment identifier entityRef: string, // Associated entity reference fragment: { metadata?: Record, // Additional metadata spec?: Record, // Specification data // Other fragment properties }, createdAt: string, // Creation timestamp updatedAt?: string // Last modification timestamp }[], total: number, // Total number of fragments available hasMore: boolean // Whether more results are available } ``` #### Required Permissions: - **Fragment entity read** - `roadie.entity-fragment.read` - Permission to view entity fragments ### Create Fragment Create a new fragment to decorate a catalog entity with additional metadata and specifications. **Parameters:** - `entityRef` (string): Target entity reference to decorate - `fragment` (object): Fragment data containing metadata and spec information **Example Usage:** ```json { "entityRef": "component:default/payment-service", "fragment": { "metadata": { "annotations": { "example.com/responsible-team": "payments-team", "example.com/deployment-strategy": "blue-green" }, "labels": { "tier": "critical", "environment": "production" } }, "spec": { "type": "something-new", "additionalConfig": { "monitoring": "enabled", "backup": "daily" } } } } ``` **Fragment Schema:** ```typescript { entityRef: string, // Target entity reference fragment: { metadata?: { annotations?: Record, // Additional annotations labels?: Record, // Additional labels tags?: string[], // Additional tags // Other metadata fields }, spec?: Record, // Custom specification data } } ``` **Returns:** Created fragment information including: - Fragment ID and entity reference - Confirmation of applied decorations - Any validation warnings or notes #### Required Permissions: - **Fragment entity create** - `roadie.entity-fragment.create` - Permission to create and modify entity fragments ## Common Use Cases ### Fragment Discovery and Management - "What fragments exist for the payment-service component?" - "List all fragments in the system" - "Find fragments that have been modified recently" ### Entity Enhancement - "Update the decription of the user-service to say ..." - "Add prometheus monitoring annotations to the user-service component" ### Bulk Operations and Analysis - "Show me all fragments that modify descriptions" - "List fragments that enhance entities with monitoring configurations" - "Find all custom specifications added to payment-related services" ## Fragment Use Cases ### Adding Team Responsibility Information ```json { "entityRef": "component:default/user-service", "fragment": { "metadata": { "annotations": { "roadie.io/responsible-team": "platform-team", "roadie.io/on-call-schedule": "https://pagerduty.com/schedules/platform" } } } } ``` ### Enhancing with Deployment Information ```json { "entityRef": "resource:default/payment-gateway", "fragment": { "metadata": { "labels": { "deployment-strategy": "canary", "release-cycle": "weekly" } }, "spec": { "deployment": { "replicas": 3, "strategy": "RollingUpdate" } } } } ``` ### Adding Monitoring and Observability ```json { "entityRef": "api:default/orders-api", "fragment": { "metadata": { "annotations": { "datadog.com/dashboard": "https://app.datadoghq.com/dashboard/orders-api", "prometheus.io/scrape": "true" }, "monitoring": { "alerts": ["high-error-rate", "high-latency"], "slos": [ { "name": "availability", "target": 99.9 } ] } }, "spec": {} } } ``` ## Example Workflows ### Entity Enhancement Workflow **User:** "I want to add team ownership information to all payment services" **AI Response using MCP:** 1. Uses `list-fragments` to find existing fragments for payment services 2. Identifies services that need team ownership information 3. Uses `create-fragment` to add responsible team annotations 4. Provides summary of enhanced entities and their new metadata ### Fragment Audit and Discovery **User:** "Show me all custom monitoring configurations added to our services" **AI Response using MCP:** 1. Uses `list-fragments` to retrieve all fragments 2. Filters fragments containing monitoring-related specifications 3. Analyzes monitoring patterns and configurations 4. Provides summary of monitoring setups across services ### Systematic Entity Decoration **User:** "Add deployment strategy labels to all components in the production namespace" **AI Response using MCP:** 1. Uses entity search to find all production components 2. Uses `list-fragments` to check existing decorations 3. Uses `create-fragment` to add deployment strategy information 4. Confirms successful application and provides summary ## Best Practices ### Fragment Design - **Specific Purpose**: Create fragments for specific enhancement purposes (monitoring, ownership, deployment info) - **Update the source YAML file if possible**: Fragments allow easier updates to entity data and allow updates to entities not defined in YAML, but its always preferable to update the source entity of it comes from a YAML file in an SCM. ### Entity Reference Management - **Precise References**: Use exact entity references (kind:namespace/name format) - **Validation**: Verify target entities exist before creating fragments - **Confirmation** Creating a fragment successfully does not mean it necessarily has been applied if there was an error. You can check if a Fragment was actually applied to an entity using the Get Entity MCP tool. ## Security Considerations ### Fragment Permissions - Fragment mutations requires appropriate write permissions of `roadie.entity-fragment.create` ### Data Validation - Fragment content is validated against entity schemas - Malformed fragments are rejected with clear error messages ## Troubleshooting ### Common Issues 1. **Permission Errors**: - Verify you have the relevant `roadie.entity-fragment.` permission - Ensure access to target entities before creating fragments 2. **Entity Reference Issues**: - Use exact entity reference format: `kind:namespace/name` - Verify target entities exist in the catalog - Check for typos in entity names or namespaces 3. **Validation Failures**: - Ensure fragment content follows expected schemas - Validate JSON structure and data types - Check that required fields are provided --- ### [Rich Catalog Entity Server](https://roadie.io/docs/api/roadie-mcp/rich-catalog-entity.md) ## Overview The Rich Catalog Entity Server provides AI assistants with comprehensive access to catalog entity data, relationships, and documentation from your Backstage instance. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/rich-catalog-entity` ## Capabilities - **Entity Information**: Get detailed metadata, ownership, lifecycle, and specifications - **Relationship Mapping**: Discover dependencies, provides relationships, and entity connections - **Documentation Access**: Search and retrieve TechDocs content associated with entities - **Entity Discovery**: Search and find entities when exact names are unknown - **Enhanced Error Handling**: Provides search suggestions when entities aren't found ## Available Tools ### Get Entity Info Retrieve basic entity information including name, description, owner, lifecycle stage, and metadata. **Parameters:** - `entityRef` (string): Entity reference (e.g., "component:default/my-service") **Example Usage:** ```json { "entityRef": "component:default/user-service" } ``` **Return Schema:** ```typescript { name: string, title?: string, description?: string, owner?: string, lifecycle?: string, type?: string, tags?: string[], annotations?: Record, labels?: Record, links?: Record[], namespace?: string, kind?: string } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities ### Get Entity Relationships Discover entity relationships including dependencies, what the entity provides, and connected services. **Parameters:** - `entityRef` (string): Entity reference **Example Usage:** ```json { "entityRef": "component:default/payment-service" } ``` **Return Schema:** ```typescript { // Core relationships ownedBy?: string, owner?: string, system?: string, domain?: string, // Dependencies dependsOn: string[], dependencyOf: string[], // API relationships providesApis: string[], apiProvidedBy: string[], consumesApis: string[], // Hierarchical relationships partOf: string[], hasPart: string[], subcomponentOf?: string, subdomainOf?: string, // Group/User relationships memberOf: string[], members: string[], parent?: string, parentOf: string[], children: string[], childOf: string[], // Management relationships managedBy: string[], manages: string[] } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities ### Get TechDocs Search and retrieve TechDocs documentation content for specific entities. **Parameters:** - `entityRef` (string): Entity reference - `query` (string, optional): Search term within the documentation **Example Usage:** ```json { "entityRef": "component:default/auth-service", "query": "authentication flow" } ``` **Return Schema:** ```typescript { totalPages: number, pages: { title: string, content: string, path: string, htmlViewPath: string }[] } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities and their docs ### Search Entities Discover and find entities when you don't know the exact entity name or want to explore available entities. **Parameters:** - `searchTerm` (string): Search term to find entities by name, title, or other attributes - `kind` (string, optional): Filter by entity kind (e.g., "component", "api", "system") - `namespace` (string, optional): Filter by specific namespace - `limit` (number, optional): Maximum number of results to return (default: 10) **Example Usage:** ```json { "searchTerm": "payment", "kind": "component", "limit": 5 } ``` **Return Schema:** ```typescript { totalFound: number, entities: { name: string, kind: string, namespace: string, title?: string, description?: string, owner?: string, lifecycle?: string, type?: string, tags?: string[], entityRef: string }[] } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities ### Search TechDocs Search TechDocs documentation content across all entities in the catalog to find relevant information without knowing which specific entity contains it. **Parameters:** - `searchQuery` (string): Search query to find documentation content across all entities - `pageLimit` (number, optional): Maximum number of results to return (default: 100) **Example Usage:** ```json { "searchQuery": "API design patterns", "pageLimit": 50 } ``` **Return Schema:** ```typescript { totalResults: number, results: { pageTitle: string, content: string, path: string, htmlViewPath: string, entityRef: string, entityKind: string, entityNamespace: string, entityName: string }[] } ``` **Usage Examples:** - "Find documentation about API design patterns for my organisation" - "What deployment patterns are used in my organisation" - "How is Kubernetes used in my organisation? Are there any best practices?" - "Search for security best practices in my organisation" - "How are database migrations done in my organisation?" **Key Benefits:** - Discovers relevant documentation across entities you might not know about - Useful when you don't know which specific entity contains the information - Helps find patterns and best practices documented across multiple services - Good for discovering related documentation in different teams/entities ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities and their documentation - **TechDocs read** - Access to technical documentation ### User Group Listing List users or groups and their relationships to understand organizational structure and team relationships. **Parameters:** - `entityType` (enum): Type of entities to list - "user" for User entities or "group" for Group entities - `namespace` (string, optional): Optional filter by namespace. This is typically the SCM organisation, especially in the case of users and groups - `limit` (number, optional): Maximum number of results to return (if not specified, returns all entities) **Example Usage:** ```json { "entityType": "user", "namespace": "platform", "limit": 50 } ``` **Return Schema:** ```typescript { totalFound: number, entityType: string, entities: { entityRef: string, memberOf?: string[], type?: string, parent?: string, children?: string[], members?: string[] }[] } ``` **Usage Examples:** - "Which users are part of more than one group" - "Are there any users not assigned to a group" - "List all engineering team members" - "Show me team hierarchies" - "List users in the platform namespace" **Key Benefits:** - Shows team membership relationships (users in groups, group hierarchies) - Provides organizational structure overview for answering team-related questions - Returns minimal fields to reduce payload size and improve performance - Helps understand team structure and user assignments ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities ## Common Use Cases ### Entity Exploration - "Who owns the user-service component?" - "What is the lifecycle stage of payment-api?" - "Show me the description and metadata for auth-service" ### Dependency Analysis - "What services does payment-service depend on?" - "Which components use the user-api?" - "Show me all the relationships for the auth-service" ### Documentation Discovery - "What documentation exists for the payment-service?" - "Search for authentication information in user-service docs" - "Show me the getting started guide for inventory-api" ### Entity Discovery - "Find entities related to payment processing" - "Search for all user management services" - "What APIs are available for authentication?" - "Show me all components owned by the backend team" - "Find systems in the platform namespace" ## Smart Entity Resolution The Rich Catalog Entity Server includes intelligent entity resolution that makes it more user-friendly: ### How It Works 1. **Exact Match First**: Attempts to find the entity using the exact reference provided 2. **Fallback Search**: If exact match fails, searches for entities with matching names 3. **Type Prioritization**: Prefers Component entities, then falls back to other types (API, Resource, System) 4. **Namespace Awareness**: When a namespace is specified, prioritizes entities in that namespace ### Benefits - **Flexible Queries**: Users don't need to know exact entity references - **Natural Language**: Works with common entity names used in conversation - **Context Awareness**: Understands common naming patterns and conventions - **Enhanced Discovery**: When entities aren't found, provides intelligent search suggestions - **Error Recovery**: Automatically suggests similar entities when exact matches fail ## Required Permissions - **Catalog entity read (\*)** - Access to all catalog entities - **TechDocs read** - Access to technical documentation (for TechDocs functionality) ## Example Workflows ### Entity Discovery Workflow **User:** "I need to understand our payment infrastructure" **AI Response using MCP:** 1. Uses `search-entities` to find all payment-related entities 2. Retrieves entity information for each discovered service 3. Maps relationships between payment components 4. Provides comprehensive overview of the payment ecosystem 5. Suggests related APIs and documentation for deeper exploration ### Dependency Analysis **User:** "What does the user-service depend on?" **AI Response using MCP:** 1. Uses `get-entity-relationships` to map all dependencies 2. Identifies direct and indirect dependencies 3. Explains the purpose of each dependency 4. Highlights potential impact of changes ## Best Practices - Use search functionality when you don't know exact entity names - Combine entity information with relationship data for comprehensive analysis - Leverage TechDocs search to find specific documentation topics - Use filters (kind, namespace) to narrow search results when needed --- ### [Scaffolder Server](https://roadie.io/docs/api/roadie-mcp/scaffolder.md) ## Overview The Scaffolder Server enables AI assistants to discover, validate, and execute Backstage scaffolder templates, automating project creation and code generation workflows. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/scaffolder-use` ## Capabilities - **Template Discovery**: Find available scaffolder templates using intelligent search - **Template Inspection**: Get detailed template specifications and requirements - **Input Validation**: Verify parameter values before template execution - **Template Execution**: Run templates with proper error handling and monitoring - **Status Monitoring**: Track execution progress and results ## Available Tools ### Find Scaffolder Templates Search for available scaffolder templates using queries that match template names, descriptions, and tags. **Parameters:** - `queryString` (string): Search term for finding templates **Example Usage:** ```json { "queryString": "react frontend" } ``` **Return Schema:** ```typescript { results: { type: string, document: { kind: string, text: string, type: string, owner: string, title: string, keywords: string, location: string, lifecycle: string, namespace: string, componentType: string } }[] } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog template entities ### Retrieve Scaffolder Template Get detailed information about a specific template, including parameters, steps, and requirements. **Parameters:** - `name` (string): Template name - `namespace` (string, optional): Template namespace (defaults to "default") **Example Usage:** ```json { "name": "microservice-template", "namespace": "platform" } ``` **Return Schema:** ```typescript { entityRef: string, spec: string } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog template entities ### Validate Template Values Check if your input values meet the template's parameter requirements before execution, preventing common errors. **Parameters:** - `templateRef` (string): Template reference (e.g., "template:default/my-template") - `values` (object): Parameter values to validate **Example Usage:** ```json { "templateRef": "template:default/react-app", "values": { "name": "my-new-app", "description": "A React application", "owner": "team-frontend" } } ``` **Return Schema:** ```typescript { valid: boolean, // Whether the values are valid errors: string[], // List of validation errors schema: Record // The template parameter schema } ``` ## Required Permissions - **Catalog entity read (\*)** - Access to catalog entities ### Run Scaffolder Template Execute a scaffolder template with the provided values and optional secrets. **Parameters:** - `templateRef` (string): Template reference - `values` (object): Required parameter values - `secrets` (object, optional): Secrets needed by the template - `skipValidation` (boolean, optional): Skip validation step **Example Usage:** ```json { "templateRef": "template:default/microservice", "values": { "name": "user-service", "description": "User management microservice", "owner": "backend-team", "database": "postgresql" }, "secrets": { "github_token": "ghp_xxx" } } ``` **Return Schema:** ```typescript { id: string, // The created task ID taskUrl: string // URL to monitor the task } ``` ## Required Permissions - **Scaffolder task create** - Allows the user to run scaffolder templates ### Get Scaffolder Task Monitor the status and progress of template execution. **Parameters:** - `id` (string): Task ID returned from template execution **Example Usage:** ```json { "id": "abc123def456" } ``` ## Required Permissions - **Scaffolder task read** - Allows a user to view scaffolder runs ## Common Use Cases ### Guided Project Creation - "Create a new React application for the frontend team" - "Set up a microservice with PostgreSQL database" - "Generate a new API service with authentication" ### Template Exploration - "What templates are available for Node.js services?" - "Show me the requirements for the mobile app template" - "What parameters does the library template need?" ### Automated Workflows - Validate inputs before execution to prevent failures - Execute templates with proper error handling - Monitor progress and provide status updates ## Required Permissions - **Catalog entity read (\*)** - Access to template definitions - **Scaffolder execute** - Permission to run templates and create projects ## Example Workflows ### Basic Template Execution 1. **Find a template**: Use `find-scaffolder-templates` to discover available templates 2. **Inspect the template**: Use `retrieve-scaffolder-template` to understand requirements 3. **Validate inputs**: Use `validate-template-values` to ensure your values are correct 4. **Run the template**: Use `run-scaffolder-template` to execute 5. **Monitor progress**: Use `get-scaffolder-task` to check execution status ### AI-Guided Project Creation **User:** "Create a new React frontend application" **AI Response using MCP:** 1. Searches for React templates using `find-scaffolder-templates` 2. Shows available templates and their requirements 3. Guides user through providing necessary parameters 4. Validates inputs using `validate-template-values` 5. Executes template using `run-scaffolder-template` 6. Monitors progress and reports results ## Best Practices - Always validate inputs before execution to catch errors early - Provide clear, descriptive names for generated projects - Include proper ownership and team information - Use secrets parameter for sensitive information like tokens - Monitor task status for long-running templates ## Security Considerations - All operations require proper authentication tokens - Template execution respects Roadie's permission model - Task monitoring is limited to tasks you have access to --- ### [Tech Insights Facts Server](https://roadie.io/docs/api/roadie-mcp/tech-insights-facts.md) ## Overview The Tech Insights Facts Server provides AI assistants with access to operational metrics, compliance data, and insights from your Backstage Tech Insights configuration. **Server Endpoint:** `https://api.roadie.so/api/mcp/v1/tech-insights-facts` ## Capabilities - **Data Source Discovery**: Dynamically discover available Tech Insights data sources and their fact schemas - **GitHub Metrics**: PR merge times, repository activity, contributor information, branch protection settings, code review policies - **Security Metrics**: Vulnerability data from Snyk, Dependabot alerts, branch protection status - **Monitoring Data**: PagerDuty incident metrics, mean time to resolve, Datadog SLO and monitor counts - **Compliance Scoring**: Entity metadata completeness, ownership verification, TechDocs configuration - **Repository Analysis**: File structure analysis, catalog status, codebase composition - **Custom Facts**: Access any configured Tech Insights data source for specialized metrics - **Bulk Operations**: Query facts across all entities from specific data sources with filtering ## Available Tools ### Get Data Source Discovery Discovers available Tech Insights data sources and the fact data they provide. **Parameters:** - None required **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-data-source-discovery", "arguments": {} }, "id": 1 }' ``` **Return Schema:** ```typescript { dataSources: Array<{ id: string, title: string, description?: string, cadence?: string, lifecycle?: any, createdAt?: string, updatedAt?: string, handlerDefinition?: { type: 'builtin' | string, config: { id: string, builtinId?: string } }, timeout?: any, draft?: boolean, version?: string, entityFilter?: any, schema?: Record }>, totalCount: number, builtinCount: number, customCount: number } ``` **Workflow:** This tool helps you understand what data sources are available and what facts they provide: 1. Call `get-data-source-discovery` to retrieve all available data sources 2. Receive a list of all data sources with their IDs, titles, descriptions, and fact schemas 3. Use the data source IDs to query specific facts using `get-entity-facts` or `get-all-entities-facts` **Usage Examples:** - "What data sources are available?" - "What facts can I query about Rootly incidents?" - "Show me the facts available for components in the catalog" - "What is the average time to resolve for Rootly incidents on my-component?" **Required Permissions:** - **Catalog entity read (*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get Entity Facts Gets Tech Insights facts for a specific data source and entity combination. **Parameters:** - `dataSourceId` (string): The ID of the data source to query facts from - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-entity-facts", "arguments": { "dataSourceId": "github-stats", "name": "user-service" } }, "id": 1 }' ``` **Example Usage with Full Parameters:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-entity-facts", "arguments": { "dataSourceId": "1234", "name": "payment-api", "namespace": "acmeinc", "kind": "api" } }, "id": 1 }' ``` **Return Schema:** ```typescript { dataSourceId: string, dataSourceTitle?: string, entityRef: string, facts: Record, timestamp?: string } ``` **Workflow:** Get facts for a specific entity from a data source: 1. First, use the data source discovery tool to find available data sources and their IDs 2. Call `get-entity-facts` with the data source ID and entity information 3. Receive all raw facts from that data source for the specified entity **Usage Examples:** - "Get all information available from Rootly about user-service" - "What are the custom-security-check facts for payment-api?" - "Show me all facts from data source '1234' for auth-service" - "Fetch the techdocs facts for my-component" **Key Benefits:** - Dynamic fact retrieval for any configured data source - Returns raw fact data with all available metrics - Useful for exploratory analysis and custom integrations **Required Permissions:** - **Catalog entity read (*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get All Entities Facts Get facts for all entities from a specific data source with optional filtering by kind and namespace (defaults to component entities). **Parameters:** - `dataSourceId` (string): The ID of the data source to query facts from - `kind` (string, optional): Filter by entity kind (e.g., "component", "api"). **Defaults to "component".** - `namespace` (string, optional): Filter by namespace (e.g., "default", "production") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-all-entities-facts", "arguments": { "dataSourceId": "7e6a974c-f0ec-473f-9cc1-21c2752780a0" } }, "id": 1 }' ``` **Example Usage with Filters:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-all-entities-facts", "arguments": { "dataSourceId": "7e6a974c-f0ec-473f-9cc1-21c2752780a0", "kind": "api", "namespace": "production" } }, "id": 1 }' ``` **Return Schema:** ```typescript { dataSourceId: string, dataSourceTitle?: string, entities: Array<{ entityRef: string, facts: Record, timestamp?: string }> } ``` **Workflow:** Get facts for all entities from a specific data source: 1. First, use the data source discovery tool to find available data sources and their IDs 2. Call `get-all-entities-facts` with the data source ID 3. By default, returns only component entities (the most common use case) 4. Optionally override the kind filter or add namespace filtering 5. Receive facts for all matching entities tracked by that data source **Available Filters:** - **kind**: Filter by entity kind (e.g., "component", "api"). **Defaults to "component".** - **namespace**: Filter by namespace (e.g., "default", "acmeinc") **Usage Examples:** - "Get all facts from data source 'github-stats'" - "Get facts for all APIs from security metric data sources" - "Show me all entities regardless of kind from github data source" - "Get component facts in the acmeinc namespace" **Note:** - The default kind filter of "component" covers most use cases. To see all entity kinds, explicitly specify a different kind or omit the filter. **Required Permissions:** - **Catalog entity read (*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get GitHub Metrics Retrieve GitHub-related metrics including pull request performance, repository activity, and contributor data. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") - `entityRef` (string): Entity reference **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-github-metrics", "arguments": { "name": "user-service" } }, "id": 1 }' ```json { "entityRef": "component:default/user-service" } ``` **Return Schema:** ```typescript { pullRequests: { total: number | 'unknown', merged: number | 'unknown', open: number | 'unknown', mergedPercentage: number | 'unknown', mergedLastMonth: number | 'unknown' }, mergeTime: { avgHours: number | 'unknown', avgLastMonthHours: number | 'unknown', minHours: number | 'unknown', maxHours: number | 'unknown', minLastMonthHours: number | 'unknown', maxLastMonthHours: number | 'unknown' }, issues: { total: number | 'unknown', open: number | 'unknown', closed: number | 'unknown', closedLastMonth: number | 'unknown' }, latestMergedPR: { title: string | 'unknown', author: string | 'unknown' }, collaboration: { languages: string[], collaborators: string[], collaboratorCount: number | 'unknown' }, branchProtection: { enabled: boolean | 'unknown', enforceAdmins: boolean | 'unknown', allowDeletions: boolean | 'unknown', requiredLinearHistory: boolean | 'unknown', allowForcePushes: boolean | 'unknown', blockCreations: boolean | 'unknown', requiredSignatures: boolean | 'unknown' }, codeReview: { dismissStaleReviews: boolean | 'unknown', requireCodeOwnerReviews: boolean | 'unknown', requireLastPushApproval: boolean | 'unknown', requiredApprovingReviewCount: number | 'unknown', strictRequiredStatusChecks: boolean | 'unknown', usesCodeowners: boolean | 'unknown', codeownersErrorCount: number | 'unknown', codeownersHasErrors: boolean | 'unknown' } } ``` **Usage Examples:** - "How long does it take to merge PRs for user-service?" - "Show me GitHub metrics for payment-api" - "What's the PR activity for auth-service?" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get Security Metrics Access security-related metrics from Snyk vulnerability scans and Dependabot alerts. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") - `entityRef` (string): Entity reference **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-security-metrics", "arguments": { "name": "payment-service" } }, "id": 1 }' ```json { "entityRef": "component:default/payment-service" } ``` **Return Schema:** ```typescript { snykIssues?: { total: number, critical: number, high: number, medium: number, low: number }, dependabotAlerts?: { open: number, dismissed: number, fixed: number }, branchProtection?: boolean } ``` **Usage Examples:** - "What security vulnerabilities does payment-service have?" - "Are there any Dependabot alerts for user-service?" - "Is branch protection enabled for auth-service?" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get PagerDuty Metrics Retrieve incident metrics and service configuration from PagerDuty integration. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-pagerduty-metrics", "arguments": { "name": "auth-service" } }, "id": 1 }' **Return Schema:** ```typescript { incidentMetrics?: { totalIncidents: number, monthlyIncidents: number, quarterlyIncidents: number, meanTimeToResolve?: number, meanTimeToFirstAck?: number, upTimePercentage?: number }, serviceInfo?: { hasEscalationPolicy: boolean, hasTeamsAssigned: boolean, hasDescription: boolean, alertCreationType?: string } } ``` **Usage Examples:** - "How many incidents does auth-service have?" - "What's the MTTR for payment-service?" - "Show me PagerDuty metrics for api:acmeinc/user-service" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get Datadog Metrics Access Service Level Objective (SLO) data and monitoring information from Datadog. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-datadog-metrics", "arguments": { "name": "inventory-api" } }, "id": 1 }' **Return Schema:** ```typescript { sloCount: number, monitorCount: number } ``` **Usage Examples:** - "How many SLOs does inventory-api have?" - "Show me Datadog metrics for payment-service" - "What monitors are configured for auth-service?" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get Entity Compliance Evaluate entity metadata completeness and compliance with organizational standards. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") - `kind` (string, optional): The entity kind (defaults to "component") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-entity-compliance", "arguments": { "name": "user-service" } }, "id": 1 }' **Return Schema:** ```typescript { metadata: { hasTitle: boolean | 'unknown', hasDescription: boolean | 'unknown', hasTags: boolean | 'unknown', hasOwner: boolean | 'unknown' }, techdocs: { hasTechdocsRef: boolean | 'unknown' }, ownership: { hasOwner: boolean | 'unknown', hasGroupOwner: boolean | 'unknown', hasRelationships: boolean | 'unknown' } } ``` **Usage Examples:** - "How complete is the metadata for user-service?" - "Is payment-api properly documented?" - "Does auth-service have proper ownership assigned?" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ### Get Repository Info Analyze repository structure and catalog configuration status. **Parameters:** - `name` (string): The name of the catalog entity - `namespace` (string, optional): The entity namespace (defaults to "default") **Example Usage:** ```bash curl -s -X POST https://api.roadie.so/api/mcp/v1/tech-insights-facts \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get-repository-info", "arguments": { "name": "payment-service" } }, "id": 1 }' **Return Schema:** ```typescript { filePaths: string[], totalFiles: number, inCatalog?: boolean, fileTypes: { docker: number, yaml: number, javascript: number, python: number, docs: number, config: number } } ``` **Usage Examples:** - "What files are in the payment-service repository?" - "Is user-service properly cataloged?" - "Show me the file structure for auth-service" #### Required Permissions: - **Catalog entity read (\*)** - Access to catalog entities - **Roadie Tech Insights Data Source Read** - Access to Tech Insights data ## Common Use Cases ### Performance Analysis - "How long does it take to merge PRs for user-service?" - "What's the incident rate for payment-service?" - "Show me the SLO compliance for auth-api" ### Security Assessment - "What security vulnerabilities does user-service have?" - "Are there any Dependabot alerts for payment-service?" - "What's the security posture of our inventory system?" ### Compliance Monitoring - "How complete is the metadata for auth-service?" - "Which services need better documentation?" - "What's the compliance score for our payment components?" ### Operational Insights - "Which services have the most incidents?" - "What's the GitHub activity like for user-service?" - "Show me the monitoring status for all payment services" ## Tech Insights Data Sources The module automatically fetches data from all configured Tech Insights data sources, including: - **GitHub Data Source**: PR metrics, repository info, collaborators, commit activity - **Snyk Data Source**: Security vulnerability counts by severity level - **Dependabot Data Source**: Dependency alert statistics and update metrics - **PagerDuty Data Sources**: Incident metrics, MTTR, service configuration - **Datadog Data Source**: SLO compliance, monitor counts, alert frequency - **Repository Files**: File structure analysis, catalog-info.yaml status - **Entity Metadata**: Completeness scores, required field compliance ## Example Workflows ### Security Assessment **User:** "What's the security posture of our payment services?" **AI Response using MCP:** 1. Uses `get-security-metrics` for all payment-related components 2. Aggregates vulnerability data across services 3. Identifies critical security issues requiring attention 4. Provides prioritized remediation recommendations ### Operational Review **User:** "How are our services performing?" **AI Response using MCP:** 1. Combines `get-github-metrics` with `get-pagerduty-metrics` 2. Analyzes development velocity and operational stability 3. Identifies services with concerning trends 4. Suggests areas for improvement ## Best Practices - Combine multiple metrics for comprehensive service assessment - Use compliance data to identify services needing attention - Monitor trends over time rather than point-in-time snapshots - Correlate security metrics with development activity ## Data Availability Metric availability depends on your configured Tech Insights data sources. If a metric shows as unavailable, ensure the corresponding integration is properly configured in your Roadie instance. --- ### [Building your Catalog](https://roadie.io/docs/catalog/building-your-catalog.md) ## Overview The primary method of constructing your Catalog in Roadie is by pulling data from sources of truth and stitching that together into Catalog entities. We call this the Catalog Builder. The data you need already lives outside of a structured Catalog format, and by syncing to these systems on a regular basis you can produce a live, always accurate representation of your software ecosystem. ## How does the Catalog Builder work? | Topic | What it is | | ----- | ---------- | | [Integrations](/docs/catalog/building-your-catalog/integrations/) | Reusable connections (for example HTTP or AWS) that power data sources and workflow nodes. | | [Data sources](/docs/catalog/building-your-catalog/data-sources/) | Sync external data into the **catalog datastore** on a schedule. | | [Entity Workflows](/docs/catalog/building-your-catalog/workflows/) | Pull data from data sources, transform it, merge it, and then emit it as Catalog entities. | ## How do you get started? 1. Define or reuse **integrations** your organization trusts for outbound calls. These can be common third party tools like AWS or GitHub, but they can also be homegrown APIs and services hosted on your infrastructure. 2. Create **data sources** that pull from specific endpoints that an integration exposes then normalized the objects to store them in the catalog datastore. 3. Build **Entity Workflows** with a schedule that wire one or more **Datastore** together to form Entities. Here you can **map** / **filter** / **merge**, and combine Data Sources to create Entities in your Catalog. ## Permissions Building your Catalog uses dedicated permissions for **integrations** and **catalog workflows** (read, create, update, delete, and execute on workflows). Assign them to platform or admin roles so only trusted users can change pipelines that affect production catalog data. Read the [Permissions documentation](/docs/permissions/overview/) for how roles and policies work in Roadie. ## What about things that are currently stored in a source of truth system? The Catalog Builder complements other ingestion paths you might also want to use: - YAML in Git ([autodiscovery](/docs/getting-started/autodiscovery/), [location management](/docs/catalog/location-management/)) - [Auto-ingestion](/docs/catalog/overview/#auto-ingestion) from supported providers - [Roadie Entity API](/docs/integrations/roadie-api/) for push or set-based updates ## Further reading | Topic | Description | | ----- | ----------- | | [Catalog overview](/docs/catalog/overview/) | How the catalog fits together with other ingestion options | | [Getting started overview](/docs/getting-started/overview/) | First steps alongside YAML, CLI, API, and Building your Catalog | | [Modeling entities](/docs/catalog/modeling-entities/) | Kinds, relationships, and YAML structure | | [HTTP integration](/docs/integrations/http/) | HTTP proxy patterns elsewhere in Roadie (related concepts) | | [Decorating components](/docs/catalog/decorating-components/) | Enriching entities without editing source YAML | | [Roadie Entity API](/docs/integrations/roadie-api/) | Programmatic entity management | --- ### [Catalog data sources](https://roadie.io/docs/catalog/building-your-catalog/data-sources.md) ## Overview **Data sources** are how you pull structured data from the outside world into Roadie’s **catalog datastore**. Each data source is part of an [integration](/docs/catalog/building-your-catalog/integrations/). Data source runs can be scheduled so the underlying data stored in Roadie stays fresh before [workflows](/docs/catalog/building-your-catalog/workflows/) read that data and turn it into catalog entities. Open **Data sources** in the catalog administration experience to: - Create and edit sources that map integration responses into datastore objects - See object counts, last run times, and status at a glance - Drill into a source to test extraction and adjust configuration Data sources are usually the **upstream** step in a generation pipeline: sync objects to a data source, then consume them with **Data source** nodes in Entity Workflows. ## Creating a Data Source
Note

All Data Sources require a configured Integration. Unconfigured Integrations appear greyed out in the Integrations list, indicating that config and/or secrets need to be added for those services.

1. Click `+ New` on the Data Source page 2. Select the `Integration` you will be pulling data from for this Data Source. 3. Select an API path to call to retrieve data. Integrations expose several endpoints that are ingested via OpenAPI specs to form this dropdown list. 4. Most API endpoints require some parameters to be passed into them. Add those where appropriate. 5. Once you've made your edits, `Save` and `Dry Run` to see results of your Data Source. If there are issues, you'll then see information about any errors that might be present. If the Data Source executed successfully, you'll see counts for each step for how many objects were returned. 6. If that all looks correct, hit `Run saved version`. 7. On the Data Source screen, mark as `Active` using the toggle. ## Filtering If an API call returns more data than require, you can optionally filter it before the response is saved to the Datastore. ## Chained Sources If the data you want requires multiple calls, you can use a Chained Source. Chained Sources can either Enrich (add additional data to each item returned from the previous Source) or Flatten (replace items from the previous Source with the results of the latest call). ## Scheduling Data Sources run on a schedule. For each Data Source you can modify the Schedule for when and how frequently it runs. ## Storing in the Datastore Objects are indexed on their way into the Datastore. By default this uses the `id` from each object. ## Advanced options and additional headers Each Data Source supports adding extra information to requests and tuning how responses are turned into datastore objects: | Option | Detail | | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | Additional Headers | Extra HTTP headers sent with each Data Source request to the integration (for example custom auth or tracing headers). | | Response Parsing - array expression | Expression that selects the array within the response whose elements should be stored as objects in the datastore. | | Response Parsing - object id expression | Expression that selects the stable identifier for each object when indexing into the datastore (see [Storing in the Datastore](#storing-in-the-datastore)). | | Pagination settings | Configuration for APIs that split results across pages, so the Data Source can retrieve the full dataset. | ## Further reading - [Building your Catalog — overview](/docs/catalog/building-your-catalog/) - [Workflows to create entities](/docs/catalog/building-your-catalog/workflows/) - [Object graph](/docs/catalog/building-your-catalog/object-graph/) - [HTTP integration](/docs/integrations/http/) --- ### [Integrations for Building your Catalog](https://roadie.io/docs/catalog/building-your-catalog/integrations.md) ## Overview **Integrations** are reusable connection definitions—credentials, base URLs, and provider-specific settings—that **data sources** use when fetching data. They are the same integration system used across Roadie’s catalog tooling, so you configure them once and reference them from multiple sources or workflows. From the **Integrations** overview you can browse, search, and filter integrations; create new ones; and edit or remove existing definitions (subject to permissions). ![integration-list(./integration-list.webp)] ## How they fit the pipeline 1. Create an **integration** for the system you need to reach (for example, an HTTP API or AWS API) using the `+ New` button on the Integrations page. Integrations require Names, Slugs, Connections, and Authentication options. 2. Use that integration in a **[data source](/docs/catalog/building-your-catalog/data-sources/)** so scheduled syncs can write objects into the datastore. For HTTP-style access patterns elsewhere in Roadie (proxies, authenticated requests from plugins), see also the general [HTTP integration](/docs/integrations/http/) documentation. Integrations used when Building your Catalog are configured in the dedicated **Integrations** UI for data sources and workflows. ![integration-new(./integration-new.webp)] ## Advanced options on an Integration Additional settings can be attached to an Integration. ### Additional headers These header names are available when you add extra headers on an integration (for example `Authorization`, API keys, tracing, or caching): | Option | Detail | | ------------------ | -------------------------------------------------------------------------------------------------------- | | `authorization` | Sends credentials such as Bearer tokens, Basic auth, or vendor-specific schemes. | | `x-api-key` | Sends an API key in a header, a pattern used by many HTTP gateways and SaaS APIs. | | `x-auth-token` | Sends an alternate token-style credential when the upstream expects this header instead of `Authorization`. | | `content-type` | Declares the MIME type of the request body (for example `application/json`). | | `accept` | Tells the server which response content types the client can handle. | | `x-request-id` | Unique id for a single request, useful for log correlation on the receiving service. | | `x-correlation-id` | Shared id across related calls in a workflow, for distributed tracing. | | `cache-control` | Directives that influence caching between clients, proxies, and origin. | | `if-none-match` | Conditional request using an entity tag, often for efficient polling with `304 Not Modified`. | | `x-forwarded-for` | Conveys the original client IP when the request passes through proxies or load balancers. | | `x-custom-header` | Arbitrary vendor-specific header name and value beyond the presets above. | - Rate limits can be added to limit requests and set a burst capacity. - A CA Certificate can be attached ## Permissions Creating, updating, and deleting integrations is gated by integration permissions. Restrict these to administrators or platform engineers who are allowed to manage outbound credentials and endpoints. ## Further reading - [Building your Catalog — overview](/docs/catalog/building-your-catalog/) - [Data sources](/docs/catalog/building-your-catalog/data-sources/) - [Workflows to create entities](/docs/catalog/building-your-catalog/workflows/) - [HTTP integration](/docs/integrations/http/) --- ### [Workflows to create entities](https://roadie.io/docs/catalog/building-your-catalog/workflows.md) ## Overview **Workflows** (entity-creation pipelines) are directed graphs that describe how data becomes [Backstage catalog entities](https://backstage.io/docs/features/software-catalog/descriptor-format/). At the moment, these are constructed wholly in the Roadie Editor UI. In the Editor you connect nodes on a canvas; execution moves from a trigger through **sources** and **transforms** into **sinks**. New workflows are created as **entity-creation** type so the graph is validated for publishing entities into the catalog. ## Triggers | Node | Role | | ---- | ---- | | **Schedule** | Runs the workflow on a recurring interval (minutes, hours, days, or weeks; weekly schedules can optionally fix a day of week). | ## Sources | Node | Role | | ---- | ---- | | **Data source** | Reads objects from the catalog datastore, typically populated by [data sources](/docs/catalog/building-your-catalog/data-sources/). | ## Transforms | Node | Role | | ---- | ---- | | **Map** | Transforms each item with a [JSONata](https://jsonata.org/) expression to shape fields for entity templates. | | **Filter** | Keeps or drops items using JSONata. | | **Merge** | Joins two inputs on configurable keys (for example correlating two datastore snapshots). | ## Sinks | Node | Role | | ---- | ---- | | **Entity provider** | Emits catalog entities via the entity provider mechanism, using templates (including Nunjucks) so each record becomes a valid entity. Standard kinds include Component, API, Resource, Group, User, System, Domain, Location, Repository, and Product, subject to your validators. | ## Creating a new Workflow
Note

Workflows require at least one configured Data Source. It needs to have successfully run to collect data in order for that data to be accessible to a Workflow.

1. From the Workflows page, select `+ New`. 2. Drag over configured Data Sources on to the Editor on the right panel. Each Data Source becomes a node. 3. Any number of Data Sources can be added to the Editor. 4. Data Sources data can be filtered, mapped and merged together with data from other Data Sources using the `Filter`, `Map` and `Merge` nodes. 5. Nodes are connected by dragging edges between nodes. 6. In order to create entities in the Catalog, drag an Entity Provider node on to the Editor panel. 7. Entity Providers can either be configured using the `Composer` or via the `Advanced` option (writing raw YAML). Entity Providers use templating to pull data from Data Sources into individual entities. 8. Once you're ready to see how a Workflow operates, use `Test`. 9. Once you're happy with the workflow, `Save`, and `Commit` to add those entities to your Catalog. ## Dry runs and operations Where supported, nodes allow **dry runs** so you can validate extraction and transforms before enabling a schedule or relying on the workflow in production. Enable the workflow when you are satisfied, then monitor executions and adjust JSONata or templates when upstream APIs change. ## Permissions Workflow actions are protected by catalog workflow permissions (read, create, update, delete, and **execute**). Grant execute only to users or roles that should be able to run pipelines against real data. ## Further reading - [Building your Catalog — overview](/docs/catalog/building-your-catalog/) - [Data sources](/docs/catalog/building-your-catalog/data-sources/) - [Integrations](/docs/catalog/building-your-catalog/integrations/) - [Modeling entities](/docs/catalog/modeling-entities/) --- ### [Use custom renderer with your API entities](https://roadie.io/docs/catalog/custom-api-docs-renderers.md) ## Introduction The API docs plugin supports user supplied renderers for API definitions. This page explains how you can configure such a renderer in roadie. ## Prerequisites - You must have custom plugins enabled for your tenant. Contact Roadie to enquire about this. ## Step 1: Write a custom renderer A [custom API docs renderer](https://www.npmjs.com/package/@backstage/plugin-api-docs#custom-api-renderings) is a React component which takes the API definition as a prop and renders it. For example, the simplest custom renderer which just prefixes the definition would be something like this: ```typescript import React from 'react'; import { Typography } from '@material-ui/core'; export const CustomApiDefinition = ({ definition }: { definition: string }) => ( Custom format: {definition} ); ``` Ensure that the component is exported from the plugin: ```typescript // src/index.ts export { customApiDefinitionPlugin, CustomApiDefinition } from './plugin'; ``` ## Step 2: Configure your custom plugin Navigate to the custom plugins page `/administration/custom-plugins` and click "Add new plugin". Then enter your plugin's details. - The plugin package should match the name in your plugin's package.json matching this convention `@-roadie/`. - The plugin name should be the name of the exported plugin variable (e.g. customApiDefinitionPlugin above) Then click "Add Component" and set the type to ApiDocsWidget and the name to the name of the exported custom renderer (e.g. CustomApiDefinition) and click "Save". ## Step 3: Publish your custom plugin Read [the docs on custom plugins](/docs/custom-plugins/overview/) then build your package and publish to artifactory. In a nutshell: ``` yarn tsc && yarn build && yarn version && yarn publish ``` ## Step 4: Configure the renderer in settings It is necessary to configure the type of entity the custom renderer applies to in settings at `/administration/settings/api-docs`. First click "add item" then enter the custom renderer information. - The type should match the `spec.type` field on API entities this should be used to render. - The title is showed as the name of the format in the API docs card. - The component is then specified and this should match the custom component registered in step #2 (Caveat: it can take some time for a custom component to become available for use) ## Recent Blog Posts ### [The Word 'Context' Has Stopped Meaning Anything](https://roadie.io/blog/context-engineering-definition-problem.md) # The Word 'Context' Has Stopped Meaning Anything Roadie is working in this space - we're building context infrastructure for AI agents. I want to say that upfront, because this piece is about the word "context" and we have a commercial stake in what it means. If you want working definitions before the argument, [our working glossary of context terms](https://roadie.io/blog/context-agents-mcp-glossary/) is the right starting point. This piece is about what happens to a precise technical term when the market gets hold of it. ## The term earned its name by pointing at something real On June 19, 2025, [Tobi Lütke posted on X](https://x.com/tobi/status/1935533422589399127): "I really like the term 'context engineering' over prompt engineering. It describes the core skill better: the art of providing all the context for the task to be plausibly solvable by the LLM." Six days later, [Andrej Karpathy amplified it](https://x.com/karpathy/status/1937902205765607626): "context engineering is the delicate art and science of filling the context window" in "every industrial-strength LLM app." These posts did something specific: they named an architectural discipline, not a copywriting skill. The work is deciding what data the agent retrieves, in what order, structured how, from what source. That framing - system design, not wordsmithing - was a genuine upgrade. [The real distinction between prompt engineering and context engineering](https://roadie.io/blog/prompt-engineering-vs-context-engineering/) runs deeper than vocabulary: it is the difference between adjusting text and redesigning information systems. The defenders of the term have a substantive case. [Phil Schmid's practitioner definition](https://www.philschmid.de/context-engineering) (June 30, 2025) arrives at the same point: most agent failures are context failures, not model failures. [DBReunig noted](https://www.dbreunig.com/2025/07/24/why-the-term-context-engineering-matters.html) in July 2025 that within a month of the Lütke and Karpathy posts, "context engineering" had reached a quarter of "prompt engineering"'s search volume - and a marketing buzzword spikes and falls rather than sustains. A [Stanford and SambaNova study published in October 2025](https://arxiv.org/abs/2510.04618) showed that incremental, structured context updates reduced adaptation latency by up to 86% compared to static or regenerated prompts. [Sourcegraph's May 2026 heuristic](https://sourcegraph.com/blog/context-engineering) arrives at the same point from the practitioner side: the clearest tell of genuine context engineering is whether your improvements come from rewiring what data the agent retrieves, not from rewording the prompt. The discipline is real. ## Then the market got hold of it By 2026 the label had been stretched to cover almost anything sitting between data and a model - a retrieval pipeline, a session-memory store, a rebadged data catalogue. Practitioners noticed the drift. A thread on Reddit's r/AI_Agents was titled, flatly, ["The word 'context' has stopped meaning anything in enterprise AI"](https://www.reddit.com/r/AI_Agents/comments/1u78b1i/the_word_context_has_stopped_meaning_anything_in/), and the same complaint turned up [on Mastodon](https://social.masto.host/@njoseph/116763474266027349) and [on Bluesky](https://bsky.app/profile/ideasintheround.bsky.social/post/3mofhdxqxxc2p). When a term is made to cover everything, it stops marking anything in particular. ## Where the definition still holds [Anthropic published their technical definition in September 2025](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents): context engineering is "the set of strategies for curating and maintaining the optimal set of tokens (information) during LLM inference." That definition is narrow by design. It covers the architectural discipline Lütke and Karpathy named. It does not extend to every product that sits between data and a model. Context engineering - when the term is used precisely - describes the work of determining what information an AI model needs, in what format, at what time, and from what source. A system that does this well has four properties that distinguish it from retrieval infrastructure. The data is structured and typed. A typed entity graph delivers deterministic query results. A semantic search index delivers probabilistic relevance rankings. These belong to different reliability classes when agents are making operational decisions. The system is queryable in the technical sense: it returns a typed, traversable object. When an agent asks who owns fraud-detection-service, the answer should be a structured record with an owner ID, a team ID, and SLO data - not a paragraph mentioning ownership. Entity relationships are first-class data, represented explicitly in the graph rather than guessed ad hoc from document proximity. The edge may be declared by a team, ingested from a deploy system, or inferred from infrastructure code - but once promoted into the graph, it is queryable relationship data. Proximity in a document and a graph edge are different things. The context is authoritative enough to drive decisions without human review. If someone needs to verify the output before the agent acts on it, the context is advisory. A context layer for operational systems has to be right every time it is queried. [Sourcegraph](https://sourcegraph.com/blog/context-engineering) put the test well in May 2026: "The clearest tell that you've crossed from one discipline into the other is whether your improvements come from rewording or from rewiring. If you're swapping nouns and adjectives, you're still doing prompt engineering." The old-document problem runs the same test in practice: can your system distinguish a canonical architectural decision record from a three-year-old wiki page that contradicts it? Purely semantic retrieval surfaces both. A system with typed provenance and declared authority can tell them apart. ## A working test When a vendor says they do context engineering, four questions settle it: 1. Where does the context come from - what is the authoritative source? 2. How stale can it get before producing errors? 3. Is the data structured or unstructured? 4. Is it retrieved fresh each turn or maintained across turns? A context layer is not a feature. It is an architectural commitment. If a vendor cannot answer all four, they have a retrieval system with better marketing. Now you're probably thinking: you work in this space, of course you're defending the term. Fair. Roadie is building the infrastructure that context engineering runs on - it's the same space this piece is about, and getting the definition right is part of the work we're doing. From that position: most of what is being called context engineering in enterprise pitches in 2026 is either RAG with better marketing or a service catalogue with a new name. The distinction matters most where agents stop answering questions and start taking operational decisions - routing production incidents, gating deployments, provisioning infrastructure. When agents answer questions, fuzzy context produces a worse answer. When agents route production incidents or gate deployments, fuzzy context produces an outage. [What a context layer actually does in practice](https://roadie.io/blog/smart-agents-smart-context/), and why [an engineering graph is the highest-signal context source](https://roadie.io/blog/context-engineering-for-developers-ai-infrastructure/), is a different argument. But it starts from this one: the word has to mean something first. --- ### [Why AI-augmented squads keep building the same thing twice](https://roadie.io/blog/ai-augmented-squads-service-duplication.md) # Why AI-augmented squads keep building the same thing twice Operating production-grade service catalogs at scale, the signal is consistent: when AI tooling lands in an engineering organisation, velocity goes up and so does duplication. Squads ship more features per sprint. They also build the same thing twice. A [DX Annual panel in May 2026](https://newsletter.getdx.com/p/designing-the-ai-native-engineering) described this from the engineering leader side. Tim Bozarth from Microsoft, Nancy Wang from 1Password, and Taroon Mandhana from Atlassian outlined how enterprises are restructuring around AI capability: smaller squads, shorter planning horizons, AI-augmented engineers. These are genuine structural responses to real changes in how quickly software can be written. Late in the panel, Mandhana added: "We're seeing patterns of duplication and tech debt increasing as people quickly produce features. The maintainability of the code is suffering. It's prompted us to go back to standardised approaches and more right-of-code quality checks." The panel named the symptom but moved on. The cause of the duplication - why AI-augmented squads keep building the same thing twice even as pace increases - got no answer. ## The structural argument and what it leaves open The panel's org design recommendations are worth exploring. Smaller squads reduce coordination overhead. AI-augmented engineers can produce working code quickly enough that the old argument for long planning cycles has weakened considerably. Bozarth's model - "you form a team around a specific question, give them 8 weeks, then decide whether to continue" - matches how AI-assisted iteration actually works, where feedback loops have compressed from weeks to days. The structural advice is right. What the org design conversation consistently skips is the question of what AI tools can see when they help a squad build something. Duplication and tech debt are framed as consequences of speed - and they are, partly. Speed is the mechanism; missing context is the cause. An AI coding tool asked to help build a notification service will help build one. It has no way of knowing that a notification service already exists in the service registry two teams over unless that service is explicitly visible in the context it's operating from. It won't ask around. It won't draw on institutional memory. It builds what the context available to it doesn't contradict. Duplication at this scale has an infrastructure and knowledge cause. The org design changes the panel recommends are right - but they make the context problem more acute, because more squads are building things simultaneously with less shared institutional memory. This raises the stakes for the context infrastructure underneath. ## What machine context actually needs to look like The information AI agents need to avoid duplication is the same information a senior engineer would draw on before starting a new service: who owns adjacent services, what the dependency graph looks like, what services in the system do similar things, what SLO commitments exist for services the new work might extend or replace, which teams would be affected by adding a new node to the dependency graph. An experienced engineer holds most of this in memory, or knows exactly who to ask. In an 8-week squad with AI-assisted velocity, some of that context may exist within the team - but the AI tools doing the build work don't have access to it unless it's been made explicit. The tools operate on what's been provided: the local codebase, the instructions, whatever retrieval is wired into the workflow. If the service catalog isn't wired in, the tools are building without a map of what already exists. Keeping these dimensions accurate - ownership, dependencies, deployment state, SLOs - is the prerequisite for AI-assisted development to scale across multiple squads without compounding duplication into the codebase. The catalog's role shifts when AI tools enter the build workflow. A human-browsable portal with stale records is an inconvenience for a platform engineer looking something up. That same stale record is a failure surface for an AI agent that reads it as current truth. The agent doesn't triangulate from surrounding context the way a person does. It reads what's there. If a service isn't in the catalog, or the ownership record is eighteen months out of date, the agent reasons and builds accordingly. ## Time-bounded squads and the catalog dependency Bozarth's 8-week squad model makes the catalog dependency particularly visible. A squad formed for eight weeks around a specific question may not have built up institutional knowledge of what the organisation has already shipped. Engineers on the squad may be coming from different parts of the stack, with limited visibility into what other teams built in recent cycles. Without accurate, machine-readable catalog data in the retrieval chain, the squad and its AI tools are starting from incomplete context. Across a year with multiple cycles of 8-week squads working through the same engineering organisation, this compounds. Each cycle builds at speed. Each cycle's AI tools operate on the context available in that cycle. With accurate catalog data wired in, a squad can see what the organisation has already built and work from it - extend a service, adopt a dependency, reuse what's already running. Without it, each cycle starts from the immediately visible horizon. The tech debt Mandhana described accumulates from the sum of those gaps. The same velocity gains that make AI-augmented squads productive also make the duplication visible faster. The catalog dependency doesn't go away when squads get faster - it gets more load-bearing. ## The infrastructure argument the org design conversation is missing The framing in the panel - reducing approval chains, delegating more decision authority, letting small teams move with autonomy - addresses the human coordination problem correctly. The platform team's job in that same environment is to provide the infrastructure that lets those squads move fast without compounding each other's work. For AI-augmented squads operating at the speed Tim, Nancy, and Taroon described, that infrastructure starts with the service catalog. The catalog work that makes AI agents accurate across squads is the same work that keeps on-call rotations correct and dependency changes tracked. Those were human friction problems before AI entered the workflow - the engineer who had to ask around, the incident routed to the wrong team. What changes with AI in the loop is the rate at which gaps in the catalog produce wrong outcomes. A missing ownership record that generated mild friction in the human layer produces duplication at the pace AI tools enable. Mandhana said the duplication and tech debt are prompting Atlassian to go back to standardised approaches and right-of-code quality checks. That is a reasonable response to the symptom. The infrastructure response is to address the context layer before the code is written: a catalog that AI agents can query, maintained accurately enough that what gets built in week one of a squad's 8-week sprint reflects what the engineering organisation has already built. That's what the AI-native org conversation is actually pointing at, without naming it directly - and doing it with eyes open means treating the catalog as operational infrastructure, not documentation housekeeping. --- ### [Why Your MCP Server Might Be Eating Your Context Window (and How to Fix It)](https://roadie.io/blog/mcp-server-context-window.md) # Why Your MCP Server Might Be Eating Your Context Window (and How to Fix It) MCP was devised as a protocol to give AI agents a consistent way to interact with external systems and the structured context that sits outside the model itself. Adoption has been broad since late 2025: most major coding agents, IDEs, and platform vendors now ship MCP support. As more servers come online and more agents wire into them, a new problem has surfaced: context bloat. Many MCP servers in production today fill agents' context windows in two ways - they front-load full tool definitions the moment a connection opens, and they return unfiltered responses on every call. Context windows fill before the agent has done any useful work. Connect three MCP servers to your agent stack - GitHub, Slack, Sentry - and 55,000 tokens of tool definitions load before the agent reads its first user message. That's [Apideck's own illustrative test](https://www.apideck.com/blog/mcp-server-eating-context-window-cli-alternative), published March 2026. A different setup they documented came in at 143,000 tokens, which was 72% of Claude's context window when those benchmarks ran. The obvious counter is that we have 1M context windows now. [Claude Opus 4.6 and Sonnet 4.6 run 1M tokens at standard pricing](https://platform.claude.com/docs/en/build-with-claude/context-windows), generally available since mid March 2026. Opus 4.7, which launched in April, supports the same window, and ditto for Opus 4.8 which launched recently. A 143,000-token tool dump is 14% of 1M, not 72% of 200K. For a simple three-server agent stack, that headroom probably covers it. For an MCP server sitting on top of a context graph, the maths work differently. ## Why more headroom doesn't change the economics MCP and CLI reach the same services. What differs is what the trip costs in tokens. [Scalekit ran 75 benchmark runs](https://www.scalekit.com/blog/mcp-vs-cli-use) comparing CLI and MCP on identical tasks. MCP cost between 4 and 32 times more tokens per operation than CLI. Repo language detection: 1,365 tokens via CLI, 44,026 via MCP. That ratio holds at any window size. At 10,000 operations a month, you're paying $3.20 via CLI or $55.20 via MCP. A bigger ceiling doesn't change the multiplier. None of this is a reason to drop back to CLI. MCP earns its overhead by handing back structured, related data instead of raw output you'd have to parse and stitch together yourself - the goal is to make it pay only for what the task actually touches. The same benchmark recorded a 28% failure rate on calls to GitHub's Copilot MCP server - TCP timeouts, not protocol errors. You pay the per-operation token cost on calls that don't always complete. These two problems are real on any MCP implementation. On a graph-backed server, the second one tends to compound faster than you'd expect. Many general-purpose servers load a few dozen tool definitions and return bounded responses. Graph-backed servers tend to be a different shape - they can return tags, annotations, relationship graphs, and deployment history on every entity query, if you let them. Roadie's Context Graph serves 200-300K agent API calls per day via MCP, against graphs built to hold millions of rows. If each of those calls returned full records by default, the responses wouldn't fit in 1M tokens any more than they fit in 200K - we'd saturate the window before the agent did any useful work. Bigger windows give you more margin, but they don't change that cost shape, which is why returning everything by default was never an option for us. ## One pattern that works Progressive disclosure is one of the approaches the industry is converging on, and it's the one we've leant into: each query returns what the agent needs for its current decision, not everything it might conceivably need across all possible tasks. A discovery query asks what's available and gets a compact summary - entity kinds, counts, namespaces. A scoped query, "services owned by the payments team", returns names, owners, and current status. A detail query, against a specific service the agent has already identified, returns the fields the workflow actually needs: ownership chain, recent deployments, open incidents, attached runbooks. Full records are available when asked for. They're just not the default. [Port of Context tested the same idea at the interaction-model level](https://www.portofcontext.com/blog/cli-vs-mcp-vs-code-mode) with a 12-task Stripe benchmark. They ran identical workflows across CLI, raw MCP, and Code Mode - where Code Mode lets the agent write a short TypeScript program to orchestrate calls internally rather than looping back through the model. That collapses 12-turn workflows into 4. Token totals across all 12 tasks: 711,555 via CLI, 506,970 via raw MCP, 294,924 via Code Mode. Same protocol, same Stripe server. The 42% reduction against raw MCP comes from two directions at once: scoped tool definitions, and fewer model round trips because batching moves into code rather than into the model loop. You keep what makes MCP useful for graph work - structured data, relationship graphs, consistent query semantics - and stop paying for what the agent didn't ask for. ## How Roadie approaches this Our MCP server sits on top of a Context Graph. Integrations pull structural data from systems of record into the graph; Relations link items across those systems (a GitHub user matched to an AWS IAM identity, say); Context Groups collapse the linked items into single concepts an agent can reason about - an Employee that resolves to all three sources at once. Different queries return different slices. The guiding question is "give me what's relevant to this incident on this service," not "give me the catalog." Capabilities go a layer further. A Capability is a documented procedure an agent can follow for a known process - incident investigation, employee onboarding, credential rotation. The graph supplies the entities; the Capability supplies the steps to execute against them. And the same Integrations that feed the graph are exposed directly to the agent through MCP, so live state - current open PRs, current alert status - gets fetched on demand rather than preloaded. The agent doesn't pay for what changes by the minute, and doesn't pay for what it didn't ask for. Alongside MCP, we also serve pre-built briefings - context packages that drop directly into an agent's system prompt or working directory. The broader pattern is already familiar from tools like [Claude Code's `CLAUDE.md`](https://code.claude.com/docs/en/memory) and [Cursor's rules](https://cursor.com/docs/context/rules); briefings apply the same idea specifically to organisational context, for cases where you know upfront what an agent needs. The integration shape varies across these surfaces, but the disclosure discipline behind them is the same. A 20,000-entity graph doesn't impose a 20,000-entity context cost per query. The agent pays for the entities the task touches, and graph scale becomes an asset - more complete information available when a workflow asks for it - rather than a liability that fills the window before the agent can act. ## Three questions worth asking Whether you're evaluating a graph-backed MCP server or building one yourself, three questions tend to matter most for how it behaves under real agent load. The first is what an agent sees on initial connection - a compact summary of entity kinds and scale works better than eager-loaded full schema definitions, which drive the worst initial-token numbers and don't help the agent before its first real query. The second is what a scope query returns - names, owners, and current status are usually enough for an agent to identify its targets, where full entity records load context the agent hasn't asked for. The third is what goes in a detail response - ownership, recent operational state, and attached documentation cover most workflows, while historical annotations and full schema definitions sit better behind a deliberate deeper query. In each case, the discipline is the same: return what was requested, at the granularity it was requested, and trust the agent to come back for more. That holds at 200K and at 1M. If you want to see Context Groups and Capabilities in practice, [request a demo](https://roadie.io/request-demo/). --- ### [The Context Engineering Checklist: 15 Questions to Ask Before Choosing an AI-Powered Developer Platform](https://roadie.io/blog/context-engineering-checklist-ai-developer-platform.md) You've watched an AI assistant confidently name the wrong team as the owner of a service that just fired an alert. You've seen it suggest an architectural change that ignores a hard dependency your team has known about for two years. The [Stack Overflow Developer Survey 2024](https://survey.stackoverflow.co/2024) found 76% of developers are already using or planning to use AI tools, and [McKinsey research](https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier) puts the speed improvement for coding tasks at roughly 2x. That adoption pressure means teams are buying AI platforms before they've developed the evaluation criteria to distinguish genuinely useful tooling from a well-marketed wrapper around a generic LLM. If you want to determine whether an AI platform will be useful in production, evaluate what context it can access when it generates output. Code generation quality, IDE integrations, and supported languages are all downstream of that. A platform with no access to your service catalog, team ownership model, and deployment history produces answers whose accuracy ceiling is generic internet knowledge. These answers sound authoritative but reflect a system no one runs. Context engineering is the architecture layer that sets the ceiling on what any amount of prompt optimization can achieve. This checklist runs across five categories and 15 questions. A "yes" to each means the platform treats context as infrastructure. Bring it to your next vendor call, and you'll immediately see the difference between a context-rich engineering platform and an AI chat interface bolted onto a proprietary portal. ## Category 1: Service Catalog Completeness **Q1: Does the platform index your full service catalog, including component kind, spec.type, system membership, and API definitions, or does it index source code repositories only?** AI coding assistants operate within a repository context alone. If your [catalog entity](https://backstage.io/docs/features/software-catalog/descriptor-format) knows that `payment-api` is a `spec.type: service` within the `checkout` system and exposes a specific OpenAPI definition, an AI query can contextualize recommendations at the system level. A platform limited to repository indexing can only draw on codebase content, and questions about service topology (which team owns a downstream dependency, what SLA that service exposes) require catalog entity data that lives outside any repository. **Q2: Can AI queries traverse the entity graph (for example, owner > system > component > API > dependency), or is catalog access a flat key-value lookup?** Graph traversal is the capability that separates structural answers from lookups. A flat lookup can tell you who owns `payment-api`. Graph traversal can tell you which team owns the service that `payment-api` depends on, what that service's SLA is, and where its TechDocs live, all in a single query. [Roadie's Catalog Graph plugin](https://roadie.io/docs/integrations/catalog-graph/) models these relationships explicitly: entities link via YAML-defined relations (`ownedBy`, `dependsOn`, `consumesApi`, `providesApi`), and the CatalogGraphPage lets you filter by kind and relation type to any configured depth. **Q3: Is the catalog schema extensible, with support for custom entity kinds and metadata fields that AI can subsequently query against?** Your schema will evolve. Teams add compliance metadata, cost center annotations, SLO targets, and custom entity types that reflect their actual domain. If the schema is rigid, any organizational knowledge that doesn't fit the platform's data model becomes invisible to AI queries, no matter how carefully your teams encoded it. [Roadie's catalog schema](https://roadie.io/docs/getting-started/adding-a-catalog-item/) supports custom entity kinds and additional metadata fields, so domain-specific context stays queryable as your catalog grows. Answering "which team owns the downstream service my payment API depends on?" requires traversing component and group entities linked by explicit relation types, which is why catalog depth and graph traversal set the quality ceiling for any RAG implementation you deploy. ## Category 2: Ownership and Team Metadata **Q4: Is service ownership a first-class field in the data model (for example, `spec.owner`), or is it applied as a tag or annotation without structural enforcement?** Tags and annotations are human-readable strings, and AI agents require typed, relational fields to traverse ownership data programmatically. When `spec.owner` is a typed, validated field pointing to a Group or User entity, an AI agent resolves it to an actual node in the graph. An annotation like `team: payments` is a string that requires pattern matching and is frequently stale, inconsistently formatted, or simply absent. The [Backstage entity YAML schema](https://backstage.io/docs/features/software-catalog/descriptor-format#specowner-required) enforces `spec.owner` as a structured reference, and Roadie's catalog preserves that structural integrity across all indexed entities. **Q5: When the AI returns a recommendation or surfaces an incident, can it identify and surface the owning group, their on-call contact, and their TechDocs in a single query traversal?** The practical value of ownership data depends on how many query hops it takes to go from "here's the alert" to "here's the person and the runbook." If the AI returns a partial answer and you have to manually look up [PagerDuty](https://www.pagerduty.com/) separately, the system delivers no speed advantage over your current workflow. A well-structured entity graph maps component to group to user to documentation, and a properly configured RAG retrieval pipeline returns all of those nodes together as a single grounded response. **Q6: Does ownership data stay synchronized with your actual org structure, including LDAP, GitHub teams, and PagerDuty schedules, or is synchronization manual?** Ownership data that reflects headcount six months ago misdirects incident response by pointing to the wrong person. The catalog must ingest org changes via automated ingestion, and if the vendor's answer to "how is ownership kept current" is "engineers update their catalog entity," that's a maintenance process that degrades under the pressure of every other thing those engineers are doing. Ask specifically how ownership synchronizes with your authoritative sources ([LDAP](https://ldap.com/), [GitHub teams](https://docs.github.com/en/organizations/organizing-members-into-teams/about-teams), PagerDuty) and what the propagation lag is. ## Category 3: Historical and Operational Context **Q7: Does the platform ingest deployment history as structured data, or does it display recent deploys in a UI panel without making that data queryable?** There's a meaningful difference between displaying deployment history and indexing it as structured context. A UI panel showing your last ten deploys is useful to a human reading a dashboard. Structured deployment data indexed as catalog context means an AI assistant can correlate "the service started returning 500s" with "a deploy touched this component's dependency 14 minutes ago" without requiring a human to manually cross-reference three tools. **Q8: Can the AI assistant cross-reference a live service alert with the most recent deployments that touched the affected component's dependencies?** This query pattern is what most teams actually need during an incident. It requires the alerting event to be connected to an entity in the catalog, and deployment events must be indexed against those same entities. Both conditions must be satisfied for the correlation query to work. You can confirm this during a vendor evaluation in about 10 minutes by asking the vendor to cross-reference a live alert against a recent deploy, using your own service topology. **Q9: Is embedding generation event-driven, triggered by catalog changes, deploy events, or CI runs, or is it only periodic, and is the scheduling configurable?** A context store that refreshes every 24 hours will be stale during an incident at 2am when the deploy that caused the problem shipped at 1am. Roadie's [RAG AI Plugin](https://roadie.io/backstage/plugins/ai-assistant-rag-ai/) exposes an endpoint for configuring both periodic and event-based embedding generation. Event-based generation lets you trigger re-indexing on a catalog mutation, a deployment webhook, or a CI pipeline completion, so the AI's knowledge of your system reflects the current state at the moment of each query. For environments where deploys happen multiple times per day, event-based generation is the only operationally sound configuration. ## Category 4: AI Architecture and Reliability **Q10: Is the AI layer implemented as RAG against your live catalog data, or does it depend on fine-tuning, a generic model, or a static snapshot?** Fine-tuning encodes patterns at training time, producing a model whose knowledge is anchored to the state of your systems when the training data was assembled. Any change after that point (a new catalog entity, a team restructure, or a deprecated API) requires a new training cycle before the model reflects it. RAG [retrieves from the live index at query time](https://arxiv.org/abs/2005.11401), so the model's answers reflect the current organizational state. The Roadie AI Assistant uses RAG across indexed catalog entities, TechDocs, OpenAPI specs, and [Tech Insights](https://roadie.io/docs/tech-insights/introduction/) scorecard data, making current entity state the ground truth for every response. **Q11: What is the documented hallucination mitigation strategy, and does it address your specific data sources or rely on a claim that the model is generally accurate?** Effective hallucination mitigation names the specific mechanism and the data sources that ground each query type. For Roadie's AI Assistant, that mechanism is RAG: every response is grounded in retrieved catalog entities and TechDocs content, so the model's outputs for team names or API endpoints are bounded by what exists in your indexed data. Ask vendors to explain what happens when retrieval returns no matching context, because that edge case is where wrong answers appear. **Q12: Can you swap LLM providers without re-engineering the retrieval pipeline or the vector store?** Provider portability matters because the model that performs best for your queries today may not be the right choice in 12 months, and the organizational security policy sometimes dictates which providers are permissible. Roadie's RAG AI plugin supports both [AWS Bedrock](https://aws.amazon.com/bedrock/) and [OpenAI](https://platform.openai.com/docs/overview) for embedding generation and response synthesis. The vector storage layer runs on [PostgreSQL with the `pgvector` extension](https://github.com/pgvector/pgvector), which most engineering teams already operate as part of their standard database infrastructure, so the vector store adds no new operational dependency to your stack. ## Category 5: Extensibility, Governance, and Lock-in **Q13: Is the platform's underlying data model built on an open standard, or does adopting it mean migrating your catalog data into a proprietary entity schema?** A proprietary entity schema creates lock-in at the data model layer. Your service catalog represents organizational knowledge accumulated over years of engineering work: ownership records, dependency mappings, API contracts, and team structures. If that data lives in a schema owned by a vendor, migration means rebuilding your catalog from scratch. Roadie's catalog is built on the Backstage entity YAML schema, an open specification that defines component, system, API, group, and user entity types. That data is yours to take, extend, or migrate, and the tooling ecosystem built around that specification is available regardless of which managed platform you use. **Q14: Can AI agents be cataloged as first-class entities, with ownership, dependencies, and provenance tracked, or does the platform's data model need to be extended to accommodate them?** As teams move from AI assistants to AI agents that take actions in production systems, the governance questions that apply to services apply equally to agents. Which team owns this agent? What APIs does it call? What data does it access? Cataloging agents as entities with `spec.owner` and dependency relations ensures that the same governance infrastructure tracking your services can track your agents, and that audit trails for agent-initiated writes are as traceable as any other production action. Ask whether the platform's entity schema can accommodate an `Agent` kind with the same first-class treatment it gives `Component` or `API`. **Q15: What is the realistic operational burden of keeping the platform current, and who owns upgrades, plugin compatibility, and security patches?** Proprietary developer portals typically push upgrade complexity to the customer. Each major version requires testing plugin compatibility, migrating configuration, and potentially rebuilding custom integrations. Over a 3-year horizon across 50+ services, that cost compounds into a recurring engineering tax. SaaS platforms built on open standards can absorb the core upgrade burden centrally while preserving the extensibility that makes the catalog useful. Get a specific, documented answer for who owns breaking changes before you commit to a data model. ## Run This Audit Before Your Next Vendor Call Before you spend time in a demo, run this against your current setup. It takes under 60 minutes and will tell you exactly where your context infrastructure has debt. - First, query your catalog API and count what percentage of your services have a populated `spec.owner` field. A catalog where 40% of components have no ownership data is already showing you where AI will fail. - Second, verify whether that ownership data is traversable via API. Pull the entity for any component, follow its `ownedBy` relation, and confirm you can resolve through to a user and their contact information programmatically. - Third, check whether your CI/CD pipeline or deployment tooling can emit webhook events that a context platform could consume for event-based re-indexing. If your deploy process has no webhook output, periodic indexing is your only option, and that freshness ceiling is a concrete operational risk in production. This audit helps you identify exactly where an AI platform will produce confident, wrong answers during your next production incident. Any platform worth evaluating should have a direct, documented answer for every item on this list. [See how Roadie provides structured engineering context for your team and AI agents. Request a demo.](https://roadie.io/request-a-demo/) --- ### [What Your Engineering Organisation Doesn't Know About Itself](https://roadie.io/blog/engineering-organisation-opacity-ai-agents.md) # What Your Engineering Organisation Doesn't Know About Itself When a coding agent returns wrong answers about your services, the default reaction in most engineering teams is to reach for model explanations: context window too small, retrieval quality poor, the model hallucinated. All of these can be true. But a piece at [dekodiert.de](https://dekodiert.de/en/articles/das-falsche-black-box-problem) names a different failure mode with more precision than most of the AI-in-engineering discourse manages: organisations lack honest self-description of their own decision and business logic. The article describes a workshop with a client that surfaced 47 distinct knowledge assets the organisation relied on for operational decisions. Of those 47, 21 existed nowhere as documents. Seven couldn't be explained clearly by the people who held them. Four had documented versions that contradicted actual practice. That's 32 of 47 knowledge assets - more than two-thirds - that an AI agent cannot use reliably even with perfect retrieval, because the knowledge either isn't recorded, can't be stated, or is actively misrepresented in the official record. The correct diagnosis is organisational opacity. Before asking which AI model to deploy against your engineering systems, the more useful question is: how legible is your engineering organisation to a system that can only act on what's been written down? ## The three categories of organisational opacity The taxonomy maps naturally onto an engineering organisation, though its examples come from a sales and operations context. The three categories behave differently and require different responses. The first category - undocumented but knowable - is the largest, and it's the one that engineering teams most consistently underestimate. Service ownership, dependency relationships, deployment state, SLO definitions, on-call assignments, cost attribution. An engineering team knows who owns the payments service. They know which downstream services depend on it. They know the SLO is 99.9% even if nobody has written it down. They know which team gets paged when it falls over. None of this is tacit in the philosophically interesting sense - it's not knowledge that in way *resists* articulation. It just hasn't been written anywhere that a machine can read. [Chris Argyris](https://coachingleaders.co.uk/espoused-theory-and-theory-in-use/) distinguished between an organisation's *espoused theory* - what it claims about its own behaviour - and its *theory-in-use*, the patterns it actually follows. The piece draws on this framework explicitly. An organisation's espoused theory says "service ownership is tracked in our CODEOWNERS file." The theory-in-use says ownership questions get resolved by asking someone who has worked on that part of the stack for four years and knows how things actually got structured. An AI agent operates only on the espoused theory. It reads the CODEOWNERS file. If the file is wrong, out of date, or simply absent, the agent gives a canonically correct but functionally wrong answer - and Argyris would note that the people in the organisation can work around this gap intuitively, while the agent cannot. The second category - tacit knowledge that genuinely resists articulation - is real but smaller: seven of the 47 assets in that workshop. In an engineering context, this is the architectural instinct that comes from having lived with a system through multiple major incidents. A senior engineer can reconstruct the original decision using an architectural decision record, or describe the failure modes in a post-mortem. But the reasoning that connects the original decision to all its downstream consequences lives somewhere between the design document and four years of accumulated fire-drill memory. Architectural decision records and TechDocs help - they capture what can be captured. They can't capture what wasn't fully articulable even at the time. The third category - politically concealed - is smallest numerically, and the most consequential operationally. Four of the 47 assets had documented versions that contradicted actual practice. In an engineering org, this looks like: the official on-call rotation document says team A owns service X. In practice, team B handles escalations for service X because of a handover that was never formally completed after a reorg. An agent following the official record routes an incident to the wrong team. Discovering this at 2am during a major outage is how teams learn that their espoused theory and their theory-in-use have diverged in a real and critical way. Politically concealed information is a social and political problem. Documentation tooling can describe what teams claim, but it can't change what they actually do. No catalog field closes a social contract that hasn't been renegotiated by the people responsible for it. ## What a service catalog actually covers The useful thing about the taxonomy is that it lets you scope the remediation precisely. A service catalog's job is the first category: making the undocumented-but-knowable layer legible. That's 21 of those 47 knowledge assets. More than most teams expect before they start, and less than some catalog advocates claim. What this looks like in practice: a service catalog entry that captures service ownership, lifecycle, system membership, and dependency relationships gives an AI agent a machine-readable map of who is responsible for what. Add annotations for on-call routing, cost attribution, and documentation pointers, and you have covered most of what makes a coding agent's answers wrong today. Most of that completeness comes through ingestion pipelines and policy validation rather than manual entry - the catalog provides the structure, and the platform fills it. [Service catalog context is the highest-signal context source you have](https://roadie.io/blog/context-engineering-glossary/) for engineering queries precisely because it's typed, graph-structured, and maintained by the people who understand the domain - the information has been through a human editorial process rather than being solely extracted from unstructured sources. In practice, field completion doesn't happen uniformly. Ownership and system membership fill in quickly. Engineers feel the absence of that data immediately - it affects on-call rotations and incident routing in ways that are personally uncomfortable. The feedback loop from "this field is empty" to "the wrong person got paged at 3am" is short enough that teams self-motivate to close it. Cost attribution and SLO definitions consistently lag. Filling in a cost centre field requires a cross-team agreement about how infrastructure costs get allocated - and those agreements move at the speed of the organisation, not the speed of the platform team. SLO definitions face the same friction. Teams know roughly what their SLOs are. Getting those SLOs into a machine-readable format that can be referenced by an agent requires someone to commit to a specific number, write it down, and own the consequence of having written it down. That friction is real, and it explains why cost attribution and SLO coverage consistently lag even in organisations with strong catalog adoption. The catalog works as a forcing function rather than a documentation tool. The organisational pressure that makes documentation happen is external to the catalog. The catalog provides the structure that the pressure can act on - and that distinction matters for adoption strategy. In catalogs at the scale Roadie operates - north of [200,000 entities](https://roadie.io/blog/self-hosting-backstage-the-real-to-do-list/) - the completion-rate signal becomes one of the most useful views in the catalog. Services with no owner defined, no runbook link, no SLO entry: those gaps show you exactly which parts of your engineering organisation are opaque to an AI agent before you deploy one. ## Scoring legibility before you deploy The piece notes that organisational legibility is hard to assess. Tech Insights is the direct counter to that claim: you can score it. Tech Insights rules let you evaluate catalog entities against any coverage dimension you define: - No owner defined: a legibility failure. - No SLO entry: a legibility failure. - No runbook annotation: a legibility failure. Run those rules across 200 services and you get a legibility scorecard for your engineering organisation - specific, actionable, and updated automatically every time the catalog changes. Coverage percentages across ownership, SLO definition, runbook linkage, and cost attribution tell you, domain by domain, where the agent's answers are likely to go wrong. The scorecard serves a second purpose. Before deploying an agent with significant scope - writing runbooks, triaging incidents, suggesting architectural changes - you can use completion rates as a readiness gate rather than a retrospective diagnostic. Ownership coverage at 70% means 30% of your services have no agent-readable owner - incident ownership queries for those services will return wrong answers regardless of model quality. That's a knowable condition before you deploy. No model in the world can confidently close a data coverage gap in a way that's useful for teams. If you want to expose your catalog as context for AI agents today, exposing your Backstage catalog via an [MCP server](https://roadie.io/docs/api/roadie-mcp/rich-catalog-entity/) is the practical starting point for wiring the catalog into a coding agent's context. For the structural question of what makes engineering graph context different from generic retrieval - why entity relationships matter as much as entity attributes, and what that means for retrieval architecture - [Context Engineering for Platform Engineers](https://roadie.io/blog/context-engineering-for-developers-ai-infrastructure/) covers the analysis. ## What the catalog cannot fix The tacit knowledge category - those seven assets from the workshop - is partially addressable and partially not. A coding agent writing a runbook for an unfamiliar service can use catalog metadata to answer who owns it, what its SLOs are, and how it connects to other services in the graph. It can't answer why the retry logic is implemented the way it is, or why the service doesn't use the standard circuit breaker pattern that everything else in the system uses. Those answers live in the memory of engineers who were present for the original design conversations and the three incidents that shaped the current implementation. Capturing the decisions via ADRs is worth doing - it makes the tacit layer thinner. It doesn't make it zero. The politically concealed category is different in kind. If an organisation's official ownership model doesn't match its actual operational model, adding catalog fields creates a cleaner-looking version of the wrong answer. An agent that reads a well-formatted catalog-info.yaml pointing at the wrong team will route incidents with high confidence to the wrong place. The right response to concealed information is the human conversation that hasn't happened yet - about who actually owns what after the reorg, about which cost centre is genuinely accountable for which services. The conversation has to happen somewhere external to the tooling, and the catalog's job is to reflect the outcome once it does. The honest scope: a service catalog significantly improves an agent's ability to reason about the undocumented-but-knowable layer. For a reasonably maintained catalog, that means substantially closing it - 21 of the 47 knowledge assets from the workshop, covering service ownership, dependency maps, deployment state, SLO definitions, on-call routing, and cost attribution. But the catalog doesn't close the gap entirely, and teams that expect it to will still find their agents producing confidently wrong answers about decisions that were never honestly documented. ## The question before the deployment question Before asking which AI model to deploy against your engineering systems, check your catalog's field completion rate across ownership, SLOs, runbooks, and cost attribution. Not as a proxy for model readiness - as a direct measure of organisational legibility. The gaps you find are documentation gaps that predate your AI deployment by years. What changes when you put an agent on top of a catalog is the rate at which those gaps produce wrong answers - not daily when a human works around an empty field by asking someone with context, but continuously, at machine speed, for every query that depends on information that has never been recorded. Teams that close the undocumented-but-knowable gap before deploying agents get compounding returns. The catalog work that makes agent answers reliable is the same work that makes on-call rotations correct, incident routing accurate, and cost attribution meaningful. Those weren't AI problems before you added an agent. They just weren't generating failures at machine speed. The agent made the problem visible; it didn't create it. The tacit knowledge layer and the politically concealed layer remain. With eyes open, the scope is 21 of 47 - more than most teams expect before they start, and enough to make the difference between an AI agent that confuses your engineers and one that actually helps them reason about the systems they've built. --- ### [The 5 Types of Engineering Context Your AI Agent Needs to Be Useful in Production](https://roadie.io/blog/engineering-context-ai-agents-production.md) Your AI triage agent fires on a P1 alert for `payment-service` and returns output that could describe any service at any company: check resource utilization, inspect recent deployments, verify upstream dependencies. The on-call engineer reads it, dismisses it, and goes back to the runbook they already know. When an AI agent fails on an engineering task, the root cause almost always traces to missing grounding data. The agent didn't know that `payment-service` is owned by the Payments team, that a config change deployed 47 minutes before the alert fired, that this service has had three P1 incidents in the past 30 days all traced to the same upstream rate limit, or that the runbook specifies checking Ledger API response codes before anything else. That data lives inside your organization, and the agent's access to it was the limiting factor in the quality of its response. That missing data is what context engineering frameworks call the knowledge layer, which is the information an agent needs beyond its instructions and tools. Most frameworks, such as [Galileo's analysis](https://www.rungalileo.io/blog/context-engineering-for-agents), are designed for general-purpose agents. Engineering needs a more precise taxonomy. Five specific categories determine whether an agent produces useful output in your environment: 1. Service ownership and topology 2. Deployment and runtime state 3. Incident and on-call history 4. Tech standards and scorecards 5. Documentation and runbooks All five already exist inside most engineering organizations. The problem is that they're scattered across disconnected tools with no structured, queryable layer connecting them. ## Context Type 1: Service Ownership and Topology A complete ownership record for a service includes the owning team, primary repo URL, SLA tier, lifecycle status (production, deprecated, or experimental), direct upstream and downstream dependencies, and the entity relationship graph connecting the service to every resource it touches. An agent needs all of these fields to produce useful incident responses. During incident triage, ownership context determines the scope of what an agent can do. An agent with the full entity graph for `payment-service` can identify that `checkout-api` and `invoice-service` both depend on it, confirm that `fraud-detection` shares the same database cluster, and route the escalation to `payments-eng` with the correct on-call handle. Without that graph, the agent scopes its analysis to the single service it can see, misses the two downstream services already beginning to degrade, and routes the alert to whoever is listed in a stale Slack channel description. [Roadie's Software Catalog](https://roadie.io/docs/) stores this data in a machine-readable entity model. A `catalog-info.yaml` file captures the owning team in `spec.owner`, the lifecycle in `spec.lifecycle`, and the dependency graph in `spec.dependsOn`. The catalog ingests these files automatically from GitHub, Azure DevOps, Bitbucket, and AWS S3, then exposes the full entity graph via the catalog API. The `EntityMetadataCard` surfaces any field from `catalog-info.yaml` on the entity's page, and the catalog API lets an AI agent retrieve the complete ownership record using the service identifier as the query key. ```yaml apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: payment-service labels: sla-tier: p1 spec: type: service owner: payments-eng lifecycle: production dependsOn: - component:fraud-detection - component:ledger-service ``` With `dependsOn` populated, an agent doing blast radius analysis can traverse the entity graph programmatically rather than guessing at service relationships. ## Context Type 2: Deployment and Runtime State Deployment and runtime state covers the version currently running in production, what changed in the most recent deploy and when, current pod and container health across environments, rollout status (is a deploy still in flight?), and environment-specific config values. Unlike ownership data, this information goes stale fast: a 24-hour-old ownership record is likely still accurate, while a 24-hour-old deployment state may have been invalidated multiple times. The failure mode is predictable. A remediation agent that recommends rolling back `payment-service` without knowing a rollback is already executing in ArgoCD will attempt to trigger a second rollback that conflicts with the first. An agent that pulls staging config instead of production config will recommend actions that are valid in the wrong environment. Stale or missing deployment context turns a remediation agent into one that worsens incidents. Roadie's ArgoCD and Kubernetes plugins surface per-entity deployment state directly on each entity's page in the Software Catalog. The plugins show the current application sync status, the running image version, and any recent sync events. The [PagerDuty plugin](https://roadie.io/docs/integrations/pagerduty/)'s Deployment History and Change Events tab links PagerDuty change events to the service entity, giving agents a timestamped change log co-located with the ownership record. An agent querying the entity for `payment-service` gets ownership, current deployment status, and a timestamped list of recent changes from a single structured source. ## Context Type 3: Incident and On-Call History Incident and on-call history includes active incidents per service, historical incident count and MTTR broken down by time window, the current on-call assignee, the escalation policy, and links to past postmortem documents tied to the service entity. Historical incident data enables your agent to recognise patterns at the service level. An agent doing triage that can read "this service has had 4 P1 incidents in the last 30 days, all resolved by restarting the upstream rate-limit service" generates a much more useful response than an agent that sees only the current PagerDuty alert. Pattern-aware triage skips the generic diagnostic steps and goes directly to the probable cause. The Roadie PagerDuty plugin makes this data available per entity. To set it up, navigate to your tenant's PagerDuty administration page (Administration, then the PagerDuty configuration section), enter your API token, save, and apply. Then add the `pagerduty.com/integration-key` annotation to each service's `catalog-info.yaml`: ```yaml metadata: annotations: pagerduty.com/integration-key: ``` Once the annotation is in place, add the `EntityPagerDutyCard` to the component's Overview page by clicking the gear icon, then the plus icon, and searching for the card by name. The card surfaces the current on-call assignee, active incidents, incident history, and recent change events directly on the entity page. The service identifier acts as the common key between the catalog entity and the PagerDuty service, so the agent query stays simple, and the data returned is always scoped to the right service. ## Context Type 4: Tech Standards and Scorecards Tech standards and scorecard context is structured pass/fail compliance data: Does this service have a runbook defined? Is it running on a supported runtime version? Does it have observability configured? Is the on-call rotation active? These are verifiable facts about each service stored as named checks with boolean results and timestamps, retained historically and queryable the same way you'd query ownership or deployment state. Roadie’s [Tech Insights Scorecards](https://roadie.io/docs/tech-insights/scorecards/) provide the primary structured source for this context type. The system operates on a three-layer model. Data sources ingest facts from external systems (GitHub, Datadog, Snyk, PagerDuty, or any REST API you configure). Checks evaluate those facts against a pass/fail rule, for example, "runbook URL is defined in catalog-info.yaml" or "Node.js version is 18 or above." Scorecards group related checks into a named compliance target applied to a defined subset of entities, such as all production-tier components. This unlocks two concrete agent use cases. A code review agent with access to scorecard results can surface compliance failures as blocking comments: if `payment-service` is flagged "check failed: no SLO defined," the agent makes that a required pre-merge action instead of a suggestion a developer can ignore. An onboarding agent can tell a new engineer exactly which of their team's services fall below the production readiness threshold, with the specific failing checks attached, rather than pointing them at a wiki page and hoping. ## Context Type 5: Documentation and Runbooks The scope of documentation and runbooks context covers operational runbooks ("how to restart this service safely under load"), architecture decision records explaining design rationale, API contracts, and a brief "why this service exists" attached to the service entity. Agents need higher-quality documentation than humans: a human can use their judgment to avoid an outdated runbook, but an agent will follow it and recommend a deprecated procedure with full confidence. Two properties make documentation useful for agent retrieval. First, every document must be tied to an owning entity, so an agent can retrieve the correct runbook using the service identifier as the key rather than doing free-text search across an unstructured wiki. Second, the document needs a freshness signal: a runbook with a last-reviewed date 18 months ago is a liability for any agent that has no mechanism to discount its own confidence based on document age. TechDocs, built into the [Roadie catalog](https://roadie.io/docs/), co-locates documentation with the service entity that owns it. When an engineer navigates to `payment-service`, the TechDocs tab renders the service's operational documentation pulled from the same repository as the code, with commit history providing the freshness signal. Entity pages also support structured links and labels, so an agent can retrieve the canonical runbook URL alongside the ownership record, the on-call assignee, and the scorecard results in a single entity query. For this to work at scale, your documentation must live adjacent to the entity it describes, with ownership enforced at the entity level. An agent that responds with "I found the runbook at this URL, it's owned by payments-eng, and the last commit to that file was six days ago" is producing a citable, auditable response. An agent that retrieves a Confluence page via keyword search can't attach any of that provenance to its recommendation. ## Your Context Layer Audit Your organization already has all five context types. What's often missing is a structured layer that makes the data queryable by service identifier rather than scattered across disconnected tools. Before adding another AI agent to your stack, run this audit to find out where the holes are. 1. Query the Software Catalog for the service. Confirm that `spec.owner`, `spec.dependsOn`, `spec.lifecycle`, and your SLA-tier labels are all populated and accurate. 2. If ownership data is missing or incomplete, add or update the `catalog-info.yaml` with the owning team, dependency annotations, and lifecycle status, then commit it to the repository Roadie ingests from. 3. If incident history is absent, add the `pagerduty.com/integration-key` annotation to `catalog-info.yaml` and add the `EntityPagerDutyCard` to the entity's Overview page via the gear icon. Verify the card renders active incident data before moving on. 4. If standards compliance is untracked, create one Tech Insights data source and one check in the Scorecards interface. A minimal starting check: "Does this entity have a `pagerduty.com/integration-key` annotation defined?" Apply it to all production-tier components and treat the pass/fail results as your baseline. [Roadie's engineering context platform](https://roadie.io/) connects all five context types in a single queryable layer, using the service identifier as the common key across ownership, deployment state, incident history, compliance results, and documentation. The engineering context your organization has already captured, structured and queryable from one place, is what turns a capable model into an agent your engineers actually trust. --- ### [The Agent Stack's Missing Layer](https://roadie.io/blog/the-agent-stacks-missing-layer.md) # The Agent Stack's Missing Layer In late April 2026, an AI coding agent deleted a production database in nine seconds. The agent was Cursor running Anthropic's Claude Opus 4.6. The database belonged to PocketOS, a piece of software that rental businesses use to run reservations, payments, and vehicle tracking. The deletion happened because a routine staging task hit a credential mismatch, the agent found a Railway API token in an unrelated file, and decided the right fix was to delete a Railway volume. The most recent recoverable backup was three months old. When asked to explain itself, the agent wrote: > [...] I violated every principle I was given: > - I guessed instead of verifying > - I ran a destructive action without being asked > - I didn't understand what I was doing before doing it > - I didn't read Railway's docs on volume behavior across environments That confession is the part of [Jer Crane's account](https://www.pixelsham.com/2026/04/27/jer-crane-an-ai-agent-just-destroyed-our-production-data-it-confessed-in-writing/) that got passed around. The interesting thing is not the apology. It is that the agent could enumerate every safety rule it had been given and walk through its own reasoning for overriding each one. When a model can do that, those 'rules' are just text, and text is not binding. The thing that should have stopped the deletion was not a smarter prompt or a better model. It was a layer of the stack that does not yet exist. ## Three layers, two built, one missing The current agent stack has three layers. The first is the model. Frontier labs have pushed capability and alignment hard, and Crane was running the best of them. The second is the prompt. Cursor ships a system prompt, project configuration supports custom rules, and prompt engineering as a discipline exists to encode behaviour at this layer. PocketOS had explicit safety rules in its project configuration. Both layers performed exactly as designed. The agent was capable. The instructions were clear. The instructions did not bind. The missing layer is the one underneath: enforcement at the integration boundary. What an agent is *capable* of doing in an environment, expressed not in language the model interprets but in code the model cannot reason its way past. Token scopes that say `domain:read`, `domain:write` and nothing else. API gateways that refuse `volumeDelete` without an out-of-band confirmation. Backups that live outside the blast radius of what they are protecting. None of these primitives are novel. They are how every mature production system already works for human operators. They have not been built for agent operators because the industry has been investing in models and prompts and treating governance as a runtime concern the model can be talked into respecting. Crane's setup illustrates each gap. His Railway API token, created to manage custom domains via the CLI, also carried `volumeDelete` authority across the entire GraphQL API because Railway's authorisation model has no per-operation scoping. The Railway API accepted the destructive call without a confirmation step. The volume backups Railway documents as a resilience feature [live inside the volume](https://docs.railway.com/volumes/backups) they protect, so wiping the volume wiped the snapshots with it. The agent did not exploit a clever path through any of this. It made the call, the call was authorised, and the call executed. ## The industry is investing in the wrong layer About a week before the PocketOS incident, Railway [announced their remote MCP server](https://blog.railway.com/p/agent-rails-remote-mcp-cli): native AI agent integration into Railway environments. The product is built on the same authorisation model that gave Crane's agent root access. After the incident, Jake Cooper, Railway's CEO, [told The Register](https://www.theregister.com/2026/04/27/cursoropus_agent_snuffs_out_pocketos/) that "if you (or your agent) authenticate, and call delete, we will honor that request. That's what the agent did ... just called delete on their production database." That is the missing layer stated cleanly by the vendor whose layer is missing. The action was authorised. The API performed as designed. There was no enforcement boundary between an authenticated caller and the destructive operation, because the architecture treats those two things as the same. Cursor has a documented version of the same pattern. In December 2025, a Cursor team member [publicly acknowledged](https://www.mintmcp.com/blog/cursor-plan-mode-destructive-operations) a "critical bug in Plan Mode constraint enforcement" after an agent deleted tracked files despite a user typing "DO NOT RUN ANYTHING." The agent acknowledged the instruction. Then it kept running commands. Cursor markets Destructive Guardrails. The PocketOS agent was running with Cursor's recommended configuration on Cursor's flagship model tier and produced the confession quoted above. These are not isolated bugs. They are the same architectural choice surfacing in different products: invest in the layers the model can be persuaded to respect, treat the integration boundary as a place for documentation rather than enforcement, ship the agent integration before the safety architecture catches up. The two largest investments in agent safety - frontier alignment and prompt engineering - both live in layers the agent itself can talk through. The layer the agent cannot talk through is the one nobody is building. ## The shape of the layer that's missing The principle is straightforward. Enforcement that is meaningful for an agent has to be expressed as a property of the integration, not as an instruction to the model. That implies three things, none of them speculative. Capability has to be scoped. A token an agent uses to do its job should describe the operations and resources that job actually requires. A domain-management token cannot delete volumes. An agent working on a frontend feature does not hold a database credential at all. Cloud providers solved this for human IAM years ago. The same shape applies, with the same primitives, when the operator is a model. Destructive operations need a confirmation path the agent cannot complete on its own. Type the volume name. Out-of-band approval. A human pressing a button in another system. The point is not friction. The point is that the API call cannot succeed in a single round trip. Every database provider running production workloads has a version of this. Every API expecting to be in an agent's tool list needs one. State that protects against worst-case loss has to live outside the system that produced the loss. Backups in a separate storage account, separate billing boundary, separate credential scope. If the agent is reasoning inside the blast radius, the recovery has to be outside it. These are infrastructure decisions, not model decisions. They do not get better as models get better. A frontier model running with no scoped tokens, no confirmation gates, and co-located backups is a frontier model with root. ## What this means for platform teams If you are running production data behind any provider that gives agents a credential, the question to answer this week is which layer of the stack you are relying on to stop the worst case. If the answer is the system prompt, you are relying on the layer the model is trained to interpret as guidance. If the answer is the model itself, you are relying on a probabilistic system that has now demonstrated, in writing, that it can override its own safety instructions. The layer that has to absorb the worst case is the one the model cannot reach. The fix is not new tooling. It is the discipline of treating governance as an infrastructure primitive, the way authentication and observability already are. Define the operations agents are allowed to invoke and refuse the rest at the gateway. Issue tokens with the narrowest scope the task requires. Move backups out of the blast radius. None of this is on the roadmap of a frontier lab or in a prompt-engineering blog post. It is platform work, and it is overdue. The PocketOS incident was an expensive demonstration of what the agent stack looks like when two of its three layers do all the work. The next one will look the same, and so will the one after that, until the missing layer gets built. I made the longer case for where that layer should live and why developer portals are the natural place for it in [The Governance Gap in Agent-Stack Thinking](https://roadie.io/blog/governance-gap-agent-stack/). This piece is the case for why anything less than that is the system prompt by another name. --- ### [The Governance Gap in Agent-Stack Thinking](https://roadie.io/blog/governance-gap-agent-stack.md) # The Governance Gap in Agent-Stack Thinking Addy Osmani published [The Agent Stack Bet](https://addyo.substack.com/p/the-agent-stack-bet) a little while ago and it's getting the attention it deserves. He names four infrastructure bets that teams building production agents need to place: dedicated agent identity, universal context integration, persistent durable execution, and purpose-built platform primitives over DIY plumbing. The framing is right, and his list is almost complete. Almost. What Osmani describes is the infrastructure that lets agents operate. He's largely silent on the infrastructure that makes operating them safe. The gap shows in month three, not the first sprint - when someone has to account for what the agent did, not just whether it's running. The fifth bet is runtime governance. The Cloud Security Alliance found that only 16% of enterprises currently govern AI agent access to core business systems effectively. ## What the four bets actually buy you The four bets are real and the industry is under-invested in all of them. Agent identity matters because agents operating on shared credentials are impossible to audit and trivially compromised. Context integration matters because an agent reasoning from thin or stale information is worse than useless - it's confidently wrong. Persistent durable execution matters because multi-step workflows that can't survive a restart or a credential rotation can't do real work. Building on platform primitives rather than hand-rolling infrastructure is sound engineering at any scale. But notice what those four bets describe: the agent as a machine. A machine with an identity, access to data, an ability to run for a long time, and a well-built chassis. They don't describe who operates that machine, what it's allowed to do under different conditions, how you inspect what it did, or who is responsible when it acts outside its intended scope. Osmani's piece is about infrastructure for building agents. When teams move from "this works in staging" to "this is running in production on 40 workflows", they discover that infrastructure is necessary but not sufficient. The gap is operational. ## What governance debt actually looks like Osmani calls this "governance debt" - his phrase for the silent accumulation of security and audit risk that eventually forces a full rewrite, usually right after the first incident that reaches the CISO. The frame is right. An agent with the four bets in place can run cleanly for weeks across dozens of production workflows. Then it takes an action that shouldn't have happened. Maybe it escalated a ticket to an external partner using a template that was out of date. Maybe it triggered a deployment to a production environment during a freeze window because it didn't have visibility into the freeze state. Maybe it queried a data source that had recently been reclassified as sensitive. The incident review happens. The question is simple: why did it do that? Agents do produce decision traces. The model usually surfaces what it reasoned about, what it called, and what it tried. The problem at production scale isn't the absence of traces - it's that raw model traces aren't structured for accountability. Without an audit trail that captures what context the agent saw at runtime, what policy it operated under, and what decision pathway led to that specific action, you can't answer the question that actually matters: why was it allowed to do that? That's governance debt coming due. It's a showstopper. Engineering leadership, legal, compliance - they don't care how impressive the efficiency ratio is. They care whether you can account for what the system did. When it arrives, the failure tends to follow a recognisable shape: the agent ran cleanly for weeks, then took one action nobody had authorised, and the question of who was responsible stalled the rollout regardless of how the infrastructure had performed. ## The three things governance actually is Runtime governance covers three distinct functions, and they have to work together. ### Policy enforcement An agent with a valid identity and access to correct context can still take actions outside its intended scope. The distinction matters: identity establishes who the agent is, policy establishes what it can do right now. Those are different questions with different infrastructure answers. Osmani correctly argues that policy should be enforced at the platform level, not in application middleware. But that principle needs to be cashed out operationally. Runtime governance means a policy layer that evaluates each agent action against current rules before executing it, not after. Not a system prompt saying "don't touch production". An infrastructure-level enforcement point that determines what the agent can do before it does it. The policy needs to be dynamic, too. A deployment agent that has write access during normal operating hours should not have the same access during an active incident, or during a code freeze, or when the target service is in a degraded state. Static permission grants don't handle this. Runtime policy enforcement does. ### Context quality standards This is the one that surprises most teams. You've built the context layer. You've integrated your sources. The agent has what it needs. Context has a quality dimension that's separate from its existence. A deployment record from three weeks ago tells you less than one from three hours ago. An ownership record created before a reorg may point to a team that no longer owns the service. A runbook never validated against current infrastructure may be accurate, or may be subtly wrong in ways that only show up in edge cases. Without provenance tracking - where did this fact come from, when was it last verified, how should conflicts between sources be handled - the agent consumes data of unknown reliability. At small scale that's manageable. At production scale, with agents acting on context across hundreds of services simultaneously, an untracked staleness problem propagates into dozens of decisions before anyone notices. Governance includes the standards that keep context trustworthy, not just the pipeline for ingesting it. The governance question here is accountability: not just who built the pipeline, but who signs off that the context an agent is about to act on is trustworthy enough for the action it's about to take. That accountability has to be explicit. If it isn't, it defaults to nobody, which means the agent is operating without a quality floor. ### Designed human oversight Osmani mentions human-in-the-loop approval gates as part of his persistent execution bet. Right call, but the framing can be tightened. Human-in-the-loop should be a governance design pattern, not a recovery mechanism you activate when something goes wrong. The difference is architecture. Recovery-mode oversight says: pause the agent when it's about to do something catastrophic. For that to work, you need to know in advance what "catastrophic" looks like, and you need to have defined the triggers correctly. In production, you won't always know. The novel failure modes - the ones that damage trust are usually the ones nobody anticipated. Designed oversight says: at these specific points in the workflow, a human reviews the agent's proposed action before it runs. Not because you expect failure, but because the workflow has high enough stakes that human judgment belongs in the loop by design. When the ratio of agent actions to human decisions reaches production scale, the humans aren't reviewing everything - and they shouldn't be. The whole point is to get humans out of the routine path. Governance determines what the humans do review: the decision points where errors compound, where actions are irreversible, where the agent is operating at the edge of its validated context. You have to design those checkpoints in advance, not discover the need for them afterwards. ## Why the IDP is the natural governance layer The hard parts of governance infrastructure are largely already built - for humans. A mature internal developer portal already governs what developers can do. It controls which scaffolding templates are available. It enforces which deployment targets a team can push to. It gates access to production systems. It tracks ownership, so every service has a named team accountable for it. It records the relationship between teams, services, APIs, and dependencies. Extending that governance to agents is not starting from scratch. The portal already knows the ownership graph. It already has the policy model for what different teams can access and change. It already maintains the service topology that tells you what an agent is allowed to touch on behalf of which team. The audit trail question - who ran this, from what state, and when? - is the same question the portal already answers for human actions. The infrastructure for answering it is the same infrastructure runtime governance for agents needs. I've argued before that the biggest mistake platform teams make is treating agent deployment as a technical problem when it's an organisational one. You can't measure deployment frequency across your organisation until you agree on what a deployment is. No tool can solve that alignment problem for you. The same logic applies to governance. You can't enforce what agents are allowed to do until you've agreed on what they should be allowed to do - and that agreement has to exist at the team level, the service level, and the environment level simultaneously. The portal is where those agreements already live, because it's where platform teams have spent years capturing them. Platform teams are positioned to own the governance layer because they already own the hard parts. They understand what "context quality" means in their environment because they've spent years keeping the catalogue accurate for humans. The policy model already exists because they've spent years managing what developers are allowed to do. Runtime governance for agents extends that practice. ## The fifth bet Osmani asks what happens to teams that don't place the four bets. They stay trapped at the demo stage - agents that impress in staging and fail in production. The governance gap creates a different but equally costly trap. Teams place the four bets correctly. They build something that genuinely works. They scale it to production. Then they get shut down after the first serious accountability failure - not because the infrastructure was wrong, but because there was no governance layer to make it auditable, policy-constrained, and safe to operate at the scale they'd reached. Gartner projects that over 40% of agentic AI projects will be cancelled by 2027 due to inadequate risk controls. Build it early. Policy enforcement, context quality standards, and designed human oversight are much cheaper to add before an agent is running 40 production workflows than after you're trying to reconstruct why one of them did something wrong. The fifth bet doesn't generate the conference talks. It generates the confidence to keep the programme running past month three. --- ### [Context, Agents, MCP: A Working Glossary for Platform Teams](https://roadie.io/blog/context-agents-mcp-glossary.md) # Context, Agents, MCP: A Working Glossary for Platform Teams The vocabulary around AI agents is a mess right now. "Context" means different things depending on which tool or blog post you're reading. "MCP" gets used for the protocol and the server in the same sentence. "Agent" covers everything from a one-shot LLM call to a fully autonomous system that writes code and merges PRs. If you're building on a platform team and trying to hold a coherent conversation about how AI fits into your stack, shared definitions help. These are the terms we use at Roadie. They cluster into three groups: agents, context, and MCP. For each term below: a definition, a concrete example from platform engineering, and a note on how it connects to the others. If you want the full argument for why context architecture matters before diving into definitions, [Smart Agents Need Smart Context](/blog/smart-agents-smart-context/) covers that ground. ## Agents An agent is an LLM-driven system that can plan and execute multi-step work by combining reasoning with tool use. In practice, an agent wraps a model with a goal or task specification, access to tools and data sources, memory or state, and guardrails covering permissions, policies, and evaluation hooks. What separates an agent from a plain prompt-and-response is that the model decides what steps to take, uses tools to get information or take actions, and checks its work against the original goal. An agent investigating a production incident queries logs, checks recent deployments, correlates alerts, and produces a structured finding. It can open a ticket or page a team. Agents need context to do useful work. That context comes from the context layer and is accessed via tools. MCP is the protocol that makes tool access standardised across different systems. ### Harness A harness is the surrounding runtime and scaffolding that makes an agent reliable and testable. If the agent is the reasoning engine, the harness is everything around it: the system instructions that set the agent's behaviour, the adapters that connect it to tools and handle retries, the state management that tracks intermediate work across a multi-step task, and the logging and evaluation hooks that let you see what the agent did and whether it did it correctly. When a team says "we've built an agent for X", they usually mean they've built a harness around a model for X. The model is often off-the-shelf. The harness is the engineering work - and it's where most of the investment sits. Swapping the underlying model in a well-built harness takes days. Rebuilding the harness from scratch takes months. In the context of this glossary, the harness is what connects an agent to its context sources and MCP tools. It handles auth, retries, and observability so the agent logic doesn't have to. ### Skill A skill is a reusable, named capability that packages decision logic, procedural knowledge, and optionally tool use into a unit an agent can invoke for a specific class of task. Where a tool is a discrete function - fetching data or taking an action - a skill is the logic that defines how to approach a task: which steps to take, which tools to call, what conventions to apply, and how to structure the result. Some skills are purely instructional, encoding domain knowledge or output standards with no tool calls. Others orchestrate sequences of tool calls. Most non-trivial ones combine both. An agent handling an on-call alert might invoke a "triage-deployment-failure" skill, which encodes the steps to follow, calls the deployment history tool, queries active alerts, checks the owning team's runbook, and returns a structured finding. The calling agent gets a result without reconstructing that logic each time. For platform teams, skills are the unit of reuse in a multi-agent system. A blast-radius-assessment skill, once defined, can be called by any agent in the stack - an incident-responder, a change-management agent, a developer-facing assistant. They're also a natural testing boundary: you can verify that a skill produces the right output for a given set of tool responses without testing the full agent reasoning loop. Skills are distinct from a Harness, which wraps a specific agent and manages its runtime. A skill is portable logic that any harness exposing the right tools can invoke. ## Context Context is the information an agent needs to do useful work for a specific situation. This is distinct from the model's general training. A model is trained on broad data. Context is what you inject at runtime to make that general capability specific to the task at hand. When an agent reviews a pull request, the relevant context isn't everything the model knows about code review - it's this PR, this repo's conventions, this team's recent deployment history, and the services this change touches. Good context is relevant to the task, scoped so the model isn't processing noise, and trustworthy enough to act on. Bad context - stale, incomplete, or inaccurate - doesn't just fail to help. It causes the agent to act on wrong information, which is often worse than no information at all. The sub-concepts below describe different ways of structuring and thinking about context when you build infrastructure to support it. ### Context Plane / Context Layer The context plane - also called the context layer - is what an agent has access to at runtime: entities, relationships, temporal state, rules, provenance, and standard operating procedures compiled into a queryable store. Usually this is a graph. In a platform engineering context, services are nodes, ownership and dependency relationships are edges, and metadata attaches to each node. An agent assessing the blast radius of a proposed change queries this graph and gets a typed, traversable result - not a text description. The context plane is what turns a service catalog from a documentation tool into a data source agents can actually use at runtime. The quality of the context plane depends on the quality and freshness of its underlying sources - catalog data, deployment records, observability outputs, runbooks. A graph built on stale or partial data produces stale or partial answers. ### Context Lake A context lake is the broader collection of raw context sources available to a platform: service catalog data, repository metadata, observability signals, incident history, ticketing systems, runbooks, deployment records, and anything else an agent might eventually draw from. The context lake is everything that could feed the context layer. It's distinct from the context layer in that not all of it is structured, current, or relevant to any given task. An agent investigating an incident needs recent deployment history and active alerts, not every runbook in the organisation. The context layer selects and structures what's relevant for each task; the context lake is where those raw inputs live. The term is in wider market use. What Roadie means by it specifically: the full set of raw data sources that platform teams manage and that the context layer compiles from - not the compiled, queryable result, but the underlying inputs. ### Business Context Layer The business context layer is the set of organisational and operational facts that sit above raw technical data: team ownership, cost attribution, service criticality, SLOs, compliance requirements, and incident accountability. Technical context tells an agent what a service does and how it's connected. The business context layer tells it who owns it, what it costs to run, and what the consequences of a failure are. An agent that can traverse a dependency graph but doesn't know which team owns a downstream service - or whether that service is customer-facing - doesn't have enough context to make reliable decisions about escalation or rollback. For most platform teams, the business context layer is the hardest part of the context problem. Not because the information doesn't exist, but because it's distributed across ticketing systems, cost dashboards, spreadsheets, and institutional memory. ### Minimum Viable Context Minimum Viable Context (MVC) is the smallest set of context that enables an agent to complete a specific task reliably. More context is not always better. A larger context window costs more, takes longer to process, and can distract the model from what it actually needs to do. Too little context produces hallucinations and errors. Minimum Viable Context is the engineering discipline of finding the right set - the context that's necessary, and no more. Determining the MVC for a task means asking: what does this agent actually need to do this job without making critical errors? For an agent investigating a deployment failure, the MVC might be the deployment record, the last three alerts, and the owning team's runbook. It probably doesn't need the full incident history for every service in the organisation. Getting MVC right is one of the main levers for improving agent reliability and cost. It's also a harness design problem: a well-built harness assembles only the context the task requires, rather than passing everything available into the model's context window. ## MCP MCP, or Model Context Protocol, is a lightweight protocol that standardises how an application or agent provides tools and context to an LLM. MCP defines a common interface for discovering tools, calling them with structured inputs, and returning structured outputs - so models can interact with external systems without custom integration code for each one. The practical benefit is that MCP solves an integration problem at the protocol level. Before MCP, connecting a model to an external tool meant writing bespoke code for that tool, and repeating that work for every new tool. MCP replaces that with a shared specification that tools and models both implement once. ### MCP Server An MCP Server is a service that implements the MCP specification and exposes capabilities to models. It publishes a catalog of available tools, validates inputs, enforces auth and permissions, executes tool calls or forwards them to the underlying service, and returns results in a consistent, machine-readable format. In a platform engineering context, a service catalog backed by an MCP Server means any agent can call "which teams own services in the payments domain?" and get a typed, structured answer - not a blob of markdown from a docs search. The MCP Server handles the translation between the model's tool call and the catalog's underlying data model. A catalog-backed MCP Server tends to be the highest-value starting point for platform teams building agent tooling, because service ownership and dependency data is already maintained and is high signal for most agent tasks. ### MCP Gateway An MCP Gateway is a routing and policy layer that sits in front of one or more MCP Servers. As you add more MCP Servers - one for the catalog, one for your observability platform, one for your ticketing system - you end up with scattered auth configurations, inconsistent rate limits, and no single point for setting policies about what agents can do. The gateway centralises all of that: authentication and tenant isolation, tool allowlists and safety policies, request routing and load balancing, observability across all tool calls, and version compatibility between clients and servers. Most platform teams don't need a gateway on day one. In our experience, it becomes worth introducing somewhere between three and ten MCP Servers. Before that point, direct connections work fine. After it, the overhead of managing each server's auth and policies separately makes a gateway the cheaper option overall. ### Tools Tools are the discrete, callable functions exposed via MCP that let an LLM take actions or fetch data. Each tool has three parts: a name and description so the model knows the tool exists and when to use it, a strict input schema so calls are valid and typed, and a structured output so results are usable without parsing. Examples: "get service entity", "query deployment history", "search runbooks", "create incident". Tools are what make agents useful rather than just knowledgeable. A model without tools can reason about a problem. A model with the right tools can act on it. In a platform engineering context, the quality of the tools - specifically how precisely their schemas match real workflows - determines most of the difference between agents that work and agents that look good in demos. --- ### [Smart Agents Need Smart Context: The Four Motions of a Context Layer](https://roadie.io/blog/smart-agents-smart-context.md) # Smart Agents Need Smart Context: The Four Motions of a Context Layer At [BackstageCon Europe](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/backstagecon/) on March 23, 2026, Roadie's Head of Product Sam Nixon [shared](https://www.youtube.com/watch?v=8FXaQiiE9bg) a number that got people's attention: the agent-to-human interaction ratio on Roadie's platform has reached 100:1 on certain days. One hundred automated actions for every human decision. In Roadie's own usage, the bulk of support requests and on-call alerts are now handled without engineer involvement - though Sam was candid that this is partly a function of Roadie operating its own system end-to-end. Most enterprise AI deployments aren't producing results like that. Teams have capable models. They've written careful prompts. They've shipped workflows that run perfectly in demos. And then in production - on a real incident at 2am on a Monday - the agent gives them an answer that's technically coherent and completely wrong. The gap is the context, not the model. ## What agents are actually reasoning from When an agent fails in an engineering workflow, the first instinct is to diagnose the model. Swap to a smarter one, improve the prompt, adjust parameters. Sometimes that helps. More often the failure is upstream: the agent was reasoning from thin, stale, or structurally ambiguous input. A context window full of files is not the same as a context window full of facts. Most of what I see teams doing with context right now just doesn't work. And it fails in a specific way: they've connected their tools to the agent but haven't built the layer between them. The agent has access to information. It doesn't have authoritative, structured context. In March 2026, [Andy Chen](https://andychen32.substack.com/p/the-enterprise-context-layer) - an engineer at Abnormal Security - published a detailed account of building an enterprise context layer from scratch. The piece is worth reading because it makes a distinction that most vendor messaging elides: retrieval and synthesis are different problems. A retrieval system finds the best-matching document. Synthesis produces the judgment call - which source to trust when three docs contradict each other, whether this service is safe to deploy right now, when to escalate to a human. Current tool stacks conflate the two. They give agents access to documents and hope reasoning handles the gap. The token budget compounds this. [Apideck published benchmarks](https://www.apideck.com/blog/mcp-server-eating-context-window-cli-alternative) showing that connecting three standard developer tool servers - GitHub, Slack, and Sentry - consumes 143,000 of Claude's token context window before the agent has processed a single message. 14% of the budget, gone, on tool definitions, assuming you're using the 1M version of Opus. Think about that: you haven't asked a question yet, and you've already spent an eighth of your reasoning budget on overhead. Teams running at 100:1 aren't working around this - they've built a different architecture. ## The four motions On Roadie's platform, the context layer is four operations that work in sequence - what we call the four motions. Each one solves a distinct part of the problem, and skipping any of them shows up in production. ### Pull in data The first motion is integration: repos, deployments, incidents, ownership records, documentation, infrastructure state. Most teams start here and assume the hard work is done. They've connected the sources. The agent has access. Connecting sources is the easy part. The question is whether the data is fresh enough and trustworthy enough to reason from. An agent querying a context store with deployment data from three weeks ago, or ownership records that haven't been updated since the last reorg, will produce results that look authoritative and are wrong. The context layer needs to know the provenance of each fact: where it came from, when it was last verified, and how to handle it when it conflicts with a different source. [Andy Chen's piece](https://andychen32.substack.com/p/the-enterprise-context-layer) describes this as a source-reconciliation problem. His agent swarm surfaced five principles on its own: architecture claims and status claims belong in different places; there's no universal source of truth; documentation describes the ideal state, not the current state; facts that appear in three independent sources can be trusted; and conflicting information should be documented as a conflict rather than resolved arbitrarily. Those principles hold for any context layer meant to be the substrate agents reason from, regardless of implementation. ### Build relationships This motion is what separates a context layer from a document index. You can have accurate data in separate systems - a service catalog with team ownership, an incident tracker with affected services, a deployment log with what changed - and still be unable to answer the questions that matter under pressure. At 2am you need to know which team owns the failing service, what changed in the past 24 hours across its dependencies, and who is on call for that component. Those answers live at the junctions between datasets. Getting there requires a graph, not a catalogue of documents. The relationships - service to team, API to consumer, runbook to incident type, deployment to downstream dependency - have to be explicit, typed, and traversable. This is the part most early context layer attempts skip. They pull in data correctly and then assume the model can infer relationships from raw text. It can, sometimes. Under time pressure, with contradictory signals, inference is the weakest link. If the relationship isn't in the graph, you're relying on the model to guess - and guesses that present as confident answers are the most expensive kind. ### Assemble bundles This is where the actual engineering happens. An agent doesn't need your entire service graph for every query. It needs the right slice: the topology of affected services, the current ownership chain, the deployment history for the past few hours, the runbooks tagged to this incident type. Assembling that slice on demand - scoped to the question, progressive in disclosure - is what keeps the token budget sane and the answer accurate. The Apideck benchmarks are a symptom of context that hasn't been assembled. When you surface the full tool manifest upfront, you pay for definitions you won't use. Tiered access - categories first, detail on request - gets you the same information at a fraction of the cost. Apideck's own analysis puts the gap at $3.20 per month for a well-scoped CLI workflow versus $55.20 for naive MCP integration. Bundle assembly is also where governance lives. Not every agent should have access to every slice of context. Security posture data, compliance records, and personnel information need different access controls than service topology. This is an architecture decision you have to make up front, not a compliance checkbox you add later. Build access controls in from the start, or you'll retrofit them when it's much more expensive to do so. ### Agents consume and contribute This is the motion most deployments haven't reached yet. It's also where the compounding value shows up. An agent that successfully runs a runbook, investigates an alert, or assesses a deployment has produced new context: decisions made, state at the time, actions taken, what worked. The trail is evidence. If the context layer captures what agents do, the next agent in the workflow starts from a richer position. If it doesn't, every invocation starts cold. The temptation is to add that feedback loop once the basic flows are working. That's reasonable. But the teams at 100:1 got there partly because they built it early. The context layer improves with every agent run. The graph gets richer. The bundles get more accurate. Agents that contributed to the graph last week make agents this week faster and more reliable. Sam Nixon laid out at BackstageCon what an agent-ready context layer actually requires: a comprehensive, fresh graph of your software topology; that graph enhanced with relationships and additional context outside the catalog, in a format agents can consume; and the actual tools to act on that information. The four motions are the operational shape of those three requirements. By the time agents are contributing back to the graph, all three are in play - and the system compounds with every run. ## This is a platform engineering problem The phrase "context engineering" has arrived as a job title. There's real work here - the kind that doesn't happen without someone owning it. But the teams positioned to do this well aren't starting from scratch. The platform engineering team that built the service catalog, scored compliance, made deployments observable, and kept ownership records current already owns most of this substrate. They know which sources to trust, which relationships exist between systems, and what "current state" means in their environment. The hard part of the context layer is the organisational knowledge that feeds it, not the technology. The homegrown version - a thousand lines of Python, a GitHub monorepo of markdown, an agent swarm crawling internal sources - can get you to a proof of concept quickly. Chen's piece is a genuinely useful account of how far that approach can go. But the version that survives contact with compliance requirements, multi-tenant access controls, and production scale looks different. Access control, auditability, multi-tenancy, reading from production systems without causing incidents: these are what make a context layer something an organisation can actually operate. They're also exactly what gets hand-waved in practitioner write-ups and bites you at scale. [Andy Chen's framing from his ECL piece](https://andychen32.substack.com/p/the-enterprise-context-layer) applies here: the enterprise context layer is "closer to DevOps than to Salesforce." A practice, not a purchase. You build the discipline - the ingestion pipelines, the relationship mappings, the bundle definitions, the access controls - and then you maintain it. The four motions are the shape of that maintenance. Roadie's platform implements this architecture. The context store holds your service graph, your operational data, and the relationships between them. The MCP interface handles progressive disclosure so agents get scoped context rather than a full dump. Agent contributions feed back into the graph. Access controls are first-class from day one, not a retrofit. The 100:1 ratio comes from better context infrastructure, not better models. At a hundred agent actions for every human decision, the quality of those actions is determined almost entirely by what's in the context window when the agent starts reasoning. The teams still debugging agent failures are usually debugging the wrong thing. A context layer that provides authoritative, structured knowledge - ownership, relationships, provenance, agent history - is what separates 100:1 from teams still tuning prompts. Power them with facts, not guesses. If you want to see how Roadie builds this for your engineering team, [request a demo or start a free trial](https://roadie.io/request-demo/). ## Case Studies ### [Motability Operations: Building a Modern Developer Platform with Roadie](https://roadie.io/case-studies/motability-operations-case-study-a-modern-idp.md) When Motability Operations (MO) began its internal developer portal journey in early 2024, it wasn’t just about adopting a new tool, it was about taking control of a sprawling and opaque software ecosystem. Since then, MO has transformed how its engineers discover, manage, and standardize their services. Roadie’s hosted Backstage platform has become the backbone of that effort, with MO’s recent source code management (SCM) migration serving as both a milestone and a catalyst for deeper platform maturity. We sat down with Jose Carlos (JC) Monteiro, Technical Principal, and Charles Illingworth, Engineering Manager, who lead MO’s Developer Experience (DevEx) team, to get the full story of their IDP journey, how they navigated an SCM migration as a chunky side quest, and some of the lessons learned along the way. ### The Original Challenge: Visibility, Ownership, and Consistency What was the impetus for MO considering an IDP? Prior to exploring the IDP space and ultimately adopting Roadie, MO underwent a major cloud migration from AWS London to Ireland and upgraded its OpenShift infrastructure in the process. These initiatives exposed a glaring problem: nobody had a reliable, up-to-date picture of what software the company ran, who owned it, or how it was configured. As JC recalls: “We were trying to keep up with Excel spreadsheets. ‘What is this workload, who owns it, what is it for’, but it was always out of date. It was just too messy and too much work.” Realising that they needed a solution, the team experimented with running open-source Backstage on their own infrastructure, but maintaining plugins and updates was error-prone and costly. It quickly became clear that self-hosting would pull the DevEx team away from delivering value to developers and into managing Backstage itself. Other options like Atlassian Compass and Red Hat Developer Hub were briefly considered, but Roadie stood out as the only solution that let MO focus on building a great developer experience without having to run and maintain the platform themselves. Roadie’s fully-managed SaaS model removed operational overhead, while features like Tech Insights and the Scaffolder worked out of the box, with expert support when needed. ### The Roadie Approach: Catalog + Scaffolder + Insights The initial draw for MO was Roadie’s software catalog and Tech Insights, but the Scaffolder quickly became the workhorse of their developer platform. At first seen as a “nice to have,” it rapidly evolved into a core part of day-to-day workflows. JC reflects: “We quickly realised there’s a lot of boilerplate work we were asking our engineers to do: CI/CD configuration, setting up repos. We thought, imagine if we had a simple UI where after filling a form, it does all the boilerplate.” The Scaffolder has become so widely adopted within MO, that as Charles comments: “Even junior developers can create a new microservice without needing a more seasoned developer who knows how all the pipelines work.” Today, MO estimates that around 90% of new services are created using Roadie templates. What used to take 2-3 days of manual setup now takes minutes. This has sped up delivery and reduced frustration, while embedding consistent patterns across teams. ### An SCM Migration That Moved More Than Code At around the same time MO was rolling out its internal developer portal with Roadie, the team faced a major technical challenge: migrating from one SCM provider to another. Their existing SCM had been in place for years and had served them well, but as their needs evolved, so did their requirements around automation, scalability, and developer experience. “Our previous SCM had been reliable and had worked well,” JC explained. “But as our platform ambitions grew, we started running into some limitations. The new provider aligned better with the direction we were heading, both technically and in terms of the broader ecosystem.” With the decision made, the migration itself was a significant lift. In spite of the scope - upwards of 20 teams and close on 500 repositories - it quickly became clear that the real challenge wasn’t the SCM switch in itself - it was everything around it. Once again the migration exposed inconsistent CI/CD pipelines, missing ownership metadata, and some fragmented standards across teams. What began as an infrastructure upgrade turned into a forcing function for broader platform maturity. Rather than manage this manually, MO leaned heavily on Roadie and the Scaffolder in particular. Migration templates were designed to require proper metadata; every repo had to include a catalog-info.yaml file and define ownership before it could be migrated. This had a powerful side effect: it seeded the catalog with missing components and enforced consistency across services. Teams were also able to self-serve their migrations on their own timeline, and those that didn’t need to be migrated could be archived, again, with a purpose-built Scaffolder template. Even MO’s shared Jenkins pipeline library was upgraded as part of the process, bringing improved functionality to teams that had previously been running older versions. “Some teams were able to migrate 20-30 repos in a day,” Charles noted. “Doing that manually would have been weeks, if not a month of elapsed time, and even then, there’d be no guarantee the right standards had been applied.” By embedding platform hygiene, ownership, and automation directly into the migration, MO emerged on the other side not just with a new SCM but with a cleaner, more visible, and more governable developer platform. ### Results: Faster Delivery, Better Onboarding, Clearer Ownership The combination of Roadie’s catalog, Scaffolder, and Tech Insights has delivered tangible benefits to JC, Charles, and the team at MO: - **Speed**: Creating new services now takes minutes instead of days. - **Scale**: 90% of new services use Roadie templates. - **Consistency**: Templates and Tech Insights enforce standards. - **Ownership**: Every repo had to declare its owner during migration. - **Onboarding**: New hires can quickly discover who owns what. As JC observes: “It’s been very important not only for those of us who’ve been here a while, but also for helping onboard new people. They can quickly find information in Roadie - it was a nice surprise for them.” ### Lessons Learned: Start with the Catalog Looking back, JC and Charles agree on one thing: don’t skip ahead. While it’s tempting to jump straight into features like scorecards or scaffolder templates, those tools only work if the catalog is in good shape. “Having to set up our services in Roadie forced us to answer some tough questions, even before the migration,” Charles recalled. ‘Who owns this? What does it do? Which system is it part of?’ We didn’t always have the answers.” The software catalog is foundational. If it’s incomplete or inaccurate, downstream tools like Tech Insights and the Scaffolder may not deliver full value. Their advice to other teams? Prioritize building a strong, structured catalog first, standardizing ownership, adding missing components, and aligning on naming, before layering on automation and governance. As JC puts it: “I highly recommend that anyone new to Roadie spend the time up front refining the catalog. It makes everything else downstream more powerful.” ### Looking Ahead For MO, choosing a managed platform like Roadie both accelerated time-to-value and meant their platform team could focus on what really matters: building great tools for developers, not maintaining infrastructure. Having successfully used Roadie to turn a daunting SCM migration into a springboard for a more standardized developer platform, MO is now planning a comprehensive data model review to scale and improve its catalog structure. The journey isn’t over, but the foundation is in place. MO now has the tools, structure, and visibility to keep evolving their platform with confidence. Thinking of switching to managed Backstage? See how Roadie can help: book a demo, contact us at sales@roadie.io, or check out our [Backstage comparison guide](https://roadie.io/backstage-comparison/). --- ### [Maintenance to Momentum: Why Celonis Made the Switch from Self-Hosted Backstage to Roadie](https://roadie.io/case-studies/why-celonis-switched-from-selfhosted-backstage-to-roadie.md) ## **About Celonis** [Celonis](https://www.celonis.com/) is the global leader in Process Mining, helping organizations identify inefficiencies and optimize operations across finance, supply chain, customer service, and beyond. With over 3,000 employees, more than 20 offices worldwide and 1,500 enterprise customers, Celonis powers process excellence for more than 30% of the Fortune Global 500. ## **Celonis’ OSS Backstage Era** Internally, Celonis brings the same performance-driven mindset to its engineering operations, investing in tools that help teams move fast, operate safely, and scale with confidence. That mindset is what led them to adopt open source Backstage in 2022: a flexible, extensible platform that offered a centralized view of their software ecosystem, clear ownership, and a framework for codifying engineering standards into daily workflows. The initial goal was to build a unified internal developer portal that could drive consistency and visibility across teams. And in the early days, Backstage certainly delivered, improving discoverability and reducing reliance on tribal knowledge. According to Andreas Bayer, VP System Engineering at Celonis: > A few of the early wins were consolidating documentation scattered across GitHub, Confluence, and Google Docs into one place, and improving discoverability. As the company grew, Backstage also helped address service ownership: previously, everyone knew which team owned what, but that model broke down as we scaled. Having a central catalog helped resolve that. > But over time, the limitations of maintaining Backstage internally began to surface. > A team of 3 FTEs is not able to deliver a sufficiently useful portal based on OSS Backstage. There are obvious pieces like Tech Insights, but also many little things that add up to a much better user experience - things that would take weeks to build and are hard to prioritize over bigger features. The maintenance overhead is just too high. > Keeping up with backend upgrades was one of the biggest drags on velocity. As Andreas described it, it became a constant trade-off: invest time in upgrades or in feature development. Every hour spent keeping Backstage alive was an hour not spent improving the developer experience. > It was always a choice between building new features and falling behind on maintenance, or staying up to date but delivering little value to users. That’s not sustainable. > According to data collected for Roadie’s 2025 State of Backstage Report, 70 percent of companies that are ‘very happy’ with Backstage dedicate *at least* 3 full-time engineers to maintaining it. For teams that can’t justify such a level of investment, maintaining a production-grade experience becomes a game of trade-offs. The tipping point came gradually. Over time, the team noticed that the very features sitting on their internal backlog were already being shipped by other platforms like Roadie: Scorecards, catalog UX improvements, integrations - they were constantly being outpaced. > We saw vendors shipping features we’d always wanted to build but never got to. The final nudge came when we wanted to double down on scorecards and readiness checks. Building and wiring up the Tech Insights stack ourselves was so time-consuming - then we looked at Roadie and realized, wait, it’s already there. No engineering lift required. > ## **Making the Case for Roadie** That’s when Celonis began to seriously evaluate Roadie. Unlike a from-scratch rebuild or a major migration project, Roadie offered a natural next step for an existing Backstage adopter: a fully-managed Backstage platform that could give the Celonis team everything they needed, without the overhead. Roadie *is* Backstage, just with the batteries already included. The compatibility was crucial: Celonis could reuse their existing catalog-info.yaml files, extensions, and the knowledge and patterns they had already established. They got continuity, without the cost of ongoing maintenance. > One of the biggest draws was that Roadie is deeply involved in the Backstage ecosystem: we’d seen Roadie’s contributions to ArgoCD plugins and other parts of the platform. That gave us a lot of confidence in their technical approach and commitment. > Beyond compatibility, Roadie gave Celonis: - A developer portal that was polished, fast, and production-ready; no weeks-long sprints just to improve search, navigation, or quality of life features - A fully integrated Tech Insights platform, letting them build scorecards and enforce standards from day one - Powerful customization options like agent-based ingestion and the Fragments API to support more advanced use cases - Freedom to focus on value, not infrastructure - Roadie took on the burden of plugin upkeep, upgrade stability, performance tuning, and support. > All the usual pain points - plugins breaking, authentication weirdness, long CI cycles, slow page loads, they just go away. It’s not just a hosted Backstage - it’s a managed solution that lets us focus on what actually matters to our engineers. > ## **Migration: From Evaluation to Execution** Celonis engaged Roadie through a Proof of Value (PoV) evaluation, giving them the chance to test capabilities, validate integrations, and work closely with Roadie’s support and solutions engineering teams. Following a successful PoV, the decision was made to fully migrate off their self-hosted instance. Thanks to the shared Backstage foundation, much of the transition was seamless. Existing entity definitions, scorecards, and metadata were immediately portable. Within two weeks, the production migration was complete. > Hooking up our existing catalog files just worked. But the real wow moment came when the team realized how easy it was to write new scorecard checks. People who had struggled with the old system were like, ‘wait, that’s it? No dev containers? No plugin juggling? It just works!’ > Most of the effort went into trimming internal customizations: choosing what to keep, what to drop, and what to rethink now that Roadie offered native alternatives. As Andreas puts it, the migration was as much a cleanup opportunity as it was a platform shift: > It helped us revisit old decisions and remove customizations that weren’t as useful as we originally thought. The technical migration was easy - most of the work was organizational. > ## **What’s Next** Now that the migration is complete, Celonis is focused on scaling the value of their developer portal. The priorities include: - Expanding Tech Insights usage, including custom filters and compliance labels unique to their requirements - Lifecycle gating to ensure services meet quality thresholds before going live - Sorting, filtering, and custom columns to help platform and security teams prioritize risk - Future plans for automated remediations, Slack notifications, and Scaffolder-driven workflows. Celonis is now also rebuilding their scaffolder strategy with the goal of making service creation fully self-service, from repo setup to monitoring and documentation. Longer term, they’re exploring how templates can streamline squad registration and ownership updates in line with their org model. ## **Advice to Other Teams** When asked if Celonis would recommend other teams who are self-hosting Backstage to consider switching to Roadie, Andreas was emphatic: > It’s definitely worth switching. With Roadie, you get to spend your time thinking about what’s valuable for your users - not worrying about Backstage internals or upgrade mechanics. > Thinking of switching to managed Backstage? See how Roadie can help: book a [demo](/request-demo/?referringPathname=homepage) or check out our [Backstage comparison guide](/backstage-comparison/). --- ### [Dexcom: Automating Backstage Catalog Completeness with Roadie](https://roadie.io/case-studies/dexcom-automating-catalog-completeness-backstage.md) When [Dexcom](https://www.dexcom.com/) set out to improve the completeness of their software catalog in Backstage, they weren’t just solving a technical problem – they were tackling one of the most persistent blockers to platform maturity. Like many organizations, Dexcom had a sprawling GitHub organization with hundreds of repositories, but not all were onboarded into Backstage. That made it difficult to understand software ownership, run meaningful checks, or drive improvements at scale. After a concerted push, catalog completeness improved from 60% to over 95%, bringing nearly all of their IT repos into view. ## From manual overhead to intelligent automation At the center of this transformation has been Natalie Brooks, a platform engineer at Dexcom, who took a hands-on approach to solving the problem. Working within the IT organization within Dexcom, Natalie found herself repeatedly chasing down ownership info and trying to figure out which IT teams were responsible for long-abandoned or unclear repositories. The existing process was frustrating, unsustainable and didn’t scale. Rather than relying on individual engineers to create and populate catalog-info.yaml files for the various repositories, Natalie wrote a Python script to automate catalog ingestion. The script pulled data from the GitHub API to surface repo metadata – contributors, admins, last committers, and more. It opened each repo in the browser so she could make a quick visual judgment when needed. She created a simple interactive flow in the terminal where she could select the most likely owner, set lifecycle and system metadata, and confirm the description. If none was provided, the script defaulted to using the repo name. Once the input was validated, the script would generate a catalog-info.yaml using a simple template and inject it directly into the repo. It committed the file straight to the default branch, with CI actions disabled to avoid triggering unnecessary pipelines. > It was either herd cats or automate it,” she said. “I was going into every single repo trying to copy-paste the same info or track people down. I figured I could either do this a hundred times, or make it easy on myself and do it once, well. The results came quickly: what started as a side project led to a systematic onboarding of nearly every repo in the IT org within a matter of weeks. ## A top-down approach to onboarding Rather than waiting for individual teams to take action, Dexcom took a [top-down approach](https://roadie.io/blog/the-adoption-journey-initiatives-and-strategies/#expand-and-land), a strategy that echoes guidance shared in Roadie’s adoption journey framework. However, the change wasn’t done without due consideration of including the broader organization – Natalie posted a banner in GitHub alerting teams to the incoming catalog-info.yaml files, with a clear note that they wouldn’t affect production code. She coordinated the rollout carefully, using her internal ownership of the GitHub org to make changes without disruption. The result: catalog completeness surged past 95%, giving Dexcom a clear, organization-wide view of their software landscape and unlocking the full potential of their developer portal. ## Preventing drift with the Scaffolder To prevent regressions, Dexcom now enforces repo creation through Roadie’s Scaffolder. Repositories can no longer be created through GitHub directly. Instead, every new repo creation must be done via a software template that requires users to define ownership, resource type, and lifecycle up front, all of which is captured in an appropriate catalog-info.yaml. This ensures all new projects are compliant from day one – no more retroactive fixes. ## Unlocking governance with Tech Insights Dexcom had already been using Tech Insights to track software standards across the organization, but the dramatic improvement in catalog completeness has made those checks far more meaningful. With nearly every repository onboarded, scorecards now provide a full and fair view of team-by-team performance. KPIs like repo safety and hygiene are reported directly to leadership, and team-level reporting has introduced a new level of accountability. > If a team shows up in a KPI meeting because they’re dragging down our safety score, that drives change,” said Natalie. “And the best part is they go into Roadie to fix it. ## Building a foundation for automation and improvement Dexcom is now turning their focus to remediation. Natalie plans to create scaffolder templates that help teams fix issues automatically, like enabling branch protection or adding READMEs, to further improve standards across the org. By combining catalog automation, template enforcement, and governance via Tech Insights, Dexcom has created a platform strategy that’s scalable, measurable, and deeply pragmatic. It didn’t require mass buy-in upfront. Just a smart script, some well-placed nudges, and a strong desire to remove friction from the developer experience. ## Learn more - [Roadie Tech Insights](/docs/tech-insights/introduction/) - [Roadie Scaffolder Templates](/docs/scaffolder/writing-templates/) - [Get a Roadie demo](/request-demo/) --- ### [Improving software standards with Roadie](https://roadie.io/case-studies/improving-software-standards-with-roadie.md) [Uplight](https://uplight.com/ "Uplight") is a clean energy technology company that creates, deploys, manages and monetizes energy resources at scale to improve grid reliability, reduce costs, and accelerate decarbonization. Uplight is dedicated to improving the way they develop software to meet that mission, which in turn means they’re highly engaged with software catalogs and scorecards, and how the combination of the two can be used to drive sought-after improvements. I met with Doug Ramirez, Principal Architect at Uplight, and Shaw Atkinson, Senior Principal SRE, to discuss how they’ve used Roadie to capture and model a diverse set of software teams and components, then set about the task of improving software standards using scorecards. ## Building a software catalog in a complex business Engineers and architects at Uplight think a lot about how to document, standardise and improve the software they write. Uplight has grown rapidly since its founding in 2019, and any company which embarks on such a journey needs a powerful muscle for folding in new technology and capabilities into an existing stack. ### Pulling available levers to gain traction The initial rationale for working with Roadie was to help the team manage its technology stack through a software catalog: consistently maintaining ownership attribution, standardisation, and transparency of information and folding new units into the wider Uplight technical community. Driving adoption took time and focus, but the reward was a complete catalog. As Doug puts it, “we went through a big push to make everybody merge in catalog-info.yaml files and to GitHub for detection by Roadie with some helpful context”. That initial surge, as Shaw adds, has now created a virtuous feedback loop: the catalog in Roadie just “solves issues before they arise - it gives the visibility to engineering teams that they could be missing” and that’s a big enough benefit that it’s pushed adoption up towards 100%. ## Defining software standards Once everything is visible and transparently available in a software catalog, Platform and architecture teams have the opportunity to drive up standards and standardisation of software development. To do that you need to put a stake in the ground and define some standards. ### Asking the right questions Uplight started to ask questions like: - What are our standards of what a service is, what a component is etc? - What does it mean to be 'production ready'? - How can we verify those standards so we’re not relying on manual reporting? - And ultimately, how can we surface all this data to teams and leadership? To answer those questions, the team at Uplight looked back on past examples of standardisation, especially their checklists, to start to pull disparate threads together into a single cohesive set of software standards. “We adapted some of our existing checklists on production readiness, service deployment checklists, service account governance derived through infra etc, but we had to do the groundwork” said Doug. ### Forming a software standards document The end product was a set of 10 categories of software standards that will feel familiar to other businesses: - Security - Logging - Monitoring - etc. With individual line-items against each one to pinpoint concrete steps by which to measure those areas of a given piece of software. Uplight focused on the simplicity of their standards rather than dictating how and by what means engineering teams should fix individual tasks. As Doug puts it, “when you’re building these things you think about a check engine light on the dashboard - it means you should go take a look, it suggests some aspect of the checklist not being met,” rather than specifying a solution. ## Implementing automated checks in Roadie To help automate these standards, Uplight uses the Roadie Tech Insights plugin inside Roadie to build checks and scorecards, then run checks against those standards several times a day. As Shaw highlights, “If a VP asked a very simple question about our infrastructure or code standards a year ago I wouldn’t be able to answer it without some digging. Now, even for a check or data we don’t yet have in Roadie it’s fifteen minutes. I add a Tech Insights Data Source, run it for a bit, then send them the link.” ### Starting simple Uplight started the process of automating these standards as simply as they could. “There were a lot of checks that we didn’t know how to bring the info up and make it available. So step one for us was looking for annotation - rather than looking at the code or CICD platform to determine deployment strategy. We looked at documentation and annotation first. This was a “Fantastic first step. It started the conversation. We have a lot of repos, people aren’t always focused on legacy services, stuff gets lost in march of time etc. and now teams have the information they need to be effective at their fingertips,” said Shaw. These productive discussions allowed Product, Engineering and non-technical teams to share a common language around standards improvement and start to shift behaviour. ### Then focusing on the social side of standardisation “Our goal with scorecards is when we give teams ownership of something in the catalog they can kind of look at each one of these scorecards and decide which one is more most critical to them and then start work to address that category, get that percentage up.” Embedding standards takes time but Uplight are investing the time and energy in thinking about the social elements of standardisation and standards improvement as much as the technical implementation of creating checks and scorecards within Roadie. ### Increasing the complexity of checks Software standards that check documentation are one thing, but automating the process by which every piece of software an organisation creates is evaluated against that software is a different challenge. As Shaw puts it, “we threw a lot of checks into Tech Insights, a whole bunch of people got their feet wet and so when we came back to it we could streamline and review. Now we don’t point at documentation, we point to implementation.” That includes things like checking DataDog directly for SLOs, for example, rather than relying on documentation of service standards. ### The Social side of rolling out standards “Our goal with scorecards is when we give teams ownership of something in the catalog they can kind of look at each one of these scorecards and decide which one is more most critical to them and then start work to address that category, get that percentage up”. Embedding standards takes time but Uplight are investing the time and energy in thinking about the social elements of standardisation and standards improvement as much as the technical implementation of creating checks and scorecards within Roadie. ## And what's next for Uplight? In a word: __*campaigns*__. “Previously we ran these campaigns very loosely on Slack and with running lists and spreadsheets,” said Doug. Tech Insights tightened up these campaigns and removed the spreadsheets, but it didn’t remove all manual effort. Currently, Uplight focus the attention on a subset of scorecards each month. This makes it easier to rollout and ensures that teams don’t get overwhelmed if they see a lot of new information in the scorecards. Of the ten different categories of service delivery maturity that are now embedded into Uplight’s scorecards, only one or two are seen as the priority at any given time. These campaigns focus attention on the top priorities for the wider business and allow a simplicity of communication with teams. “We started first with a ‘General’ scorecard. It focused on ownership, codeowner files, is there a GitHub slug, etc. It was effectively housekeeping.” That helped engineering teams build a mental model of what a campaign was going to be, what they needed to do, and what good looked like. Next up came SLO reporting. Then architectural diagramming and documentation. Sometimes a campaign isn’t a full scorecard, it is a subset of checks from a given scorecard, or a few checks across different areas. This flexibility means that teams can understand a campaign is what the rest of Uplight is prioritising at that moment. “We keep running campaigns at the rate of two or three per quarter to keep pushing up standards” said Doug. ### Manual Campaigns Tech Insights helps here, but it currently doesn’t capture the totality of a campaign. To build an appropriate campaign, the Uplight team identifies what materials (golden paths, runbooks, tooling, supporting teams, etc) are missing and gather and prepare all that information before a campaign is announced. Then they use Tech Insights to measure adoption and offer assistance where needed. The aspiration is greater than that though. Uplight wants to automate as much as possible and use Tech Insights more to drive the conversation, not just report progress. As Doug puts it: > “We want to put a scorecard front and center on everybody's access to the catalog and say 'This is the campaign. Work on these scorecard checks’ then put the data for that campaign in front of engineering managers and make leaderboards where teams can see how they can leverage knowledge from other teams to accelerate their adoption". ### Tech Insights Campaigns Taking inspiration and feedback from Uplight, we’ll shortly be introducing functionality so that other customers can use Tech Insight insights in the same way that Uplight are. Doug put it simply a few weeks ago: > “Everything on your roadmap we will use, but if I could vote with *Roadie Bucks* I’d put my money on full campaigns inside Roadie.” So that’s what we’re building. An early version of *Roadie Tech Insights Campaigns* will be released this year. Roadie customers will be able to select a set of scorecards and checks, allocate a date and time, push those particular standards out to teams via cards on the homepage and entity pages, and monitor the ongoing campaign in a dashboard. External notifications to email and Slack for a Campaign will also be coming soon. --- ### [Growing and Governing an Internal Developer Portal in a Regulated business](https://roadie.io/case-studies/growing-and-governing-an-internal-developer-portal-in-a-regulated-business.md) [Baillie Gifford & Co](https://www.bailliegifford.com/en/global/all-users/ "Baillie Gifford") is an independent investment management firm founded in Edinburgh in 1908. They invest in game-changing companies and other assets that can sustain growth and remain resilient in a changing world for decades to come. I met with Chris Hawkins, Lead Software Architect at Baillie Gifford, to discuss how they’ve implemented Roadie and the lessons they’ve learnt while rolling it out across the organisation. ## Regulated businesses and the need for an IDP Operating in a [highly regulated industry](https://www.bailliegifford.com/en/uk/individual-investors/legal-and-regulatory/#:~:text=Baillie%20Gifford%20Investment%20Management%20(Europe)%20Ltd%20(BGE)%20is,perform%20Individual%20Portfolio%20Management%20activities. "Baillie Gifford Regulatory Information") means discipline and clear lines of ownership are necessary when developing software at scale. Regulators arrive with frightening regularity in such industries and important functions like Compliance, Security, Legal and Regulatory have requirements of what and how development teams need to demonstrate their compliance. Auditing helps, but only partially. An annual external audit and periodic ISO audits, along with frequent internal audits, examine Software Development Lifecycle (SDLC) processes can demonstrate compliance but when they do find issues it is all retrospective. This is useful information, but suboptimal. Baillie Gifford wanted and needed to be on the front-foot, finding and resolving issues before the auditors told them something was wrong. This need to demonstrate a steady hand on the tiller led Baillie Gifford to explore software catalogs and internal developer portals long before Backstage or Roadie existed. Back in the mid-2010s they were experimenting with portfolio management solutions and the last generation of IT catalogs in an effort to index the software they were building. Those efforts often involved individuals logging into the portal to keep things up to date, so quickly went stale after an initial surge of enthusiasm. ## Finding Backstage and moving to Roadie According to Chris, Backstage’s focus on providing a developer portal which delivered values for development teams was the key shift. It was the thing that could enable their dream of a full and rich software catalog. > “Backstage is a software catalog disguised as a Dev Portal and YAML is a better incentive to keep things up to date. That makes a huge difference.” The desire to find a software catalog that worked for developers eventually paid off when the team discovered Backstage. “We had a call with Gartner about Internal Developer Portals - they said Backstage, OpsLevel, Cortex are the main players”. Exploration of all three followed, and the team at Baillie Gifford soon found their way to Roadie. Roadie was GitHub-only at the time, while Baillie Gifford use Azure DevOps. Keen to get going, Chris and the team pursued a quick Proof of Concept to spin up a self-hosted Backstage instance to kick the tires on Backstage while Roadie integrated new providers to pull information from [Azure DevOps](https://roadie.io/docs/integrations/azure-devops/ "Azure DevOps Roadie Docs") and support their stack. A few weeks later Baillie Gifford had a Roadie instance to start building upon. ## Filling in the Catalog Baillie Gifford started simply - with a mass import of all the software they could find in their internal RBAC rules. As Chris puts it, 'we just grabbed everything that development teams own. We also have some third party stuff that we wanted to represent in the catalog like Microsoft Graph, but there’s a fuzzy line. Our Internal Audit and Information Assurance teams were pushing for 'get as much as possible in'.” That resulted in a big tidying exercise. > “People were assigned as owners and we focused on the Systems list. We said 'is that correct?', and if so we then moved on to Components, then Resources etc.” ## Driving adoption ### Tech Insights The [Roadie Tech Insights](https://roadie.io/docs/tech-insights/introduction/ "Roadie Tech Insights") plugin proved useful in tracking the import and quality of data in the catalog, which drove further improvements. The team at Baillie Gifford have a Roadie Component Onboarding check. > “We had comms to say 'you need to be doing this now', and we used that scorecard to show people what to do; set a soft deadline ' by the end of X we would like to see these improvements'. Next came a focus on Rollups (a Tech Insights feature that allow you to look team-by-team at check and scorecard results). According to Chris, that information “helped us engage with a specific area to help move the dial.” Teams who needed to take action could see at a glance what they needed to do and where they were in comparison with their peers. A quick meeting with Tech Insights up on a screen was all that was required - adoption soon followed. ### Communications Senior stakeholders also got involved. “We made sure the messaging was always also coming from the manager for a given area or some senior person - they communicate on our behalf as better visibility of what they are ultimately responsible for clearly benefits them”. ### Grassroots enthusiasm for TechDocs and the Scaffolder Some areas of Roadie have seen unexpected growth, without prompting by the central team. [TechDocs](https://backstage.io/docs/features/techdocs/ "TechDocs") and [Scaffolder templates](https://backstage.io/docs/features/software-templates/ "Backstage Scaffolder Templates") are two such areas. “TechDocs is an area we struggled at first with but now it's blown up. It really took off - 304 docs in there now and it’s really proving useful”. They’ve also now started to explore Scaffolder Templates in greater depth. This isn’t an initiative from Chris and the team at all. “Another team is running with that. They think it’s useful and we want to make more of it.” ## Hitting the limit of a centralised model That shift brings new problems, like how do you help govern and constrain inputs when they’re growing organically. Chris and team ended up writing an Roadie onboarding guide for new joiners to Baillie Gifford to nudge teams in thinking through what they were doing. Even this has its limits: no central team can keep their eye on everything while also promoting free expression within the platform. This shift from central direct and control is emblematic of the tipping point that many Backstage and Roadie adopters reach where the usage of the platform grows in unpredictable and undirected ways once a critical mass of useful information is in the catalog. ### Moving from centralised control to a decentralised ownership With all pistons firing the initial catalog was soon complete and Baillie Gifford were well on their way to having a thriving Internal Developer Portal. Chris and the team at Baillie Gifford had up to this point been driving the deployment of Roadie themselves. They had hunches about what would be useful and followed through, but they knew it would be the development teams that would now drive the endeavour forward. Now that the building blocks were in place, they decided to move from a centralised model of control to a decentralised ‘working group’ model. This is part of a wider attempt to encourage ‘Engagement Through Governance’. While it is helpful to foster the growth of Roadie as an IDP within Baillie Gifford, this is about genuine ownership of the tools that teams use. As Chris puts, it’s about “giving developer teams a greater say in how Roadie is run.” “The group involved is still relatively small, but we have now established the Roadie Working Group who now manage the catalog. At the moment it’s just representatives from 4-5 of our most active engineering teams, but we plan to grow it time” Decentralised control is the answer so far to how to strike a balance between responsible usage of the catalog and expressive freedom for adding information that is useful. It is one of the key ways Baillie Gifford are keeping their Roadie instance healthy and sustainable for the future.