Skip to content

feat(chat-discord): implement contract:chat Discord adapter specification - #1484

Merged
potiuk merged 10 commits into
mainfrom
feat/chat-discord-adapter
Oct 8, 2026
Merged

potiuk merged 10 commits into
mainfrom
feat/chat-discord-adapter

Conversation

@onlyarnav

@onlyarnav onlyarnav commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Part 1 of 2 in the contract:chat Discord adapter stack (next: #1485).

Summary

  • Implements the Discord adapter specification for contract:chat under tools/chat-discord/README.md.
  • Backed by the pinned Discord MCP server (@pasympa/discord-mcp@2.2.0, repository PaSympa/discord-mcp), registered with claude mcp add discord -s user -e DISCORD_TOKEN="$(cat ~/.config/apache-magpie/discord-token)" -- npx -y @pasympa/discord-mcp@2.2.0.
  • Documents credential delivery via -e DISCORD_TOKEN=... and Layer 0 clean-environment wrapper (agent-iso / claude-iso) passthrough via AGENT_ISO_ALLOW=DISCORD_TOKEN.
  • Declares bot permissions (VIEW_CHANNEL, READ_MESSAGE_HISTORY) and privileged gateway intents (MESSAGE_CONTENT, GUILD_MEMBERS).
  • Defines operational mappings onto the Discord MCP (mcp__discord__*) in tools/chat-discord/operations.md for list_channels(), resolve_user(), and search_messages():
    • list_channels() checks effective visibility against guild-level @everyone base role permissions combined with channel and parent category overwrites.
    • resolve_user() notes bot tokens cannot read OAuth accounts/bios, returning candidate members with confirmed_by: null.
    • search_messages() scopes search to explicitly requested channels when provided, resolving <guild_id> from chat.guild_id in project config or channel metadata.
  • Adds behavioral eval fixture case-8-discord-community-signals in tools/skill-evals/evals/contributor-nomination/step-3-gather-signal/fixtures/ validating Discord community signal handling.
  • Updates MCP table entry in docs/labels-and-capabilities.md to Discord MCP (PaSympa/discord-mcp).
  • Synchronizes docs/vendor-neutrality.md reflecting 11/13 capability contracts (85%).
  • Enforces strict read-only guarantees by construction: explicitly forbids message sending, editing, deleting, reacting, DM reading, and private channel access.
  • Adds tools/chat-discord/** to contract:chat in .github/labeler.yml.

Type of change

  • Tool / bridge contract (tools/<system>/*.md)
  • CI / dev loop (prek, workflows, validators)

Test plan

  • Verified tools/chat-discord/README.md and operations.md conform to tool metadata and prerequisite requirements.
  • Verified skill_and_tool_validator.validate_tools reports 0 violations for tools/chat-discord.
  • Verified vendor_neutrality_score successfully detects and loads tools/chat-discord as an implementation for contract:chat (11/13 capability contracts, 85%).
  • Verified eval case case-8-discord-community-signals conforms to schema in step-3-gather-signal.
  • Ran doctoc TOC generation, markdownlint-cli2, and SPDX license validation.

RFC-AI-0004 compliance

  • Write-access discipline — the Discord adapter is strictly read-only; operations explicitly forbid sending, editing, reacting, or accessing private messages.
  • Vendor neutrality — adheres to the project-agnostic contract:chat interface.
  • External content as data — treats Discord messages and bios strictly as untrusted external data, never instructions.

Linked issues

Refs #1421

🤖 Generated with Antigravity

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The adapter follows the Slack adapter's shape closely, but two things need fixing first: resolve_user relies on data a Discord bot token cannot read while the adapter is advertised as a complete backend (which flips the published vendor-neutrality score), and the README doesn't say which MCP server provides the discord_* tools or where the token lives. Details inline.

Coverage — resolve_user relies on profile data bots cannot read

partial-read-only means the tool implements a read-only subset of named contract operations, but does not satisfy the complete contract and must not be advertised as a complete/selectable backend.
— docs/labels-and-capabilities.md § Coverage qualifiers

A bot token can't read another user's connected accounts or their "About Me" bio — connections need the OAuth2 connections scope from that user, and the profile endpoint is user-only — so the confirmed_by: "profile" path never fires for the bot this README asks for. Because vendor-neutrality-score counts any implementation without a **Coverage:** line as a full backend, this PR turns contract:chat green and moves the headline to 11/12. The simplest fix keeps that: the contract allows confirmed_by: null, so drop the profile step and return member-search candidates with confirmed_by: null. The alternative is **Coverage:** partial-read-only and dropping the docs/vendor-neutrality.md change.

(search_messages is fine on this front: Discord documented a bot-accessible Search Guild Messages endpoint in March 2026 — it needs READ_MESSAGE_HISTORY and the Message Content intent.)

Prerequisites — name the MCP server and put the token under $HOME

Any persistent token, API key, OAuth refresh token, or session cookie a framework tool needs goes under a well-known home-directory path — ~/.config/apache-magpie/<tool> for framework-owned tools, or the third-party tool's own convention … New integrations MUST follow the pattern
— AGENTS.md § Local setup

Slack can leave this out because it uses the claude.ai connector; there is no Discord equivalent, so "Discord MCP (mcp__discord__*)" doesn't point at anything an adopter can install. Please name the server (repo URL and a version that exposes the discord_* tools in operations.md) or give the claude mcp add … -s user recipe, say where the bot token is stored (under $HOME, never in the project tree), list the required permissions and intents (View Channel, Read Message History, and the privileged Message Content intent — without it text comes back empty and search is unavailable), and add the server's source to the MCP table row in docs/labels-and-capabilities.md.

Smaller observations

  • See inline: search_messages ignores the channels argument, and list_channels filters on an is_private field Discord channels don't have.
  • docs/adapters/authoring.md step 5 asks for an eval under tools/skill-evals/evals/; none exists in the stack yet (#1486 adds only a scorer unit test). A community-signals fixture with kind: discord would cover it.
  • Stack ordering: this PR flips the neutrality score while tools/chat/README.md still lists Discord as placeholder | not implemented until #1485 — merging the stack together avoids a contradictory main.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. After you've
addressed the points above and pushed an update, an Apache Magpie
maintainer — a real person — will take the next look
at the PR. The findings cite the project's review criteria;
if you think one of them is mis-applied, please reply on the
PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
CONTRIBUTING.md.

Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/README.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
onlyarnav added a commit that referenced this pull request Oct 4, 2026
Address maintainer review feedback on PR #1484:
- In tools/chat-discord/README.md: document concrete MCP server (chrishayuk/discord-mcp),
  store token under $HOME (~/.config/apache-magpie/discord-token), specify bot permissions
  (VIEW_CHANNEL, READ_MESSAGE_HISTORY) and privileged intents (MESSAGE_CONTENT, GUILD_MEMBERS).
- In tools/chat-discord/operations.md: clarify that bot tokens cannot read OAuth connected
  accounts or bios, returning confirmed_by: null; check VIEW_CHANNEL permissions on channels
  and parent categories; honor channels argument in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to match tool README with
  Discord MCP (chrishayuk/discord-mcp).

Generated-by: Antigravity

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resolve_user, channels-argument, and channel-visibility fixes look right — three of the four threads are resolved on my side. Two things still block this, both inline: the README now points at a Discord MCP server (chrishayuk/discord-mcp) whose repository returns 404, and the branch conflicts with main in the generated vendor-neutrality block, so no CI has run.

Smaller observations

  • The eval gap from the last review is still open: docs/adapters/authoring.md step 5 asks for one; a community-signals fixture with kind: discord would cover it.
  • operations.md:27 checks the @everyone overwrite on the channel and its category but not the guild-level @everyone role permission. On a server where @everyone lacks VIEW_CHANNEL at the guild level, every channel would pass as public. Worth folding the base role permission into the rule.
  • operations.md:45 builds message URLs from <guild_id>, but chat.guild_id is optional in the README config — please say where it comes from when unset.
  • Stack order still applies: this needs to land before #1485, which flips the discord status on tools/chat/README.md.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. After you've
addressed the points above and pushed an update, an Apache Magpie
maintainer — a real person — will take the next look
at the PR. The findings cite the project's review criteria;
if you think one of them is mis-applied, please reply on the
PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
CONTRIBUTING.md.

Comment thread tools/chat-discord/README.md Outdated
Comment thread tools/chat-discord/README.md Outdated
Comment thread docs/vendor-neutrality.md Outdated
onlyarnav added a commit that referenced this pull request Oct 5, 2026
Address maintainer review feedback on PR #1484:
- In tools/chat-discord/README.md: document concrete MCP server (chrishayuk/discord-mcp),
  store token under $HOME (~/.config/apache-magpie/discord-token), specify bot permissions
  (VIEW_CHANNEL, READ_MESSAGE_HISTORY) and privileged intents (MESSAGE_CONTENT, GUILD_MEMBERS).
- In tools/chat-discord/operations.md: clarify that bot tokens cannot read OAuth connected
  accounts or bios, returning confirmed_by: null; check VIEW_CHANNEL permissions on channels
  and parent categories; honor channels argument in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to match tool README with
  Discord MCP (chrishayuk/discord-mcp).

Generated-by: Antigravity
onlyarnav added a commit that referenced this pull request Oct 5, 2026
…s, and eval fixture

Address review feedback on PR #1484:
- In tools/chat-discord/README.md: replace 404 repo with active PaSympa/discord-mcp pinned
  at @pasympa/discord-mcp@2.2.0; document credential delivery to MCP server via
  -e DISCORD_TOKEN=... and clean-environment passthrough via AGENT_ISO_ALLOW=DISCORD_TOKEN.
- In tools/chat-discord/operations.md: fold guild-level @everyone base role VIEW_CHANNEL
  permission into list_channels() visibility check; document <guild_id> resolution
  in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to PaSympa/discord-mcp.
- In tools/skill-evals: add case-8-discord-community-signals eval fixture in
  contributor-nomination step-3-gather-signal testing Discord community signals,
  and update case counts in documentation.

Generated-by: Antigravity
@onlyarnav
onlyarnav force-pushed the feat/chat-discord-adapter branch from d04cf30 to f70042d Compare October 5, 2026 17:41
@github-actions github-actions Bot added family:tools tools/* family:docs Docs, MISSION.md, READMEs family:ci .github workflows, prek, validators capability:stats Read-only dashboards, metrics, governance evidence family:contributor-growth contributor-growth skills substrate:framework-dev Tool substrate: build / validate / eval the framework itself labels Oct 5, 2026
@onlyarnav
onlyarnav added this pull request to stack #1534 October 5, 2026 17:52

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the rebase, the real pinned server, and the token wiring — those points and the eval are done. Reading @pasympa/discord-mcp@2.2.0's source, though, the spec's assumptions don't match its actual tools in two places that matter: discord_search_messages is per-channel, keyword-only, last-100 with no author, window, or paging (inline on operations.md:44), and the public-channel guard needs @everyone base permissions and channel overwrites that the tools this step calls don't return (inline on operations.md:28) — and that guard is the adapter's only protection against reading private channels. operations.md needs one more pass against the server's real tool surface.


This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. After you've
addressed the points above and pushed an update, an Apache Magpie
maintainer — a real person — will take the next look
at the PR. The findings cite the project's review criteria;
if you think one of them is mis-applied, please reply on the
PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
CONTRIBUTING.md.

Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/operations.md Outdated
Comment thread tools/chat-discord/README.md Outdated
onlyarnav added a commit that referenced this pull request Oct 7, 2026
Address maintainer review feedback on PR #1484:
- In tools/chat-discord/README.md: document concrete MCP server (chrishayuk/discord-mcp),
  store token under $HOME (~/.config/apache-magpie/discord-token), specify bot permissions
  (VIEW_CHANNEL, READ_MESSAGE_HISTORY) and privileged intents (MESSAGE_CONTENT, GUILD_MEMBERS).
- In tools/chat-discord/operations.md: clarify that bot tokens cannot read OAuth connected
  accounts or bios, returning confirmed_by: null; check VIEW_CHANNEL permissions on channels
  and parent categories; honor channels argument in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to match tool README with
  Discord MCP (chrishayuk/discord-mcp).

Generated-by: Antigravity
onlyarnav added a commit that referenced this pull request Oct 7, 2026
…s, and eval fixture

Address review feedback on PR #1484:
- In tools/chat-discord/README.md: replace 404 repo with active PaSympa/discord-mcp pinned
  at @pasympa/discord-mcp@2.2.0; document credential delivery to MCP server via
  -e DISCORD_TOKEN=... and clean-environment passthrough via AGENT_ISO_ALLOW=DISCORD_TOKEN.
- In tools/chat-discord/operations.md: fold guild-level @everyone base role VIEW_CHANNEL
  permission into list_channels() visibility check; document <guild_id> resolution
  in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to PaSympa/discord-mcp.
- In tools/skill-evals: add case-8-discord-community-signals eval fixture in
  contributor-nomination step-3-gather-signal testing Discord community signals,
  and update case counts in documentation.

Generated-by: Antigravity
@onlyarnav
onlyarnav force-pushed the feat/chat-discord-adapter branch from f70042d to 58ecf7a Compare October 7, 2026 13:05
Add the tools/chat-discord adapter specification and operational mappings
for contract:chat. Defines read-only interactions over public Discord channels,
mapping list_channels(), resolve_user(), and search_messages() verbs onto
Discord MCP tools, with explicit enforcement of safety constraints and
automatic labeling in .github/labeler.yml.

Generated-by: Antigravity
Update docs/labels-and-capabilities.md with tools/chat-discord capability
and MCP entries to satisfy capability-sync validation. Synchronize
docs/vendor-neutrality.md with the recalculated vendor-neutrality score
(11/12 contracts, 92%) reflecting contract:chat's two backend vendors.

Generated-by: Antigravity
Address maintainer review feedback on PR #1484:
- In tools/chat-discord/README.md: document concrete MCP server (chrishayuk/discord-mcp),
  store token under $HOME (~/.config/apache-magpie/discord-token), specify bot permissions
  (VIEW_CHANNEL, READ_MESSAGE_HISTORY) and privileged intents (MESSAGE_CONTENT, GUILD_MEMBERS).
- In tools/chat-discord/operations.md: clarify that bot tokens cannot read OAuth connected
  accounts or bios, returning confirmed_by: null; check VIEW_CHANNEL permissions on channels
  and parent categories; honor channels argument in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to match tool README with
  Discord MCP (chrishayuk/discord-mcp).

Generated-by: Antigravity
…s, and eval fixture

Address review feedback on PR #1484:
- In tools/chat-discord/README.md: replace 404 repo with active PaSympa/discord-mcp pinned
  at @pasympa/discord-mcp@2.2.0; document credential delivery to MCP server via
  -e DISCORD_TOKEN=... and clean-environment passthrough via AGENT_ISO_ALLOW=DISCORD_TOKEN.
- In tools/chat-discord/operations.md: fold guild-level @everyone base role VIEW_CHANNEL
  permission into list_channels() visibility check; document <guild_id> resolution
  in search_messages().
- In docs/labels-and-capabilities.md: update MCP entry to PaSympa/discord-mcp.
- In tools/skill-evals: add case-8-discord-community-signals eval fixture in
  contributor-nomination step-3-gather-signal testing Discord community signals,
  and update case counts in documentation.

Generated-by: Antigravity
@onlyarnav
onlyarnav force-pushed the feat/chat-discord-adapter branch from 58ecf7a to 9f504ae Compare October 7, 2026 13:11

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — the earlier findings are addressed and CI is green.

Checked against @pasympa/discord-mcp@2.2.0: the tools named in operations.md and the DISCORD_TOKEN, DISCORD_MCP_TOOLSETS and DISCORD_ALLOWED_GUILDS variables exist, the package is pinned, guild resolution is up front, search uses discord_search_guild_messages with local date filtering, and the public-channel rule is conservative.
I resolved the six threads this push answered.

Two non-blocking nits:

  • discord_search_guild_messages requires query; say what to send when searching by author only.
  • -e DISCORD_TOKEN="$(cat …)" puts the token on the command line during registration; consider noting that.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The maintainer
approving this PR has read the findings and signed off. If
something feels off, please reply on the PR and a maintainer
will follow up.

More on how Apache Magpie handles maintainer review:
Contributing guide.

@potiuk
potiuk merged commit 68b380b into main Oct 8, 2026
11 checks passed
@potiuk
potiuk deleted the feat/chat-discord-adapter branch October 8, 2026 12:18
@github-actions github-actions Bot added the contract:chat Tool capability: project chat reads (public channels only) label Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:stats Read-only dashboards, metrics, governance evidence contract:chat Tool capability: project chat reads (public channels only) family:ci .github workflows, prek, validators family:contributor-growth contributor-growth skills family:docs Docs, MISSION.md, READMEs family:tools tools/* substrate:framework-dev Tool substrate: build / validate / eval the framework itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants