"""
High-level API functions for Microsoft Graph MCP.
These are exposed to Claude via the 'msgraph' module in the sandbox.
"""
from typing import Dict, List, Optional, Any
from .graph_client import get_client
import json
def _format_result(data: Any) -> Dict:
"""Wrap result with metadata."""
if isinstance(data, list):
return {"count": len(data), "items": data}
return data
# ========================================
# Connection & Utility
# ========================================
def test_connection() -> Dict:
"""Test Microsoft Graph API connectivity."""
client = get_client()
return client.test_connection()
def list_users(query: str = None, limit: int = 50) -> Dict:
"""
List users in the organization.
Args:
query: Optional filter by name/email prefix
limit: Max results (default 50)
Returns:
Dict with count and user list
"""
client = get_client()
users = client.list_users(query=query, limit=limit)
return _format_result(users)
def get_user(user_email: str) -> Dict:
"""
Get user details by email.
Args:
user_email: User's email address
Returns:
User profile dict
"""
client = get_client()
return client.get_user(user_email)
# ========================================
# SharePoint
# ========================================
def search_sites(query: str, limit: int = 10) -> Dict:
"""
Search for SharePoint sites.
Args:
query: Search query (site name)
limit: Max results
Returns:
Dict with count and site list
"""
client = get_client()
sites = client.search_sites(query, limit=limit)
return _format_result(sites)
def get_site(site_id: str) -> Dict:
"""
Get SharePoint site details.
Args:
site_id: Site ID (e.g., 'contoso.sharepoint.com,guid,guid')
Returns:
Site details dict
"""
client = get_client()
return client.get_site(site_id)
def list_site_contents(site_id: str, path: str = "/") -> Dict:
"""
List files and folders in a SharePoint site.
Args:
site_id: SharePoint site ID
path: Folder path (default: root)
Returns:
Dict with count and item list
"""
client = get_client()
items = client.list_drive_items(site_id, path)
return _format_result(items)
def search_files(query: str, site_id: str = None, limit: int = 20) -> Dict:
"""
Search for files across SharePoint.
Args:
query: Search query
site_id: Optional site to scope search
limit: Max results
Returns:
Dict with count and file list
"""
client = get_client()
files = client.search_files(query, site_id=site_id, limit=limit)
return _format_result(files)
def get_file_content(site_id: str, item_id: str) -> Dict:
"""
Get file content (text files only, max 10MB).
Args:
site_id: SharePoint site ID
item_id: File item ID
Returns:
Dict with content or error
"""
client = get_client()
content = client.get_file_content(site_id, item_id)
if content is None:
return {"error": "File too large or not accessible"}
try:
text = content.decode("utf-8")
return {"content": text, "size": len(content)}
except UnicodeDecodeError:
return {"error": "Binary file - cannot display as text", "size": len(content)}
def get_file_metadata(site_id: str, item_id: str) -> Dict:
"""
Get file metadata.
Args:
site_id: SharePoint site ID
item_id: File item ID
Returns:
File metadata dict
"""
client = get_client()
return client.get_file_metadata(site_id, item_id)
# ========================================
# OneDrive
# ========================================
def list_user_files(user_email: str, path: str = "/") -> Dict:
"""
List files in a user's OneDrive.
Args:
user_email: User's email
path: Folder path (default: root)
Returns:
Dict with count and file list
"""
client = get_client()
files = client.list_user_files(user_email, path)
return _format_result(files)
def search_user_files(user_email: str, query: str, limit: int = 20) -> Dict:
"""
Search files in a user's OneDrive.
Args:
user_email: User's email
query: Search query
limit: Max results
Returns:
Dict with count and file list
"""
client = get_client()
files = client.search_user_files(user_email, query, limit=limit)
return _format_result(files)
# ========================================
# Outlook Mail
# ========================================
def search_emails(
query: str,
user_email: str,
limit: int = 20
) -> Dict:
"""
Search emails in a user's mailbox.
Args:
query: Search query (subject, body, sender)
user_email: User's email address
limit: Max results
Returns:
Dict with count and email list
"""
client = get_client()
emails = client.search_emails(query, user_id_or_email=user_email, limit=limit)
return _format_result(emails)
def list_recent_emails(
user_email: str,
limit: int = 20,
folder: str = "inbox"
) -> Dict:
"""
List recent emails from a user's mailbox.
Args:
user_email: User's email address
limit: Number of emails
folder: Folder name (inbox, sentitems, drafts)
Returns:
Dict with count and email list
"""
client = get_client()
emails = client.list_recent_emails(user_email, limit=limit, folder=folder)
return _format_result(emails)
def get_email(user_email: str, message_id: str) -> Dict:
"""
Get full email content.
Args:
user_email: User's email address
message_id: Email message ID
Returns:
Full email dict including body
"""
client = get_client()
return client.get_email(user_email, message_id)
# ========================================
# Teams
# ========================================
def list_teams(limit: int = 50) -> Dict:
"""
List all Teams the app can access.
Args:
limit: Max results
Returns:
Dict with count and team list
"""
client = get_client()
teams = client.list_teams(limit=limit)
return _format_result(teams)
def get_team(team_id: str) -> Dict:
"""
Get team details.
Args:
team_id: Team ID (GUID)
Returns:
Team details dict
"""
client = get_client()
return client.get_team(team_id)
def list_channels(team_id: str) -> Dict:
"""
List channels in a team.
Args:
team_id: Team ID
Returns:
Dict with count and channel list
"""
client = get_client()
channels = client.list_channels(team_id)
return _format_result(channels)
def get_channel_messages(
team_id: str,
channel_id: str,
limit: int = 50
) -> Dict:
"""
Get recent messages from a Teams channel.
Args:
team_id: Team ID
channel_id: Channel ID
limit: Max messages
Returns:
Dict with count and message list
"""
client = get_client()
messages = client.get_channel_messages(team_id, channel_id, limit=limit)
return _format_result(messages)
def search_channel_messages(
team_id: str,
channel_id: str,
query: str,
limit: int = 20
) -> Dict:
"""
Search messages in a Teams channel.
Args:
team_id: Team ID
channel_id: Channel ID
query: Search query
limit: Max results
Returns:
Dict with count and matching messages
"""
client = get_client()
messages = client.search_channel_messages(team_id, channel_id, query, limit=limit)
return _format_result(messages)
# ========================================
# Calendar
# ========================================
def list_events(
user_email: str,
days_ahead: int = 7,
days_back: int = 0
) -> Dict:
"""
List calendar events for a user.
Args:
user_email: User's email
days_ahead: Days to look forward (default 7)
days_back: Days to look back (default 0)
Returns:
Dict with count and event list
"""
client = get_client()
events = client.list_events(user_email, days_ahead=days_ahead, days_back=days_back)
return _format_result(events)
def search_events(user_email: str, query: str, limit: int = 20) -> Dict:
"""
Search calendar events by subject.
Args:
user_email: User's email
query: Search query (subject)
limit: Max results
Returns:
Dict with count and event list
"""
client = get_client()
events = client.search_events(user_email, query, limit=limit)
return _format_result(events)
def get_event(user_email: str, event_id: str) -> Dict:
"""
Get full event details.
Args:
user_email: User's email
event_id: Event ID
Returns:
Full event dict
"""
client = get_client()
return client.get_event(user_email, event_id)
# ========================================
# Module Exports (for sandbox)
# ========================================
__all__ = [
# Utility
"test_connection",
"list_users",
"get_user",
# SharePoint
"search_sites",
"get_site",
"list_site_contents",
"search_files",
"get_file_content",
"get_file_metadata",
# OneDrive
"list_user_files",
"search_user_files",
# Outlook
"search_emails",
"list_recent_emails",
"get_email",
# Teams
"list_teams",
"get_team",
"list_channels",
"get_channel_messages",
"search_channel_messages",
# Calendar
"list_events",
"search_events",
"get_event",
]