Discord ↔ GitHub Issue Correlator
When to Use
Use this skill when:
- A user asks to "correlate", "match", or "find connections" between Discord discussions and GitHub issues
- They want to know which issues are being discussed in a Discord channel
- They need to prioritize issues based on community discussion activity
- They reference both a Discord server/channel and a GitHub repository
Trigger even when: The user doesn't explicitly say "correlation" — requests like "what GitHub issues relate to the auth-ig channel?" or "find issues discussed in Discord" should activate this skill.
Instructions
1. Gather Parameters
Required:
- Guild ID: Discord server ID (numeric string)
- Channel ID: Discord channel ID (numeric string)
- GitHub owner: Repository owner (e.g.,
anthropics) - GitHub repo: Repository name (e.g.,
claude-code)
Optional:
- Keywords: Domain-specific keywords to look for (auth, performance, etc.)
- Message limit: How many recent Discord messages to fetch (default: 100)
- Top correlations: How many correlated issues to show (default: 15)
2. Fetch Discord Messages
Use the guildbridge MCP server:
import * as guildbridge from './servers/guildbridge';
// IMPORTANT: read_messages returns a BARE ARRAY of message objects
// ({ id, author, content, timestamp, ... }) — NOT an object with a
// `.messages` property. Newest-first; paginate older with `before`.
const messages: any[] = [];
let before: string | undefined;
while (messages.length < MESSAGE_LIMIT) {
const batch = await guildbridge.read_messages({
channel_id: CHANNEL_ID,
limit: 50,
before, // for pagination (id of the oldest message seen so far)
});
const arr = Array.isArray(batch) ? batch : batch?.messages ?? [];
if (arr.length === 0) break;
messages.push(...arr); // each item: { id, author, content, timestamp }
before = arr[arr.length - 1].id;
}
Extract from each message:
- GitHub links (regex:
https?://github\.com/[^\s)]+) - Topics/keywords (case-insensitive matching)
- RFC references (regex:
rfc\s*\d{4})
3. Fetch GitHub Issues
Use the github MCP server. Prefer search over list_issues for large repos:
import * as github from './servers/github';
// Approach A: Targeted search (recommended for keyword-heavy domains)
const searches = [
`repo:${OWNER}/${REPO} is:open is:issue keyword1`,
`repo:${OWNER}/${REPO} is:open is:issue keyword2`,
// Add more searches for different keywords
];
for (const query of searches) {
const response = await github.search_issues({ query, per_page: 100 });
// Deduplicate by issue number
}
// Approach B: Full list (use only if search isn't applicable)
let cursor: string | undefined;
while (true) {
const response = await github.list_issues({
owner: OWNER,
repo: REPO,
state: 'open',
first: 100,
after: cursor
});
// ...
}
Extract: number, title, url, labels, createdAt, updatedAt, body (excerpt)
4. Score Correlations
For each issue, calculate a relevance score:
Topic matches (+2 per topic, weighted by Discord frequency):
- If a topic appears in the issue title/body, score += (Discord_mention_count × 2)
Direct links (+20 per link):
- If a Discord message links to this issue URL, strong signal
Label matches (+5 per relevant label):
- Check if issue labels include keywords (e.g., "auth", "mcp", "security")
Keyword overlap (+1 per significant keyword):
- Extract meaningful words from issue title (length > 4, not stopwords)
- If ≥2 keywords appear in a Discord message, score += matches
Recency boost (+5 if updated in last 30 days):
- Recent updates suggest active discussion
Comment activity (+0.2 per comment, max +10):
- High comment count indicates active discussion
5. Generate Report
Save three files to ./workspace/:
- Raw Discord data:
<channel-name>-messages.json - Raw GitHub data:
<repo>-open-issues.json - Markdown report:
<channel>-<repo>-correlation.md
Report structure:
# [Channel] ↔ [Repo] Correlation Report
Generated: [timestamp]
## Summary
- Discord messages analyzed: N
- Open issues analyzed: M
- Meaningful correlations found: K
- Top correlations shown: top 15
## Topics Extracted from Discord
| Topic | Mentions |
|-------|----------|
| topic1 | count |
## Top Correlated Issues
### 1. [#NUM] Issue Title
**Score:** X | **Comments:** Y | **Updated:** date
**URL:** link
**Labels:** label1, label2
**Matched Topics:** topic1, topic2
**Rationale:** matches topics X; directly linked in Y message(s); auth-related labels
<details>
<summary>Issue Description (excerpt)</summary>
> [First 300 chars of body]
</details>
---
## How to Read This Report
### Scoring
- Topic matches: weighted by frequency
- Direct links: +20 per link
- Auth labels: +5 per label
- Keyword overlap: multiple shared keywords
### Next Actions
1. Review top correlations
2. Cross-link Discord threads to issues
3. Triage using Discord context
4. Engage Discord participants in relevant issues
Gotchas
- read_messages return shape: it returns a bare array of message objects, not
{ messages: [...] }. Accessingresponse.messagesyieldsundefinedand silently looks like "0 messages" — the most common cause of an empty Discord result here. Always treat the result as the array itself (Array.isArray(batch) ? batch : batch?.messages ?? []). - Discord pagination:
read_messageswithbeforereturns older messages (pass the id of the oldest message seen). It is fast (≈1–3s for 50–80 messages). - GitHub auth errors:
list_issuesmay hit rate limits or auth failures mid-fetch. Wrap the loop in try-catch and save partial results. - Pull requests in issue lists: Some APIs return PRs in issue endpoints. Filter with:
if (issue.url?.includes('/pull/')) continue; - Score normalization: Scores are relative, not absolute. A score of 40 vs 10 is meaningful; 40 vs 38 might not be.
- Large repos: anthropics/claude-code has 3500+ issues. Use
search_issueswith targeted queries instead of fetching all issues. Example:repo:anthropics/claude-code is:open is:issue authentication. - Empty Discord channels: If a Discord channel is invite-only or you lack read permissions, the API returns 0 messages without error. Test with a known-readable channel first.
Example Usage
// For auth-ig Discord channel + anthropics/claude-code issues
const GUILD_ID = '1358869848138059966'; // MCP Contributors
const CHANNEL_ID = '1360835991749001368'; // auth-ig
const OWNER = 'anthropics';
const REPO = 'claude-code';
const AUTH_KEYWORDS = [
'dpop', 'mtls', 'oauth', 'oidc', 'token refresh',
'www-authenticate', 'authorization server', 'client registration',
'scopes', 'bearer token', 'mcp auth'
];
// Follow steps 1-5 above
Related Tools
guildbridgeMCP server:read_messages,list_guilds,list_channelsgithubMCP server:search_issues,list_issues,issue_read
Changelog
- 2026-06-21: Initial version based on auth-ig correlation task