Skip to main content
Glama

Apple Find My MCP Server

by batteryshark
authentication.py3.57 kB
""" Apple Find My authentication flow. """ from pyicloud import PyiCloudService from pyicloud.exceptions import PyiCloudAPIResponseException, PyiCloudFailedLoginException from credentials import elicit_credentials, get_apple_id_from_secrets, get_apple_password_from_secrets, get_2fa_code, select_device, get_2sa_code from fastmcp import Context async def authenticate_client(ctx: Context, client: PyiCloudService) -> PyiCloudService: """Handle authentication flow for iCloud client.""" await ctx.info("🔐 Checking authentication status...") # Check if already authenticated if not client.requires_2fa and not client.requires_2sa and client.is_trusted_session: await ctx.info("✅ Already authenticated") return client # Handle 2FA if client.requires_2fa: await ctx.info("🔐 2FA required") await ctx.info("Check your Apple devices for verification code") code = await get_2fa_code(ctx) if not client.validate_2fa_code(code): raise ValueError("❌ 2FA verification failed") # Establish trusted session if not client.is_trusted_session: await ctx.info("🔒 Establishing trusted session...") trust_result = client.trust_session() if not trust_result: await ctx.info("⚠️ Trusted session failed - may need 2FA again") # Handle 2SA elif client.requires_2sa: await ctx.info("🔐 2SA required") devices = client.trusted_devices device_idx = await select_device(ctx, devices) selected_device = devices[device_idx] if not client.send_verification_code(selected_device): raise ValueError("❌ Failed to send verification code") await ctx.info(f"📱 Code sent to {selected_device.get('deviceName', 'device')}") code = await get_2sa_code(ctx) if not client.validate_verification_code(selected_device, code): raise ValueError("❌ 2SA verification failed") await ctx.info("✅ 2SA successful") await ctx.info("✅ Authentication complete") return client async def create_authenticated_client(ctx: Context) -> PyiCloudService: """Create and authenticate iCloud client.""" # Try with stored credentials first try: apple_id = await get_apple_id_from_secrets() password = await get_apple_password_from_secrets() if apple_id and password: await ctx.info(f"🔑 Found stored credentials for: {apple_id}") client = PyiCloudService(apple_id, password) return await authenticate_client(ctx, client) elif apple_id and not password: # Have Apple ID but no password - try without password (will use pyicloud keyring) await ctx.info(f"🔑 Found Apple ID: {apple_id} (using pyicloud keyring for password)") client = PyiCloudService(apple_id) return await authenticate_client(ctx, client) except PyiCloudFailedLoginException: await ctx.info("⚠️ Stored credentials failed, will elicit new ones") # Fall back to manual credentials await ctx.info("🔐 Credentials required") apple_id, password = await elicit_credentials(ctx) try: client = PyiCloudService(apple_id, password) return await authenticate_client(ctx, client) except PyiCloudFailedLoginException as e: raise ValueError(f"❌ Authentication failed: {e}") except PyiCloudAPIResponseException as e: raise ValueError(f"❌ iCloud API error: {e}")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/batteryshark/mcp-findmy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server