feat: add slackbot mcp client examples with various authentication techniques#66
Conversation
Add manifests, READMEs, requirements, and static files for all four MCP client examples (no-auth, slack-identity, DCR, external-auth). Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Force-add .env.example files that are excluded by the .env* gitignore pattern to provide template environment configuration. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Fix body-consuming bug in SlackSignatureMiddleware that prevented the downstream MCP handler from reading the request body. Add replay_receive to make the body available after signature verification. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add 4 integration tests for profile card MCP server - Add mcp:connect to OAuth scopes to match manifest - Add MCP examples to CI test matrix with fail-fast: false - Add dependabot entries for both MCP example directories - Update root README with AI/MCP examples section - Make mypy conditional in CI (only if installed) Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add mypy>=2.1.0 to both MCP example requirements - Use ToolAnnotations object instead of dict literal - Handle None case for model_extra in slack-identity - Remove conditional mypy in CI (all examples have it now) Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Use Route instead of Mount to serve /mcp directly (eliminates 307 redirect that Slack's MCP client does not follow on POST) - Add _meta.ui.csp with esm.sh domains to dice resource (unblocks script loading in sandboxed iframe) - Document --host-header=rewrite for ngrok (satisfies DNS-rebinding protection allowlist) - Reorder app.py sections to mirror JS examples (MCP first, Bolt second) - Clean up test files (inline MCP_PATH, move helpers to bottom) Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add docstrings mirroring JS examples, remove section comments - Inline bolt_handler, rename tests to match JS equivalents - Replace httpx with httpx2, sort requirements alphabetically - Use os.environ[] instead of fallback empty string for signing secret Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
|
🏁 Making note here before significant refactors follow! At this point we have stable examples. |
Reorganize the Slackbot MCP client examples so authentication methods and rich responses are separate concerns: - Add rich-responses/mcp-apps (dice roller with interactive UI, no_auth) - Strip the interactive UI from no-auth so it demonstrates auth only - Strip Block Kit from slack-identity so it demonstrates auth only - Split the section README into "Authentication methods" and "Rich responses", and point docs links at page anchors - Fix .gitignore ordering so .env.example is no longer ignored - Add rich-responses/mcp-apps to the CI matrix and dependabot Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Order the dependabot pip directories alphabetically to match the CI test matrix, and keep the not-installed message on a single line. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
|
🏁 Will merge to mirror slack-samples/bolt-js-examples#83! |
zimeg
left a comment
There was a problem hiding this comment.
📣 Thoughts from earlier! We'll delete the branch once confident in adjacent references 🌚
| @contextlib.asynccontextmanager | ||
| async def lifespan(a): | ||
| async with mcp_server.session_manager.run(): | ||
| yield | ||
|
|
||
|
|
||
| mcp_app = mcp_server.streamable_http_app() |
There was a problem hiding this comment.
🦠 ramble: Implementation concern but this is kept closer toward app start instead of the existing MCP setup for sake of mirroring the JS pattern:
| ## Setup | ||
|
|
||
| ```sh | ||
| $ ngrok http 3000 --host-header=rewrite # Update manifest with new URL |
There was a problem hiding this comment.
👾 note: This is a requirement to broken app configurations due to unexpected host validation. We prefer to claim proxied requests are from localhost.
| state_store=FileOAuthStateStore( | ||
| expiration_seconds=600, | ||
| base_dir="./states", | ||
| ), |
There was a problem hiding this comment.
🔭 note: We don't have an equivalent ClearStateStore so use the file state store in this example.
There was a problem hiding this comment.
🎲 note: Interactive UI is moved to rich-responses/mcp-apps for a more focused example!
Summary
This PR adds Slackbot MCP client examples with various authentication methods and rich responses:
Architecture
All code examples use Starlette to compose Bolt (via
SlackRequestHandler) and MCP (viaFastMCP.streamable_http_app()) in a single ASGI process. ASlackSignatureMiddlewareverifies request signatures before forwarding to the MCP handler.Authentication methods (
no-auth,slack-identity, DCR, external auth) demonstrate auth alone and respond with plain text. Rich responses (rich-responses/mcp-apps) demonstrate returning an interactive UI.Preview
📚 https://github.com/slack-samples/bolt-python-examples/tree/feat/mcp-client-examples
Reviewers
Please don't fear the LOC added! Testing steps might review separate steps for focused benefits. I recommend:
READMEand commentsPlease feel free to follow setup steps included - latest manual tests are confirmed to work! 🔏 ✨
ruff,mypy, andpytestpass for all code examples.Notes
Requirements