Skip to content

Conversation

alienzach
Copy link
Contributor

@alienzach alienzach commented Sep 12, 2025

Summary by CodeRabbit

  • New Features

    • Added an async tool to list GitHub pull requests and deliver summaries to Slack with optional Slack posting.
  • Improvements

    • Now retrieves the last 10 pull requests and prioritizes by urgency, security, critical bugs, blockers, and age.
    • Switched GitHub connectivity to HTTP transport with header-based bearer auth; Slack uses OAuth token pattern.
    • Returns and prints generated summaries, adds Slack fallback, and ensures proper agent shutdown and logging.
  • Bug Fixes

    • Fixed a description formatting issue in configuration.

@alienzach alienzach marked this pull request as ready for review September 12, 2025 17:07
Copy link

coderabbitai bot commented Sep 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Converts the GitHub→Slack example into an exposed async tool, updates retrieval to the last 10 PRs, captures and returns LLM output, adds Slack-posting fallback and agent cleanup, and migrates the GitHub MCP server config from a Docker launcher to HTTP/REST with allowed tools and updated Slack config.

Changes

Cohort / File(s) Summary of Changes
Async tool & runtime flow
examples/usecases/mcp_github_to_slack_agent/main.py
Decorated github_to_slack with @app.async_tool, fetches the last 10 PRs, stores LLM output in result, prints and returns it, adds Slack posting fallback when Slack tool unavailable, and ensures await github_to_slack_agent.close() in finally.
MCP server configuration
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml
Replaced GitHub Docker command/args with HTTP/REST transport: added transport, url, headers, http_timeout_seconds, read_timeout_seconds, and allowed_tools (list_pull_requests, get_pull_request). Renamed Slack env var, adjusted description, and added allowed_tools: conversations_add_message.
Secrets / Auth
examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example
Switched GitHub auth from env token to HTTP Authorization: Bearer ... header, introduced SLACK_MCP_XOXP_TOKEN (OAuth token) and commented secret-injection placeholders; removed prior inline env token entries.
Docs / README
examples/usecases/mcp_github_to_slack_agent/README.md
Updated docs to describe retrieving the last 10 PRs, expanded PR prioritization criteria, adjusted prerequisites for cloud deployment, added cloud deployment and workflow details, and updated example YAML/secret-key guidance.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Tool as github_to_slack (async tool)
  participant GitHub as MCP GitHub (REST)
  participant LLM as LLM
  participant Slack as MCP Slack

  User->>Tool: invoke github_to_slack(repo)
  Tool->>GitHub: list_pull_requests(last=10)
  GitHub-->>Tool: returns PR list
  Tool->>LLM: generate summary prompt (PR list)
  LLM-->>Tool: returns result (summary)
  alt Slack tool available
    Tool->>Slack: conversations_add_message(summary)
    Slack-->>Tool: ack
  else No Slack tool access
    Note over Tool: Fallback — return summary without posting
  end
  Tool-->>User: return result
  Tool->>Tool: await github_to_slack_agent.close() (cleanup)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • saqadri
  • andrew-lastmile

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: upgrade gh-slack example for cloud" is a short, single-sentence summary that directly reflects the primary change in the diff—upgrading the GitHub/Slack example for cloud deployment as shown by config, README, and code updates—so it accurately represents the main intent of the PR. It is concise and focused, making it clear to reviewers what the primary change is.

Poem

Thump-thump, I hop through code tonight,
Ten PRs gleam beneath the moonlight.
I ask the LLM to sing what’s true,
If Slack is sleeping, I still send you.
Cleanup done — carrot cheers, hooray! 🥕

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 09-12-feat_upgrade_gh-slack_example_for_cloud

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@alienzach alienzach force-pushed the 09-12-feat_upgrade_gh-slack_example_for_cloud branch from 7b466ea to 31b5e60 Compare September 12, 2025 17:09
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
examples/usecases/mcp_github_to_slack_agent/main.py (1)

43-43: Same as earlier note on PR filtering.

🧹 Nitpick comments (6)
examples/usecases/mcp_github_to_slack_agent/main.py (5)

12-12: Expose as async tool: good; consider docstring and dropping redundant name.

Tool exposure looks correct. Add a short docstring (used as description fallback) and consider omitting name= since it equals the function name.

-@app.async_tool(name="github_to_slack", description="Tool to list GitHub pull requests and provides summaries to Slack")
+@app.async_tool(description="Tool to list GitHub pull requests and provide summaries to Slack")
 async def github_to_slack(github_owner: str, github_repo: str, slack_channel: str):
+    """List recent PRs, summarize, and post to Slack."""

22-22: Be explicit about “last 10 PRs” semantics to reduce ambiguity/cost.

Specify filters (state, sort, direction, per_page) so the LLM calls the GitHub tool deterministically.

-                1. Use the GitHub server to retrieve information about the last 10 pull requests for the repository {github_owner}/{github_repo}
+                1. Use the GitHub server to list the last 10 PRs for {github_owner}/{github_repo} (state=open, sort=updated, direction=desc, per_page=10).

63-64: Tighten Slack fallback text to avoid false claims.

Make the behavior explicit and falsifiable if posting isn’t possible.

-                4. Use the Slack server to post this summary to the channel {slack_channel}. If you do not have Slack 
-                   tool access, just return the final summary is OK. 
+                4. Use the Slack server to post this summary to channel {slack_channel}.
+                   If the Slack tool is unavailable, return the final summary instead and explicitly include:
+                   "Slack post skipped (no tool access)". Do not claim a message was posted.

69-69: Guard against empty LLM output and prefer structured logging over print.

Raise on empty response to surface failures; consider using the app/logger rather than stdout.

-                result = await llm.generate_str(prompt)
+                result = await llm.generate_str(prompt)
+                if not result or not result.strip():
+                    raise RuntimeError("LLM returned empty result")

72-72: Avoid dumping full LLM output to stdout.

Large messages can bloat logs; truncate or log a hash.

-                print(result)
+                print(result[:2000] + ("… [truncated]" if len(result) > 2000 else ""))
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1)

15-20: streamable_http is supported — add Accept header and configure auth

streamable_http is supported and config.headers are forwarded to the streamable HTTP client; add an Accept header and provide Authorization if the provider requires it.

Proposed header tweak:

      headers:
        Content-Type: "application/json"
+       Accept: "application/json"

Locations to act/check:

  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (headers block)
  • src/mcp_agent/mcp/mcp_server_registry.py and src/mcp_agent/mcp/mcp_connection_manager.py (transport handling; headers forwarded and MCP_SESSION_ID injected)
  • src/mcp_agent/config.py (MCPServerSettings.headers and auth fields)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8ee962 and 31b5e60.

📒 Files selected for processing (2)
  • examples/usecases/mcp_github_to_slack_agent/main.py (4 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
examples/usecases/mcp_github_to_slack_agent/main.py (1)
src/mcp_agent/app.py (1)
  • async_tool (769-817)
🪛 YAMLlint (1.37.1)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml

[error] 36-36: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (2)
examples/usecases/mcp_github_to_slack_agent/main.py (1)

74-74: Return value capture — LGTM.

Capturing and returning the LLM result fixes the silent discard.

examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1)

22-24: Allowed GitHub tools — LGTM.

Principle of least privilege with only list/get operations.

Comment on lines +34 to +36
description: "Access Slack API operations"
allowed_tools:
- "conversations_add_message"
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Slack tool naming/permissions and channel identifier; also fix EOF newline.

  • Confirm the tool name conversations_add_message matches the Slack MCP server’s schema and that your token has scopes (e.g., chat:write, channels:read or groups:read depending on channel type).
  • Ensure the CLI expects a channel ID (C…/G…) vs. a name to avoid posting failures.
  • Add missing newline at EOF to satisfy YAML linters.

Minimal EOF fix:

-        - "conversations_add_message"
+        - "conversations_add_message"
+

🌐 Web query:

What tool names and argument shapes does the official slack-mcp-server expose for posting messages, and which Slack OAuth scopes are required?

💡 Result:

Short answer — from the official slack-mcp-server package the message-posting tool is:

  • slack_post_message
    • Inputs (argument shape):
      • channel_id (string) — ID of the channel to post to (required)
      • text (string) — message text (required)
    • (There is also slack_reply_to_thread for thread replies: channel_id (string), thread_ts (string), text (string).) (npmjs.com)

Required Slack OAuth scopes (common/official bot-token scopes used by the server for full functionality — include at least chat:write plus channel/group/IM read/write and others listed below): channels:read, channels:manage (or channels:write in some forks), groups:read, groups:write, chat:write, files:write, im:read, mpim:read, reactions:read, reactions:write, team:read, users:read. (Some forks/variants may request additional/history scopes like channels:history, groups:history, im:history, or use user tokens with user scopes instead.) (github.com)

If you want, I can fetch the exact JSON tool schema (full parameter names/types) from the package manifest or repository you plan to use.

Citations:


Replace allowed_tools with slack_post_message, require channel_id & chat scopes, and add EOF newline.

  • File: examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (lines 34–36)
  • Change allowed_tools entry from the non-existent conversations_add_message to slack_post_message — the slack-mcp-server tool expects: channel_id (string) and text (string). slack_reply_to_thread exists for thread replies.
  • Ensure the bot token includes at minimum chat:write and the appropriate channel read scope (channels:read for public channels or groups:read for private channels); additional common scopes: channels:manage/groups:write, im:read, mpim:read, files:write, reactions:read/write, users:read as needed.
  • Pass a channel ID (C.../G...), not a human-readable name.
  • Add missing newline at EOF.

Minimal EOF fix (unchanged):

-        - "conversations_add_message"
+        - "conversations_add_message"
+
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
description: "Access Slack API operations"
allowed_tools:
- "conversations_add_message"
description: "Access Slack API operations"
allowed_tools:
- "conversations_add_message"
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 36-36: no new line character at the end of file

(new-line-at-end-of-file)

🤖 Prompt for AI Agents
In examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml around
lines 34 to 36, replace the allowed_tools entry "conversations_add_message" with
"slack_post_message", ensure the tool usage includes required parameters
channel_id (must be a channel ID like C... or G..., not a human-readable name)
and text, verify the bot token configuration lists at minimum chat:write plus
the appropriate channel read scope (channels:read for public or groups:read for
private) and any additional needed scopes, and add a missing newline at EOF.

transport: "streamable_http"
url: "https://api.githubcopilot.com/mcp/x/pull_requests/readonly"
headers:
Content-Type: "application/json"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where do you specify the secrets?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's populated in secret.yaml. see

@alienzach alienzach force-pushed the 09-12-feat_upgrade_gh-slack_example_for_cloud branch from 31b5e60 to 2110457 Compare September 12, 2025 18:55
Comment on lines 63 to 64
4. Use the Slack server to post this summary to the channel {slack_channel}. If you do not have Slack
tool access, just return the final summary is OK.
Copy link
Contributor

Choose a reason for hiding this comment

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

The instruction contains a grammatical issue that could cause confusion. Consider revising to either:

"If you do not have Slack tool access, just returning the final summary is OK."

or more directly:

"If you do not have Slack tool access, just return the final summary."

The current wording combines these two constructions, potentially creating ambiguity for the LLM when interpreting the fallback behavior.

Suggested change
4. Use the Slack server to post this summary to the channel {slack_channel}. If you do not have Slack
tool access, just return the final summary is OK.
4. Use the Slack server to post this summary to the channel {slack_channel}. If you do not have Slack
tool access, just return the final summary.

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

34-36: Slack tool name likely wrong; use slack_post_message and require channel_id.

Per prior review, the Slack MCP server’s message tool is typically slack_post_message (args: channel_id, text). Using conversations_add_message will fail at runtime.

   description: "Access Slack API operations"
   allowed_tools:
-    - "conversations_add_message"
+    - "slack_post_message"

Also ensure your app passes a channel ID (C…/G…), not a name, and that the bot token has chat:write plus the appropriate channel read scope. If your chosen Slack server variant differs, update README and usage accordingly.


15-21: Add Authorization header (use secret) to GitHub MCP server

File: examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml — mcp.servers.github headers (lines ~15–21). The GitHub MCP entry only has Content-Type; add an Authorization: Bearer header injected from secrets (do not hardcode).

   url: "https://api.githubcopilot.com/mcp/x/pull_requests/readonly"
   headers:
     Content-Type: "application/json"
+    # Injected from secrets; name illustrative — align with your secrets key.
+    Authorization: "Bearer ${GITHUB_COPILOT_TOKEN}"
   http_timeout_seconds: 30
   read_timeout_seconds: 60
🧹 Nitpick comments (4)
examples/usecases/mcp_github_to_slack_agent/README.md (3)

8-8: Clarify “last 10 PRs” selection (state and sort).

Specify whether these are open vs. all PRs and the sort key (e.g., updated desc) to set user expectations and align with the GitHub MCP tool’s defaults.


24-24: Be explicit about Copilot plan and token wiring for the REST MCP server.

Call out the required Copilot tier, how the token is obtained, and how it’s injected (secrets → headers) so users don’t hit auth failures.

Apply this minimal addition to the Prerequisites to remove ambiguity:

- - GitHub Copilot access (for cloud-based GitHub MCP server)
+ - GitHub Copilot (cloud MCP) access (specify required plan)
+   - Provide a Copilot API token via mcp_agent.secrets.yaml and ensure the config adds an Authorization: Bearer <token> header for the GitHub MCP server.

26-26: Specify Node/npm versions and pin the Slack server dependency.

Document minimum Node.js/npm versions and consider pinning slack-mcp-server to a known-good version to avoid breaking changes.

- - Node.js and npm (for the Slack server)
+ - Node.js ≥18 and npm ≥9 (for the Slack server)

If you agree, I can propose a matching pin in the YAML config (args: ["-y", "slack-mcp-server@"]).

examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1)

36-36: Add missing newline at EOF (YAML lint/CI nit).

Fixes YAMLlint “no new line character at the end of file”.

-        - "conversations_add_message"
+        - "conversations_add_message"
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31b5e60 and 2110457.

📒 Files selected for processing (3)
  • examples/usecases/mcp_github_to_slack_agent/README.md (2 hunks)
  • examples/usecases/mcp_github_to_slack_agent/main.py (4 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/usecases/mcp_github_to_slack_agent/main.py
🧰 Additional context used
🪛 YAMLlint (1.37.1)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml

[error] 36-36: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1)

22-24: LGTM: Explicit GitHub tools list.

list_pull_requests and get_pull_request are sensible minimums.

@alienzach alienzach force-pushed the 09-12-feat_upgrade_gh-slack_example_for_cloud branch from 2110457 to 5aa4250 Compare September 12, 2025 19:06
Comment on lines +6 to +10
# Create a Slack App Oauth Token and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_BOT_TOKEN: "xoxb-your-bot-token"
SLACK_TEAM_ID: "T01234567"
SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"
Copy link
Contributor

Choose a reason for hiding this comment

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

There appears to be a terminology mismatch in the configuration comments. The comment refers to "Slack App Oauth Token" but the environment variable SLACK_MCP_XOXP_TOKEN specifically indicates a user token (xoxp prefix), not an app/bot token.

For clarity, either:

  1. Update the comment to specify this is a user-level OAuth token (xoxp), or
  2. If a bot token is actually intended, update the variable name to reflect the correct token type

This distinction is important as user tokens and bot tokens have different permission scopes and security implications.

Suggested change
# Create a Slack App Oauth Token and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_BOT_TOKEN: "xoxb-your-bot-token"
SLACK_TEAM_ID: "T01234567"
SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"
# Create a Slack User OAuth Token (xoxp token) and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
examples/usecases/mcp_github_to_slack_agent/README.md (2)

67-68: Use channel ID, not name, to prevent posting failures.

-uv run main.py --owner <github-owner> --repo <repository-name> --channel <slack-channel>
+uv run main.py --owner <github-owner> --repo <repository-name> --channel_id <C_or_G_channel_id>

40-41: Docs say “Bot User OAuth Token” but secrets example uses a user token (xoxp). Align.

Either:

  • Keep Bot token (xoxb) in docs and secrets (recommended), or
  • Switch docs to user token and update scopes and config to pass that var through.
♻️ Duplicate comments (2)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

35-36: Wrong Slack tool name; use slack_post_message (and optionally slack_reply_to_thread).

       allowed_tools:
-        - "conversations_add_message"
+        - "slack_post_message"
+#        - "slack_reply_to_thread"

32-32: Do not hardcode Slack Team ID; pull from secrets and pass the bot token explicitly.

       env:
-        SLACK_TEAM_ID: "T0123213213"
+        SLACK_TEAM_ID: !developer_secret SLACK_TEAM_ID
+        SLACK_BOT_TOKEN: !developer_secret SLACK_BOT_TOKEN
         SLACK_MCP_ADD_MESSAGE_TOOL: "true"
🧹 Nitpick comments (3)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example (1)

22-23: Use secret injection for Anthropic key by default.

-anthropic:
-  api_key: your-anthropic-api-key
-#  api_key: !developer_secret ANTHROPIC_API_KEY
+anthropic:
+#  api_key: !developer_secret ANTHROPIC_API_KEY
+  api_key: your-anthropic-api-key  # example value; do not commit real keys
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

27-30: YAML indentation/array style nits causing linter warnings.

-      args: ["-y",
-        "slack-mcp-server@latest",
-        "--transport",
-        "stdio"]
+      args:
+        - "-y"
+        - "slack-mcp-server@latest"
+        - "--transport"
+        - "stdio"

36-36: Add missing EOF newline.

-        - "conversations_add_message"
+        - "conversations_add_message"
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2110457 and 5aa4250.

📒 Files selected for processing (4)
  • examples/usecases/mcp_github_to_slack_agent/README.md (2 hunks)
  • examples/usecases/mcp_github_to_slack_agent/main.py (4 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/usecases/mcp_github_to_slack_agent/main.py
🧰 Additional context used
🪛 YAMLlint (1.37.1)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml

[warning] 28-28: wrong indentation: expected 13 but found 8

(indentation)


[warning] 29-29: wrong indentation: expected 13 but found 8

(indentation)


[warning] 30-30: wrong indentation: expected 13 but found 8

(indentation)


[error] 36-36: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (4)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

15-20: HTTP transport OK — example secrets contain Authorization; confirm runtime merge.

examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example includes Authorization: "Bearer ghp_xxxxxxxxxxx" (lines 18–19); ensure your deployed secrets populate mcp.servers.github.headers.Authorization at runtime (e.g. use !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX) to avoid 401.


22-24: Confirm allowed_tools exist on the MCP server

File: examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (lines 22–24) — verify that "list_pull_requests" and "get_pull_request" are exposed by your MCP server. Run one of these (replace $MCP_SERVER and $MCP_TOKEN):

# REST GET (common)
curl -s -H "Authorization: Bearer $MCP_TOKEN" "$MCP_SERVER/v1/tools" | jq -r '.tools[].name' | sort -u

# RPC POST (alternate)
curl -s -H "Authorization: Bearer $MCP_TOKEN" -X POST "$MCP_SERVER/v1/tools:list" -d '{}' | jq -r '.tools[].name' | sort -u

Confirm both names appear; if either is missing, remove/update the whitelist or register the tool on the MCP server.

examples/usecases/mcp_github_to_slack_agent/README.md (2)

8-8: LGTM: clarifies retrieval scope (last 10 PRs).


24-24: Confirm the Copilot-backed MCP endpoint requirement.

If the GitHub MCP server is behind a Copilot-only endpoint, a standard PAT may not work. Call out the exact requirement and scopes here.

Comment on lines +6 to +11
# Create a Slack App Oauth Token and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_BOT_TOKEN: "xoxb-your-bot-token"
SLACK_TEAM_ID: "T01234567"
SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"
# SLACK_MCP_XOXP_TOKEN: !developer_secret SLACK_MCP_XOXP_TOKEN
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Slack token var/type mismatch; add Team ID and align with server expectations.

The example switches to a user token (xoxp) and variable SLACK_MCP_XOXP_TOKEN, while the Slack MCP server commonly expects a bot token (xoxb) and a well-known var (e.g., SLACK_BOT_TOKEN). Also, SLACK_TEAM_ID is required by your config but missing here. This will lead to 401s or tool init failures.

Apply one of the following (Option A recommended):

Option A — use bot token:

-    # Create a Slack App Oauth Token and get your Team ID
+    # Create a Slack Bot User OAuth Token (xoxb) and get your Team ID
       # https://api.slack.com/apps
       slack:
         env:
-        SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"
-#        SLACK_MCP_XOXP_TOKEN: !developer_secret SLACK_MCP_XOXP_TOKEN
+        SLACK_BOT_TOKEN: "xoxb-your-bot-token"
+#        SLACK_BOT_TOKEN: !developer_secret SLACK_BOT_TOKEN
+        SLACK_TEAM_ID: "T0123456789"
+#        SLACK_TEAM_ID: !developer_secret SLACK_TEAM_ID

Option B — if your server truly requires a user token, also pass the same var in config’s Slack env and document required user scopes.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Create a Slack App Oauth Token and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_BOT_TOKEN: "xoxb-your-bot-token"
SLACK_TEAM_ID: "T01234567"
SLACK_MCP_XOXP_TOKEN: "xoxp-oauth-token"
# SLACK_MCP_XOXP_TOKEN: !developer_secret SLACK_MCP_XOXP_TOKEN
# Create a Slack Bot User OAuth Token (xoxb) and get your Team ID
# https://api.slack.com/apps
slack:
env:
SLACK_BOT_TOKEN: "xoxb-your-bot-token"
# SLACK_BOT_TOKEN: !developer_secret SLACK_BOT_TOKEN
SLACK_TEAM_ID: "T0123456789"
# SLACK_TEAM_ID: !developer_secret SLACK_TEAM_ID

Comment on lines +17 to +19
headers:
Authorization: "Bearer ghp_xxxxxxxxxxx"
# Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid inlining GitHub tokens; use developer_secret injection.

Even in an example, showing an inline Bearer token encourages unsafe patterns. Prefer secret injection.

-      headers:
-        Authorization: "Bearer ghp_xxxxxxxxxxx"
-#        Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX
+      headers:
+#        Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX
+        Authorization: "Bearer YOUR_TOKEN_HERE"  # example value; do not commit real tokens

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example
around lines 17 to 19, the example inlines a GitHub PAT with a "Bearer
ghp_xxxxx" which encourages unsafe practices; replace the inline token with the
developer_secret placeholder (or remove the Bearer prefix and use the secret
injection syntax) so consumers are shown how to inject secrets at runtime (e.g.,
restore the commented developer_secret line or reference a properly named secret
variable) and update any accompanying README note to tell users to set the
secret in their environment rather than paste tokens into the example file.

Copy link
Collaborator

@saqadri saqadri left a comment

Choose a reason for hiding this comment

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

Ship it. Just request to update readme, copy the blob that Andrew is adding to the readmes

@andrew-lastmile
Copy link
Contributor

This is the blurb -> https://github.com/lastmile-ai/mcp-agent/blob/main/examples/basic/mcp_basic_agent/README.md

@alienzach alienzach force-pushed the 09-12-feat_upgrade_gh-slack_example_for_cloud branch from 5aa4250 to 4597a1f Compare September 12, 2025 20:27
@alienzach
Copy link
Contributor Author

updated

Comment on lines +18 to +19
Authorization: "Bearer ghp_xxxxxxxxxxx"
# Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX
Copy link
Contributor

Choose a reason for hiding this comment

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

There appears to be an inconsistency in the GitHub token format instructions:

Authorization: "Bearer ghp_xxxxxxxxxxx"
#Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX

The first line shows an explicit Bearer prefix with the token, while the commented line suggests using a developer secret that already includes this prefix (as indicated by WITH_BEARER_PREFIX).

This could lead to authentication errors if users follow both patterns. Consider standardizing the approach by either:

  1. Removing the Bearer prefix from line 18 and updating the developer secret name to indicate the token should be provided without the prefix, or
  2. Clarifying in a comment that the developer secret should include the Bearer prefix exactly as shown in line 18

Consistent instructions will help prevent authentication failures during setup.

Suggested change
Authorization: "Bearer ghp_xxxxxxxxxxx"
# Authorization: !developer_secret GITHUB_PERSONAL_ACCESS_TOKEN_WITH_BEARER_PREFIX
Authorization: "Bearer ghp_xxxxxxxxxxx"
# Authorization: !developer_secret GITHUB_TOKEN
# Note: When using a developer secret, you need to include the "Bearer " prefix in the secret value

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Collaborator

@saqadri saqadri left a comment

Choose a reason for hiding this comment

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

Awesome, ship it! Nicely done

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
examples/usecases/mcp_github_to_slack_agent/main.py (1)

63-65: Good: fallback wording is now clear and unambiguous.

Matches the Graphite suggestion and removes ambiguity for the LLM.

examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1)

35-36: Slack tool name likely mismatched; prefer slack_post_message + channel_id.

Many Slack MCP servers expose slack_post_message(channel_id, text). Confirm your server’s tool list; if applicable, rename allowed tool and align your prompts/README to require a channel ID.

-      allowed_tools:
-        - "conversations_add_message"
+      allowed_tools:
+        - "slack_post_message"

If your chosen server truly uses conversations_add_message, keep it and ignore this.

🧹 Nitpick comments (9)
examples/usecases/mcp_github_to_slack_agent/main.py (2)

12-12: Polish tool description grammar.

Change “and provides summaries” to “and provide summaries.”

Apply:

-@app.async_tool(name="github_to_slack", description="Tool to list GitHub pull requests and provides summaries to Slack")
+@app.async_tool(name="github_to_slack", description="Tool to list GitHub pull requests and provide summaries to Slack")

83-86: Clarify CLI expects a Slack channel ID.

Slack MCP servers typically require a channel ID (C…/G…), not a name. Update help text to reduce posting failures.

Apply:

-    parser.add_argument("--channel", required=True, help="Slack channel to post to")
+    parser.add_argument("--channel", required=True, help="Slack channel ID (e.g., C0123456789 or G0123456789)")
examples/usecases/mcp_github_to_slack_agent/README.md (5)

67-68: Use channel ID in usage example.

Most Slack tools require an ID. Make this explicit.

-uv run main.py --owner <github-owner> --repo <repository-name> --channel <slack-channel>
+uv run main.py --owner <github-owner> --repo <repository-name> --channel <slack-channel-id>

149-157: Minor grammar: “Tools that your agent exposes.”

Tighten phrasing.

-- Tool's that your agent expose:
+- Tools that your agent exposes:

154-154: Fix action text for workflows-resume.

“resume” should resume, not pause.

-  - workflows-resume: signal workflow to pause run
+  - workflows-resume: resume a paused run

174-174: Minor grammar.

-When you agent run successfully finishes,
+When your agent run successfully finishes,

136-140: markdownlint MD049: emphasis style.

If MD049 is enforced, switch asterisks to underscores in emphasized labels.

examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

28-30: YAML indentation off under args.

Fix to satisfy yamllint.

-      args: ["-y",
-        "slack-mcp-server@latest",
-        "--transport",
-        "stdio"]
+      args: [
+        "-y",
+        "slack-mcp-server@latest",
+        "--transport",
+        "stdio"
+      ]

36-36: Add newline at EOF.

Silences linters and improves diffs.

-        - "conversations_add_message"
+        - "conversations_add_message"
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5aa4250 and 4597a1f.

📒 Files selected for processing (4)
  • examples/usecases/mcp_github_to_slack_agent/README.md (3 hunks)
  • examples/usecases/mcp_github_to_slack_agent/main.py (4 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (1 hunks)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/usecases/mcp_github_to_slack_agent/mcp_agent.secrets.yaml.example
🧰 Additional context used
🧬 Code graph analysis (1)
examples/usecases/mcp_github_to_slack_agent/main.py (1)
src/mcp_agent/app.py (1)
  • async_tool (769-817)
🪛 markdownlint-cli2 (0.17.2)
examples/usecases/mcp_github_to_slack_agent/README.md

136-136: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


136-136: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


136-136: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


136-136: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


137-137: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


137-137: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


137-137: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


137-137: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


138-138: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


138-138: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


138-138: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


138-138: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


139-139: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


139-139: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


139-139: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)


139-139: Emphasis style
Expected: underscore; Actual: asterisk

(MD049, emphasis-style)

🪛 YAMLlint (1.37.1)
examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml

[warning] 28-28: wrong indentation: expected 13 but found 8

(indentation)


[warning] 29-29: wrong indentation: expected 13 but found 8

(indentation)


[warning] 30-30: wrong indentation: expected 13 but found 8

(indentation)


[error] 36-36: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (6)
examples/usecases/mcp_github_to_slack_agent/main.py (3)

14-18: Confirm nested app.run() is intended.

You’re calling app.run() inside a function already declared as an async tool on the same app. Ensure the workflow runtime expects/permits starting a new app context; otherwise, prefer accessing the current workflow context directly.


22-22: Retrieving the last 10 PRs is a sensible scope.

Nice constraint for cost and latency, and it matches the GitHub server tools you’ve allowed.


69-75: Good: capture and return LLM output; keep the logs.

Returning result improves tool composability; printing aids debugging.

examples/usecases/mcp_github_to_slack_agent/README.md (1)

81-95: Schema ref appears to point to config, not secrets.

If this snippet is for mcp_agent.secrets.yaml, point to the secrets schema file.

-$schema: ../../../schema/mcp-agent.config.schema.json
+$schema: ../../../schema/mcp-agent.secrets.schema.json

If the repo only ships a single combined schema, ignore this.

examples/usecases/mcp_github_to_slack_agent/mcp_agent.config.yaml (2)

32-34: Ensure token/env wiring.

Team ID is set, but make sure the Slack bot token env (e.g., SLACK_MCP_XOXP_TOKEN) is provided via secrets overlay so the child process gets it at runtime.


15-24: GitHub HTTP server config looks good.

Transport, timeouts, and allowed tools align with the prompt’s needs.

@alienzach alienzach merged commit 78118ac into main Sep 12, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants