This codelab will walk you through integrating Zoom workplace data into an MCP server and building an MCP client using the Anthropic Python Model Context Protocol SDK.
The first tool reads oom Workplace Contextual data by resource and ID.
@mcp.tool(
"read_zoom_resource",
description="Read a Zoom Workplace item (meeting, chat message, email, or calendar event) by type and ID."
)
def read_zoom_resource(
resource_type: ResourceType = Field(
description="The Zoom dataset to read from. One of: 'meetings', 'team_chat', 'mail', 'calendar'."
),
resource_id: str = Field(
description="The ID of the item to read (e.g., meetingId, messageId, emailId, eventId)."
),
):
"""
Returns the stored dict for the requested Zoom Workplace item.
"""
_, item = _ensure_resource(resource_type, resource_id)
return item
The second tool performs simple find-and-replace operations on requested Zoom Workplace item:
@mcp.tool(
name="edit_document",
description="Edit a document by replacing a string in the documents content with a new string."
)
def edit_zoom_resource(
resource_type: ResourceType = Field(
description="The Zoom dataset to write to. One of: 'meetings', 'team_chat', 'mail', 'calendar'."
),
resource_id: str = Field(
description="The ID of the item to edit or create (e.g., meetingId, messageId, emailId, eventId)."
),
new_content: dict = Field(
description="The replacement content for this item. Entire object is replaced."
),
):
"""
Replaces the entire item content. For partial updates, add another tool that merges dicts.
"""
if resource_type not in zoom_data:
raise ValueError(f"Unknown resource_type '{resource_type}'. "
f"Use one of: meetings, team_chat, mail, calendar.")
collection = zoom_data[resource_type]
collection[resource_id] = new_content
return collection[resource_id]
Run the following command to lauch the Python MCP SDK includes a built-in browser-based inspector that lets you debug and test your server in real-time.
mcp dev server.py
This starts a development server and gives you a local URL, typically something like http://127.0.0.1:6274. Open this URL in your browser to access the MCP Inspector.
Navigate to the Tools section and click "List Tools" to see all available tools from your server. When you select a tool, the right panel shows its details and input fields.
The inspector shows both the success status and the actual returned data, making it easy to verify your tool works correctly.
Add details on connecting with MCP clients overview
# TODO: Return a list of tools defined by the MCP server
async def list_tools(self) -> list[types.Tool]:
result= await self.session().list_tools()
return result.tools
# TODO: Call a particular tool and return the result
async def call_tool(
self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
return await self.session().call_tool(tool_name, tool_input)
# For testing
async def main():
async with MCPClient(
# If using Python without UV, update command to 'python' and remove "run" from args.
command="python3",
args=[ "mcp_server.py"],
) as _client:
result = await _client.list_tools()
print("Tools:", result)
python3 mcp_client.py
You should see the out of the read and edit tools created earlier. Each tool includes a description and input schema as well. This defination will be passed off to Claude.
python3 main.py
Ask Claude the following:
What is the agenda for meeting ID "987654321" ?
When we run this, Claude will:
@mcp.resource("res://resources", mime_type="application/json")
def list_zoom_resources():
"""
List all Zoom Workplace resource IDs by type.
Returns:
{
"meetings": ["123456789", "987654321"],
"team_chat": ["msg_1001", "msg_1002"],
"mail": ["email_2001"],
"calendar": ["event_3001"]
}
"""
return {
rtype: sorted(items.keys(), key=str)
for rtype, items in zoom_data.items()
}
@mcp.resource("res://resources/{resource_type}/{resource_id}")
def get_zoom_resource(
resource_type: ResourceType,
resource_id: str,
):
"""
Get a specific Zoom Workplace item by type and ID.
Example paths:
res://resources/meetings/987654321
res://resources/team_chat/msg_1001
res://resources/mail/email_2001
res://resources/calendar/event_3001
"""
if resource_type not in zoom_data:
raise ValueError(f"Unknown resource_type '{resource_type}'. "
f"Use one of: meetings, team_chat, mail, calendar.")
_, item = _ensure_resource(resource_type, resource_id)
return item
You build MCP server that can access Zoom Workplace contextual data using the PYTHON SDK.