mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-04-17 23:53:24 +02:00
Adds a GitHub Actions workflow that: - Detects PRs that only modify README.md - Comments explaining we no longer accept new server additions - Directs contributors to the MCP registry instead - Allows updates/removals via /i-promise-this-is-not-a-new-server - Uses labels (readme: pending / readme: ready for review) for filtering - Minimizes bot comment after confirmation to reduce clutter Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%) Claude-Steers: 10 Claude-Permission-Prompts: 0 Claude-Escapes: 0
110 lines
4.5 KiB
YAML
110 lines
4.5 KiB
YAML
name: README PR Check
|
|
|
|
on:
|
|
pull_request:
|
|
types: [opened]
|
|
paths:
|
|
- 'README.md'
|
|
issue_comment:
|
|
types: [created]
|
|
|
|
jobs:
|
|
check-readme-only:
|
|
if: github.event_name == 'pull_request'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
steps:
|
|
- name: Check files and comment if README-only
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { owner, repo } = context.repo;
|
|
const prNumber = context.payload.pull_request.number;
|
|
|
|
const { data: files } = await github.rest.pulls.listFiles({ owner, repo, pull_number: prNumber });
|
|
|
|
if (files.length !== 1 || files[0].filename !== 'README.md') {
|
|
console.log('PR modifies files other than README, skipping');
|
|
return;
|
|
}
|
|
|
|
// Check if we've already commented
|
|
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
|
|
if (comments.some(c => c.user.login === 'github-actions[bot]' && c.body.includes('no longer accepting PRs to add new servers'))) {
|
|
console.log('Already commented on this PR, skipping');
|
|
return;
|
|
}
|
|
|
|
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['readme: pending'] });
|
|
|
|
await github.rest.issues.createComment({
|
|
owner,
|
|
repo,
|
|
issue_number: prNumber,
|
|
body: `Thanks for your contribution!
|
|
|
|
**We are no longer accepting PRs to add new servers to the README.** The server lists are deprecated and will eventually be removed entirely, replaced by the registry.
|
|
|
|
👉 **To add a new MCP server:** Please publish it to the [MCP Server Registry](https://github.com/modelcontextprotocol/registry) instead. You can browse published servers at [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io/).
|
|
|
|
👉 **If this PR updates or removes an existing entry:** We do still accept these changes. Please reply with \`/i-promise-this-is-not-a-new-server\` to continue.
|
|
|
|
If this PR is adding a new server, please close it and submit to the registry instead.`
|
|
});
|
|
|
|
handle-confirmation:
|
|
if: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/i-promise-this-is-not-a-new-server')
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
pull-requests: write
|
|
steps:
|
|
- name: Swap labels and minimize comments
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const { owner, repo } = context.repo;
|
|
const prNumber = context.payload.issue.number;
|
|
|
|
// Check if pending label exists
|
|
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number: prNumber });
|
|
if (!labels.some(l => l.name === 'readme: pending')) {
|
|
console.log('No pending label found, skipping');
|
|
return;
|
|
}
|
|
|
|
// Swap labels
|
|
try {
|
|
await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: 'readme: pending' });
|
|
} catch (e) {}
|
|
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['readme: ready for review'] });
|
|
|
|
// Find the bot's original comment
|
|
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
|
|
const botComment = comments.find(c =>
|
|
c.user.login === 'github-actions[bot]' &&
|
|
c.body.includes('no longer accepting PRs to add new servers')
|
|
);
|
|
|
|
// Minimize both comments via GraphQL
|
|
const minimizeComment = async (nodeId) => {
|
|
await github.graphql(`
|
|
mutation($id: ID!) {
|
|
minimizeComment(input: {subjectId: $id, classifier: RESOLVED}) {
|
|
minimizedComment { isMinimized }
|
|
}
|
|
}
|
|
`, { id: nodeId });
|
|
};
|
|
|
|
if (botComment) {
|
|
await minimizeComment(botComment.node_id);
|
|
}
|
|
|
|
// Only minimize user's comment if it's just the command
|
|
const userComment = context.payload.comment.body.trim();
|
|
if (userComment === '/i-promise-this-is-not-a-new-server') {
|
|
await minimizeComment(context.payload.comment.node_id);
|
|
}
|