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@v8 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 third-party server list has been removed from this README in favor of the [MCP Server Registry](https://registry.modelcontextprotocol.io/).', '', '👉 **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.', ].join('\n'), }); 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@v8 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); }