-
Notifications
You must be signed in to change notification settings - Fork 649
feat(mcp-capabilities): add MCP Capabilities plugins #9732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jh-sh
wants to merge
6
commits into
backstage:main
Choose a base branch
from
jh-sh:mcp-capabilities
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+27,132
−0
Draft
Changes from 3 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
fd0ffbe
init plugin templates scaffolding
jh-sh c4732ea
add mcp-capabilities plugins code
jh-sh d453791
add missing backend readme section and credits ofc
jh-sh 6350d17
review fixes and ttlMS and dupes refactoring
jh-sh d0e9675
refactor MCPClient to utilize @modelcontextprotocol's sdk
jh-sh 593bbf5
PR suggestions and small refactoring of overengineering
jh-sh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Changesets | ||
|
|
||
| Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works | ||
| with multi-package repos, or single-package repos to help you version and publish your code. You can | ||
| find the full documentation for it [in our repository](https://github.com/changesets/changesets) | ||
|
|
||
| We have a quick list of common questions to get you started engaging with this project in | ||
| [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) |
11 changes: 11 additions & 0 deletions
11
workspaces/mcp-capabilities/.changeset/add-mcp-capabilities.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| '@backstage-community/plugin-mcp-capabilities': minor | ||
| '@backstage-community/plugin-mcp-capabilities-backend': minor | ||
| '@backstage-community/plugin-mcp-capabilities-common': minor | ||
| --- | ||
|
|
||
| Introduce the MCP Capabilities plugins for native `API` / `spec.type: mcp-server` catalog entities. | ||
|
|
||
| - **Backend**: connects to each MCP server (streamable-http) to discover its tools, resources, and prompts. A catalog processor enriches the entity with a summary (capabilities, counts, and tool names for search), and an on-demand endpoint serves the full live detail. | ||
| - **Frontend** (new frontend system, Backstage UI): an overview card with the server's identity and capabilities, and a "Capabilities" tab listing tools, resources, and prompts. | ||
| - **Common**: shared types and a catalog model layer that additively extends the native `mcp-server` schema (existing entities remain valid). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| { | ||
| "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", | ||
| "changelog": "@changesets/cli/changelog", | ||
| "commit": false, | ||
| "fixed": [], | ||
| "linked": [], | ||
| "access": "public", | ||
| "baseBranch": "main", | ||
| "updateInternalDependencies": "patch", | ||
| "privatePackages": { | ||
| "tag": false, | ||
| "version": false | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| .git | ||
| .yarn/cache | ||
| .yarn/install-state.gz | ||
| node_modules | ||
| packages/*/src | ||
| packages/*/node_modules | ||
| plugins | ||
| *.local.yaml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| playwright.config.ts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| module.exports = require('../../.eslintrc.cjs'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # macOS | ||
| .DS_Store | ||
|
|
||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| lerna-debug.log* | ||
|
|
||
| # Coverage directory generated when running tests with coverage | ||
| coverage | ||
|
|
||
| # Dependencies | ||
| node_modules/ | ||
|
|
||
| # Yarn 3 files | ||
| .pnp.* | ||
| .yarn/* | ||
| !.yarn/patches | ||
| !.yarn/plugins | ||
| !.yarn/releases | ||
| !.yarn/sdks | ||
| !.yarn/versions | ||
|
|
||
| # Node version directives | ||
| .nvmrc | ||
|
|
||
| # dotenv environment variables file | ||
| .env | ||
| .env.test | ||
|
|
||
| # Build output | ||
| dist | ||
| dist-types | ||
|
|
||
| # Temporary change files created by Vim | ||
| *.swp | ||
|
|
||
| # MkDocs build output | ||
| site | ||
|
|
||
| # Local configuration files | ||
| *.local.yaml | ||
|
|
||
| # Sensitive credentials | ||
| *-credentials.yaml | ||
|
|
||
| # vscode database functionality support files | ||
| *.session.sql | ||
|
|
||
| # E2E test reports | ||
| e2e-test-report/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| dist | ||
| dist-types | ||
| coverage | ||
| .vscode | ||
| .eslintrc.js |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| approvedGitRepositories: | ||
| - '**' | ||
|
|
||
| enableScripts: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # MCP Capabilities for Backstage | ||
|
|
||
| Plugins that enrich native MCP server catalog entities (`kind: API`, | ||
| `spec.type: mcp-server`) with their live **capabilities** — the tools, | ||
| resources, and prompts each server exposes. | ||
|
|
||
| ## Plugins | ||
|
|
||
| - [mcp-capabilities](./plugins/mcp-capabilities/README.md) — frontend (new | ||
| frontend system, [Backstage UI](https://backstage.io/docs/getting-started/ui)): | ||
| an overview card and a **Capabilities** tab on the entity page. | ||
| - [mcp-capabilities-backend](./plugins/mcp-capabilities-backend/README.md) — | ||
| backend: connects to each MCP server, enriches its catalog entity, and serves | ||
| live tool/resource/prompt detail. | ||
| - [mcp-capabilities-common](./plugins/mcp-capabilities-common/README.md) — shared | ||
| types and the schema-extension catalog model layer. | ||
|
|
||
| ## How it works | ||
|
|
||
| Each `mcp-server` API entity declares its endpoint in `spec.remotes`. The backend | ||
| connects over the MCP streamable-http transport to discover what the server | ||
| exposes: | ||
|
|
||
| - a catalog **processor** writes a summary (capabilities, counts, and tool names | ||
| for search) onto the entity — powering the overview card and catalog search; | ||
| - an on-demand endpoint, `GET /api/mcp-capabilities/spec?entityRef=…`, returns the | ||
| full live tool/resource/prompt detail — powering the Capabilities tab. | ||
|
|
||
| The common package's catalog model layer **extends** the native `mcp-server` | ||
| schema additively (via `updateKind`), so entities that haven't been enriched yet | ||
| remain valid. | ||
|
|
||
| > **Frontend system:** these plugins target the **new** Backstage frontend | ||
| > system. Legacy-frontend-system support is a planned follow-up. | ||
|
|
||
| ## Local development | ||
|
|
||
| ```sh | ||
| yarn install | ||
| yarn start | ||
| ``` | ||
|
|
||
| ## Credits | ||
|
|
||
| Made at [EPAM](https://www.epam.com), with love for the community. ❤️ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| { "version": "1.52.0" } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "autoVersionBump": false, | ||
| "knipReports": false | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| { | ||
| "name": "@internal/mcp-capabilities", | ||
| "version": "1.0.0", | ||
| "private": true, | ||
| "engines": { | ||
| "node": "22 || 24" | ||
| }, | ||
| "scripts": { | ||
| "start": "backstage-cli repo start", | ||
| "tsc": "tsc", | ||
| "tsc:full": "tsc --skipLibCheck false --incremental false", | ||
| "build:all": "backstage-cli repo build --all", | ||
| "build:api-reports": "yarn build:api-reports:only --tsc", | ||
| "build:api-reports:only": "backstage-repo-tools api-reports -o ae-wrong-input-file-type,ae-undocumented --validate-release-tags", | ||
| "build:knip-reports": "backstage-repo-tools knip-reports", | ||
| "clean": "backstage-cli repo clean", | ||
| "test": "backstage-cli repo test", | ||
| "test:all": "backstage-cli repo test --coverage", | ||
| "fix": "backstage-cli repo fix", | ||
| "lint": "backstage-cli repo lint --since origin/main", | ||
| "lint:all": "backstage-cli repo lint", | ||
| "prettier:check": "prettier --check .", | ||
| "prettier:fix": "prettier --write .", | ||
| "new": "backstage-cli new --scope @backstage-community", | ||
| "postinstall": "cd ../../ && yarn install" | ||
| }, | ||
| "workspaces": [ | ||
| "packages/*", | ||
| "plugins/*" | ||
| ], | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/backstage/community-plugins", | ||
| "directory": "workspaces/mcp-capabilities" | ||
| }, | ||
| "devDependencies": { | ||
| "@backstage/cli": "^0.36.3", | ||
| "@backstage/cli-defaults": "^0.1.3", | ||
| "@backstage/e2e-test-utils": "^0.1.2", | ||
| "@backstage/repo-tools": "^0.17.3", | ||
| "@changesets/cli": "^2.27.1", | ||
| "knip": "^5.27.4", | ||
| "node-gyp": "^10.0.0", | ||
| "prettier": "^2.3.2", | ||
| "typescript": "~5.8.0" | ||
| }, | ||
| "resolutions": { | ||
| "@types/react": "^18", | ||
| "@types/react-dom": "^18" | ||
| }, | ||
| "prettier": "@backstage/cli/config/prettier", | ||
| "lint-staged": { | ||
| "*.{js,jsx,ts,tsx,mjs,cjs}": [ | ||
| "eslint --fix", | ||
| "prettier --write" | ||
| ], | ||
| "*.{json,md}": [ | ||
| "prettier --write" | ||
| ] | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # The Plugins Folder | ||
|
|
||
| This is where your own plugins and their associated modules live, each in a | ||
| separate folder of its own. | ||
|
|
||
| If you want to create a new plugin here, go to your project root directory, run | ||
| the command `yarn new`, and follow the on-screen instructions. | ||
|
|
||
| You can also check out existing plugins on [the plugin marketplace](https://backstage.io/plugins)! |
1 change: 1 addition & 0 deletions
1
workspaces/mcp-capabilities/plugins/mcp-capabilities-backend/.eslintrc.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); |
103 changes: 103 additions & 0 deletions
103
workspaces/mcp-capabilities/plugins/mcp-capabilities-backend/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| # @backstage-community/plugin-mcp-capabilities-backend | ||
|
|
||
| Backend for the MCP Capabilities suite. It connects to the MCP servers described | ||
| by native `API` / `spec.type: mcp-server` catalog entities (reading their | ||
| `spec.remotes[].url`) and exposes what they offer. | ||
|
|
||
| Two parts, both reading `spec.remotes` off the catalog entity (no duplicate | ||
| config): | ||
|
|
||
| 1. **Catalog module** (`catalogModuleMcpCapabilities`) — a processor that writes a | ||
| discovered summary (capabilities, counts, `serverInfo`, and a flat list of tool | ||
| names for catalog search) onto each `mcp-server` entity. Failures are skipped | ||
| gracefully, so an unreachable server never fails catalog ingestion. | ||
| 2. **Backend plugin** — an on-demand router, | ||
| `GET /api/mcp-capabilities/spec?entityRef=<ref>`, returning the full live | ||
| tool / resource / prompt detail for the Capabilities tab. | ||
|
|
||
| The MCP client speaks the streamable-http transport with the JSON-RPC handshake | ||
| (`initialize` → `notifications/initialized` → capability-gated | ||
| `tools/list` / `resources/list` / `prompts/list`), is SSE-aware, and handles the | ||
| `Mcp-Session-Id` header. | ||
|
|
||
| ## Installation | ||
|
|
||
| ```sh | ||
| yarn --cwd packages/backend add @backstage-community/plugin-mcp-capabilities-backend | ||
| ``` | ||
|
|
||
| ```ts | ||
| // packages/backend/src/index.ts | ||
| import { provideStaticCatalogModel } from '@backstage/plugin-catalog-node/alpha'; | ||
| import { mcpServerApiEntityModel } from '@backstage/catalog-model/alpha'; | ||
| import { mcpServerEnrichmentModelLayer } from '@backstage-community/plugin-mcp-capabilities-common'; | ||
| import { catalogModuleMcpCapabilities } from '@backstage-community/plugin-mcp-capabilities-backend'; | ||
|
|
||
| const backend = createBackend(); | ||
|
|
||
| // Native mcp-server kind + the additive enrichment model layer | ||
| backend.add( | ||
| provideStaticCatalogModel({ | ||
| layers: [mcpServerApiEntityModel, mcpServerEnrichmentModelLayer], | ||
| }), | ||
| ); | ||
|
|
||
| // Discovery: enrichment processor + on-demand /spec router | ||
| backend.add(import('@backstage-community/plugin-mcp-capabilities-backend')); | ||
| backend.add(catalogModuleMcpCapabilities); | ||
|
|
||
| backend.start(); | ||
| ``` | ||
|
|
||
| Register some native `mcp-server` entities, e.g.: | ||
|
|
||
| ```yaml | ||
| apiVersion: backstage.io/v1alpha1 | ||
| kind: API | ||
| metadata: | ||
| name: aws-docs | ||
| spec: | ||
| type: mcp-server | ||
| lifecycle: production | ||
| owner: group:default/guests | ||
| remotes: | ||
| - type: streamable-http | ||
| url: https://your-mcp-server.example.com/mcp | ||
| ``` | ||
|
|
||
| Verify: | ||
|
|
||
| ```sh | ||
| curl 'http://localhost:7007/api/mcp-capabilities/spec?entityRef=api:default/aws-docs' | ||
| ``` | ||
|
|
||
| ## Limitations | ||
|
|
||
| - **Network reachability (backend egress).** Discovery runs from the Backstage | ||
| **backend** — the catalog processor and the `/spec` route — which connect | ||
| _outbound_ to each server's `spec.remotes[].url` over the MCP streamable-http | ||
| transport. Your backend must therefore be able to reach every MCP server you | ||
| register. Servers on a private network, behind a VPN, or firewalled need the | ||
| backend to have a route to them (VPC/peering, allow-listed egress, or an HTTP | ||
| proxy). The browser never connects to the MCP server directly, so this is a | ||
| backend-egress concern, not a CORS one. | ||
| - **Unreachable or slow servers.** Discovery is time-boxed (15s in the catalog | ||
| processor, 30s for the on-demand `/spec` route). A server that is unreachable or | ||
| times out is skipped gracefully: the processor leaves the entity unchanged, and | ||
| `/spec` returns an error that the Capabilities tab surfaces. | ||
| - **Per-request auth.** Remotes requiring signed requests (e.g. AWS Bedrock | ||
| AgentCore Gateway, SigV4) are not yet signed — those remotes are skipped by the | ||
| processor and error from `/spec`. Per-remote auth is a possible enhancement (depends on how future backstage shift to `connections` plays out). | ||
|
|
||
| ## Development | ||
|
|
||
| `yarn start` in this directory runs the plugin standalone (see [`/dev`](./dev)). | ||
|
|
||
| ## Exports | ||
|
|
||
| - default — the backend plugin (mounts the `/spec` router) | ||
| - `catalogModuleMcpCapabilities` — the enrichment catalog module | ||
|
|
||
| ## Credits | ||
|
|
||
| Made at [EPAM](https://www.epam.com), with love for the community. ❤️ |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.