Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"integrations/roomote-mcp",
"integrations/asana",
"integrations/better-stack",
"integrations/buildkite",
"integrations/braintrust",
"integrations/cloudflare",
"integrations/elevenlabs",
Expand Down
32 changes: 32 additions & 0 deletions apps/docs/integrations/buildkite.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: Buildkite
description: Inspect Buildkite pipelines, builds, jobs, and tests from Roomote tasks.
icon: 'https://api.iconify.design/simple-icons:buildkite.svg?color=currentColor'
---

Connect Buildkite when tasks need CI pipeline, build, job, log, artifact, test,
cluster, agent, or queue context.

## How setup works

A deployment operator connects Buildkite once from **Settings > Integrations**
using OAuth. The built-in integration uses Buildkite's hosted
`/mcp/readonly` endpoint and requests its `read` scope. Buildkite's public OAuth
metadata supports dynamic client registration and PKCE, so self-hosted Roomote
deployments do not need a preconfigured Buildkite OAuth client.

The organization picker shown during authorization is a convenience, not an
access-control boundary. The connection can see organizations available to the
authorizing account, subject to Buildkite's permissions.

## Network restrictions

If a Buildkite organization uses an API IP allowlist, add Buildkite's published
MCP egress addresses to that allowlist. The hosted MCP server calls the
Buildkite API from Buildkite infrastructure.

## Verify the connection

Start by listing pipelines or inspecting a recent failed build. This built-in
connection is read-only; use a separately configured custom MCP server if a
different endpoint or token-backed toolset is required.
1 change: 1 addition & 0 deletions apps/docs/integrations/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ from [Personal Settings](/personal-settings).
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------ |
| <IntegrationName href="/integrations/asana" icon="asana" name="Asana" /> | Project and task context from Asana | Admin connection once |
| <IntegrationName href="/integrations/better-stack" icon="betterstack" name="Better Stack" /> | Monitoring and incident context | Admin connection once |
| <IntegrationName href="/integrations/buildkite" icon="buildkite" name="Buildkite" /> | Read-only CI pipeline and build context | Admin connection once |
| <IntegrationName href="/integrations/braintrust" icon="braintrust" name="Braintrust" /> | Prompts, runs, and evaluation context | Enable first, then teammates link accounts |
| <IntegrationName href="/integrations/cloudflare" icon="cloudflare" name="Cloudflare" /> | Cloud infrastructure and API operations | Admin connection once |
| <IntegrationName href="/integrations/elevenlabs" icon="elevenlabs" name="ElevenLabs" /> | Voice narration for feature-demo videos | Admin connection once |
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/components/settings/Integrations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ const DEEP_LINK_ENABLE_DESCRIPTIONS: Record<string, string> = {
'Roomote will be able to inspect monitoring, incidents, and telemetry.',
braintrust:
'Roomote will be able to inspect prompts, evaluations, and AI run history.',
buildkite:
'Roomote will be able to inspect Buildkite pipelines, builds, jobs, logs, tests, artifacts, and agents through a read-only connection.',
cloudflare:
'Roomote will be able to inspect Cloudflare resources and run explicitly requested API operations with the permissions granted during OAuth.',
grafana:
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/components/system/custom/logos/brand-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
siAsana,
siBetterstack,
siBraintrust,
siBuildkite,
siCloudflare,
siElevenlabs,
siDependabot,
Expand Down Expand Up @@ -43,6 +44,7 @@ const SIMPLE_ICONS: Record<string, SimpleIcon> = {
asana: siAsana,
betterstack: siBetterstack,
braintrust: siBraintrust,
buildkite: siBuildkite,
cloudflare: siCloudflare,
elevenlabs: siElevenlabs,
dependabot: siDependabot,
Expand Down
8 changes: 8 additions & 0 deletions apps/worker/src/mcp/roomote-mcp-server/integration-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ Sentry uses the workspace MCP integration:

Once connected, tasks can inspect Sentry issue and project context, and scheduled Sentry triage automation uses the same read-only MCP connection.

# Buildkite

Buildkite uses OAuth:
1. A deployment operator enables Buildkite from Settings > Integrations.
2. That operator connects Buildkite once for the deployment via OAuth.

Once connected, I can inspect pipelines, builds, jobs, logs, artifacts, tests, clusters, agents, and queues through Buildkite's read-only hosted MCP endpoint. Organizations that restrict API access by IP must allowlist Buildkite's published MCP egress addresses. Organization selection during OAuth is a convenience, not an access-control boundary.

# Cloudflare

Cloudflare uses OAuth:
Expand Down
7 changes: 7 additions & 0 deletions packages/cloud-agents/src/server/mcp-self-setup/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ export const MCP_SETUP_INTEGRATION_METADATA: Record<
string,
SetupMcpIntegrationMetadata
> = {
buildkite: {
capabilities: [
'Inspect Buildkite pipelines, builds, jobs, and logs',
'Review artifacts, annotations, tests, agents, and queues',
'Keep hosted MCP access read-only at the provider endpoint',
],
},
cloudflare: {
capabilities: [
'Search the Cloudflare API for available operations',
Expand Down
40 changes: 39 additions & 1 deletion packages/slack/src/__tests__/forwarded-message-context.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/slack/src/forwarded-message-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,10 @@ export function formatSlackMcpSetupRecommendationContext(
extractBlockLinks(blocks, links, seenKeys);
for (const attachment of attachments ?? []) {
if (isRecord(attachment)) {
const titleLink = getStringField(attachment, 'title_link');
if (titleLink) {
appendUniqueSlackBlockLink(links, seenKeys, { url: titleLink });
}
extractBlockLinks(attachment.blocks, links, seenKeys);
Comment thread
roomote-roomote[bot] marked this conversation as resolved.
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/slack/src/mcp-recommendations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const SLACK_ENABLE_DESCRIPTIONS: Record<string, string> = {
'Roomote will be able to inspect and manage shared email infrastructure.',
braintrust:
'Roomote will be able to inspect prompts, evaluations, and AI run history.',
buildkite:
'Roomote will be able to inspect Buildkite pipelines, builds, jobs, logs, tests, artifacts, and agents through a read-only connection.',
cloudflare:
'Roomote will be able to inspect Cloudflare resources and run explicitly requested API operations with the connected permissions.',
linear:
Expand Down
15 changes: 15 additions & 0 deletions packages/types/src/__tests__/mcp-oauth.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions packages/types/src/__tests__/mcp-service-detection.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions packages/types/src/mcp-oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,19 @@ export const MCP_INTEGRATIONS: McpIntegration[] = [
instructions:
'Sentry advertises only a few tools directly (find_organizations, find_projects, search_issues, search_events, get_sentry_resource). Reach everything else (issue details, event stack traces, breadcrumbs, tag values, issue events, releases, traces, replays, attachments, monitors, alert rules, docs) by calling search_sentry_tools with a short query, then execute_sentry_tool with the returned tool name and arguments. Which tools exist depends on the access the admin granted when connecting. Treat Sentry as read-only unless the request explicitly asks to change Sentry state: do not resolve, assign, ignore, or otherwise update issues, and do not create or modify projects, teams, DSNs, or monitors on your own initiative.',
},
{
id: 'buildkite',
name: 'Buildkite',
url: 'https://mcp.buildkite.com/mcp/readonly',
description: `Inspect Buildkite pipelines, builds, jobs, tests, and agents from ${PRODUCT_NAME} tasks`,
icon: 'buildkite',
connectionScope: 'deployment',
oauthResource: 'https://mcp.buildkite.com/mcp/readonly',
oauthScopes: ['read'],
oauthScopeMode: 'read-only',
instructions:
"Use Buildkite to inspect organizations, pipelines, builds, jobs, logs, artifacts, annotations, tests, clusters, agents, and queues. This connection uses Buildkite's provider-enforced read-only MCP endpoint; do not assume mutation tools are available.",
},
{
id: 'cloudflare',
name: 'Cloudflare',
Expand Down
37 changes: 37 additions & 0 deletions packages/types/src/mcp-service-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,44 @@ const X_POST_PATH_REGEX = /^\/[a-z0-9_]{1,15}\/status\/\d+/;
const X_APP_PATH_REGEX =
/^\/(?:search|explore)(?:\/|$)|^\/i\/(?:lists|communities|spaces)\//;

const BUILDKITE_PUBLIC_ROOT_SEGMENTS = [
'about',
'blog',
'changelog',
'community',
'customers',
'docs',
'features',
'legal',
'pricing',
'resources',
'security',
'support',
] as const;
const BUILDKITE_ORGANIZATION_PATH_REGEX = new RegExp(
`^/(?!(?:${BUILDKITE_PUBLIC_ROOT_SEGMENTS.join('|')})(?:/|$))[^/]+(?:/|$)`,
);

export const SLACK_MCP_SETUP_SERVICES: SlackMcpSetupServiceDefinition[] = [
{
id: 'buildkite',
Comment thread
roomote-roomote[bot] marked this conversation as resolved.
name: 'Buildkite',
availabilityKind: 'curated_oauth',
hostSuffixes: ['buildkite.com'],
excludedHostnames: [
'www.buildkite.com',
'api.buildkite.com',
'mcp.buildkite.com',
],
hostRules: [
{
hostSuffix: 'buildkite.com',
pathRegexes: [BUILDKITE_ORGANIZATION_PATH_REGEX],
},
],
deploymentSettingsPath: '/integrations',
userSettingsPath: '/settings/personal',
},
{
id: 'cloudflare',
name: 'Cloudflare',
Expand Down
Loading