|
48 | 48 | list_webex_space_memberships, add_webex_space_membership, |
49 | 49 | # People functions |
50 | 50 | get_webex_me, list_webex_people, |
| 51 | + # Team functions |
| 52 | + list_webex_teams, get_webex_team, |
| 53 | + update_webex_team, delete_webex_team, |
| 54 | + list_webex_team_memberships, add_webex_team_membership, |
| 55 | + delete_webex_team_membership, |
51 | 56 | ) |
52 | 57 |
|
53 | 58 | # Import version and error handling from common |
@@ -119,6 +124,17 @@ async def dispatch(self, request, call_next): |
119 | 124 | mcp.tool()(get_webex_me) |
120 | 125 | mcp.tool()(list_webex_people) |
121 | 126 |
|
| 127 | +# Team management tools |
| 128 | +mcp.tool()(list_webex_teams) |
| 129 | +mcp.tool()(get_webex_team) |
| 130 | +mcp.tool()(update_webex_team) |
| 131 | +mcp.tool()(delete_webex_team) |
| 132 | + |
| 133 | +# Team membership tools |
| 134 | +mcp.tool()(list_webex_team_memberships) |
| 135 | +mcp.tool()(add_webex_team_membership) |
| 136 | +mcp.tool()(delete_webex_team_membership) |
| 137 | + |
122 | 138 |
|
123 | 139 | # ========== RESOURCES ========== |
124 | 140 | # Resources provide contextual information that AI assistants can read |
@@ -336,6 +352,89 @@ def webex_adaptive_cards_guide(): |
336 | 352 | """ |
337 | 353 |
|
338 | 354 |
|
| 355 | +@mcp.resource("webex://help/teams") |
| 356 | +def webex_teams_guide(): |
| 357 | + """Bot access model and guidance for Webex Teams tools""" |
| 358 | + return """# Webex Teams — Bot Access Guide |
| 359 | +
|
| 360 | +## What is a Team in Webex? |
| 361 | +
|
| 362 | +A team is a named group of people with a shared set of rooms. Teams are a higher-level |
| 363 | +construct than rooms: a team contains rooms, and all team members can see every room in |
| 364 | +the team. The team membership and team room membership are separate concepts. |
| 365 | +
|
| 366 | +## Bot Access Model (Verified Against the Webex API) |
| 367 | +
|
| 368 | +Bot tokens operate under stricter rules than user or integration tokens for the Teams API. |
| 369 | +Understanding these rules prevents confusing errors. |
| 370 | +
|
| 371 | +### What bots CAN do |
| 372 | +
|
| 373 | +| Tool | Requirement | |
| 374 | +|------|-------------| |
| 375 | +| `list_webex_teams` | Bot is a member of at least one team | |
| 376 | +| `get_webex_team` | Bot is a member of that team | |
| 377 | +| `list_webex_team_memberships` | Bot is a member of that team | |
| 378 | +| `update_webex_team` | Bot has the **moderator** role in that team | |
| 379 | +| `delete_webex_team` | Bot has the **moderator** role in that team | |
| 380 | +| `add_webex_team_membership` | Bot has the **moderator** role in that team | |
| 381 | +| `delete_webex_team_membership` | Bot has the **moderator** role in that team | |
| 382 | +
|
| 383 | +### What bots CANNOT do |
| 384 | +
|
| 385 | +| Operation | Reason | |
| 386 | +|-----------|--------| |
| 387 | +| **Create a team** | Hard platform restriction — `POST /teams` returns 401 for bot tokens regardless of scopes. This is not an error in the MCP; it is enforced by the Webex platform. | |
| 388 | +
|
| 389 | +`create_webex_team` is intentionally not implemented in this MCP server. To create a |
| 390 | +team, use a personal access token or an OAuth integration with the `spark:teams_write` |
| 391 | +scope. |
| 392 | +
|
| 393 | +## Getting the Bot Into a Team |
| 394 | +
|
| 395 | +Before any team tool will work, a human user must add the bot to the team: |
| 396 | +
|
| 397 | +1. **Via Webex UI**: Open the team in the Webex app → Members → Add member → paste the |
| 398 | + bot's email address (visible in `get_webex_me`). |
| 399 | +2. **Via API with a user token**: |
| 400 | + ``` |
| 401 | + POST https://webexapis.com/v1/team/memberships |
| 402 | + { "teamId": "<id>", "personEmail": "<bot-email>", "isModerator": true } |
| 403 | + ``` |
| 404 | + Set `isModerator: true` if you want the bot to be able to update the team or manage |
| 405 | + members. |
| 406 | +
|
| 407 | +## Understanding 404 vs 403 Errors |
| 408 | +
|
| 409 | +- **404 "not found"** from a team tool usually means the bot is not a member of the team, |
| 410 | + not that the team ID is wrong. Verify the bot has been added first. |
| 411 | +- **403 "forbidden"** from a write tool means the bot is a regular member but not a |
| 412 | + moderator. Upgrade the bot's role in the team to moderator. |
| 413 | +
|
| 414 | +## Typical Workflow |
| 415 | +
|
| 416 | +``` |
| 417 | +1. list_webex_teams() |
| 418 | + → Empty? A human must add the bot to a team first (see above). |
| 419 | +
|
| 420 | +2. list_webex_teams() |
| 421 | + → Returns teams the bot belongs to. Pick a team_id. |
| 422 | +
|
| 423 | +3. get_webex_team(team_id) |
| 424 | + → Confirm team details. |
| 425 | +
|
| 426 | +4. list_webex_team_memberships(team_id) |
| 427 | + → See who is in the team. Check bot's isModerator value. |
| 428 | +
|
| 429 | +5. add_webex_team_membership(team_id, person_email="...", is_moderator=False) |
| 430 | + → Requires bot to be a moderator. |
| 431 | +
|
| 432 | +6. delete_webex_team_membership(membership_id) |
| 433 | + → Requires bot to be a moderator. |
| 434 | +``` |
| 435 | +""" |
| 436 | + |
| 437 | + |
339 | 438 | @mcp.resource("webex://config/current") |
340 | 439 | def webex_current_config(): |
341 | 440 | """Current Webex bot configuration and status""" |
@@ -1018,7 +1117,7 @@ def server_version(): |
1018 | 1117 | "streamable-http", "stdio", |
1019 | 1118 | "error-handling", "versioning" |
1020 | 1119 | ], |
1021 | | - "tools_count": 27, |
| 1120 | + "tools_count": 34, |
1022 | 1121 | "resources_count": 11, |
1023 | 1122 | "prompts_count": 8, |
1024 | 1123 | "breaking_changes": { |
|
0 commit comments