- MCP Desktop - Microsoft Cloud Platform Desktop Client
MCP Desktop - Microsoft Cloud Platform Desktop Client
MCP Desktop - Microsoft Cloud Platform Desktop Client
MCP Desktop is an Electron-based desktop application that connects Claude to your Microsoft 365 data through the Model Context Protocol (MCP). It enables natural language access to emails, calendar events, files, and contacts with proper authentication and security, all from a native desktop experience.
Architecture Overview
The system follows a modular, layered architecture with clear separation of concerns:
- MCP Adapter (
mcp-adapter.cjs): Implements the Model Context Protocol to allow Claude to communicate with Microsoft 365 services. - Backend Server (
dev-server.cjs): Express server that handles API endpoints, routing, and orchestration. - API Controllers: Handle request validation, module invocation, and response formatting.
- Functional Modules: Implement domain-specific logic for mail, calendar, files, and people.
- Graph Services: Interact directly with Microsoft Graph API, handling authentication and data transformation.
- MSAL Authentication: Manages Microsoft identity tokens and authentication flows.
- Database (
mcp.sqlite): Local SQLite database for storing authentication tokens and session data.
Detailed Architecture Diagram
┌────────────────┐ ┌───────────────────────────────────┐ ┌─────────────────────────────────────┐
│ │ │ │ │ │
│ Claude LLM │◄────►│ MCP Adapter (mcp-adapter.cjs) │◄───►│ Backend Server (dev-server.cjs) │
│ Tool Calls │ │ • JSON-RPC handling │ │ • Express server │
│ │ │ • Tool mapping │ │ • Route registration │
└────────────────┘ │ • Parameter transformation │ │ • Middleware │
│ • HTTP client │ │ │
└───────────────────────────────────┘ └─────────────────┬───────────────────┘
│
▼
┌────────────────────────────────┐ ┌───────────────────────────────────┐ ┌─────────────────────────────────────┐
│ │ │ │ │ │
│ Microsoft Graph API │◄───►│ Graph Services (src/graph/*) │◄───►│ API Controllers (src/api/controllers)│
│ • Microsoft 365 Services │ │ • Graph client │ │ • Request validation │
│ • OAuth 2.0 endpoints │ │ • API operations │ │ • Parameter processing │
│ │ │ • Data normalization │ │ • Response formatting │
└────────────────────────────────┘ │ • Error handling │ │ • Error handling │
└─────────────────┬─────────────────┘ └─────────────────┬───────────────────┘
│ │
│ │
▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────────┐
│ │ │ │
│ MSAL Authentication │ │ Functional Modules (src/modules/*) │
│ • Token acquisition │ │ • Domain logic │
│ • Token refresh │ │ • Capability registration │
│ • Secure storage │ │ • Intent handling │
│ • Login flows │ │ • Caching │
└─────────────────────────────────┘ └─────────────────────────────────────┘
End-to-End Flow Description
The following describes the complete flow of a request from Claude through the system to Microsoft Graph API and back, using the files module as an example:
-
Claude Tool Call
- Claude issues a tool call (e.g.,
listFiles,uploadFile,getFileMetadata) - Tool parameters are passed as JSON-RPC to the MCP adapter
- Claude issues a tool call (e.g.,
-
MCP Adapter Processing
handleRequest()receives the JSON-RPC requesthandleToolCall()maps the tool name to a module and methodexecuteModuleMethod()transforms parameters if needed (e.g., formatting dates)- The adapter constructs an HTTP request to the backend server
-
Backend Routing
- Express routes the request to the appropriate controller (e.g.,
/api/v1/files→filesController.listFiles) - The controller validates input parameters using Joi schemas
- Express routes the request to the appropriate controller (e.g.,
-
Controller to Module
- The controller calls the appropriate files module method
- The module checks cache for applicable operations
- For cache misses, the module delegates to the Graph service
-
Graph Service to Microsoft Graph
- The Graph service constructs the appropriate Graph API request
- MSAL authentication is handled at this layer (token acquisition/refresh)
- The request is sent to Microsoft Graph API
- The response is received and initial error handling occurs
-
Response Processing
- Graph service returns data to the files module
- The module uses normalizers to transform the data to a consistent format
- Normalized data is cached where appropriate
- The controller formats the final HTTP response
-
Return to Claude
- MCP adapter receives the HTTP response
- The adapter formats it as a JSON-RPC response
- Claude receives the structured data and presents it to the user
This flow ensures clean separation of concerns, consistent error handling, and proper data normalization at each layer.
Getting Started
Prerequisites
- Node.js (v18+)
- npm (v7+)
- Microsoft 365 account
- Microsoft Azure App Registration (for Graph API)
- OpenAI API key (for LLM integration)
Installation
-
Clone the repository
git clone https://github.com/yourusername/mcp-microsoft-office.git cd mcp-microsoft-office -
Install dependencies
npm install -
Set up Microsoft Authentication
- Register a new app in the Azure Portal
- Set the redirect URI to
http://localhost:3000/api/auth/callback - Grant the following API permissions:
User.Read,Mail.Read,Mail.Send,Calendars.Read,Calendars.ReadWrite,Files.Read - Create a
.envfile with your app registration details:CLIENT_ID=your-client-id TENANT_ID=your-tenant-id REDIRECT_URI=http://localhost:3000/api/auth/callback LLM_PROVIDER=openai OPENAI_API_KEY=your-openai-api-key
-
Development Options
Start the combined server (API + frontend):
npm run devStart the Electron app with hot reloading:
npm run dev:electronStart just the web version:
npm run dev:web -
Open and authenticate
- For web version: Visit
http://localhost:3000 - For Electron: The app will open automatically
- Click "Login with Microsoft" and complete the authentication flow
- For web version: Visit
Claude Integration
Setting Up Claude Integration
-
Configure Claude Desktop:
- Edit your Claude Desktop configuration file (typically at
~/Library/Application Support/Claude/claude_desktop_config.json) - Add the MCP server configuration:
{ "mcpServers": { "m365": { "command": "node", "args": [ "/path/to/mcp-adapter.cjs" ], "restrictions": {} } } } - Replace
/path/to/mcp-adapter.cjswith the absolute path to your adapter file
- Edit your Claude Desktop configuration file (typically at
-
Start Your MCP Server:
- Ensure your MCP server is running (
npm run dev) - Authenticate with Microsoft in your browser
- Ensure your MCP server is running (
-
Use with Claude:
- Open Claude Desktop
- Claude will automatically connect to your MCP server
- Ask questions about your Microsoft 365 data
Available Tools
The MCP Gateway exposes these Microsoft 365 capabilities to Claude:
getMail- Read emails from your inboxsendMail- Send emails on your behalfsearchMail- Search for specific emailsflagMail- Flag/unflag emails
Calendar
getCalendar- Check your calendar eventscreateEvent- Create new calendar eventsupdateEvent- Modify existing eventsgetAvailability- Check free/busy timesfindMeetingTimes- Find suitable meeting slotsscheduleMeeting- Schedule meetings with smart time selection
Note on timezone handling: When creating or updating calendar events, Claude may use the IANA format timezone (e.g.,
Europe/Oslo) while Microsoft's API expects Windows format (e.g.,W. Europe Standard Time). The gateway handles this conversion automatically, but in some cases, especially for regions with multiple timezones, Claude might override the host user's or signed-in user's timezone preferences. For the most accurate results, always specify the desired timezone explicitly when scheduling events.
Files
listFiles- Browse your OneDrive/SharePoint filesuploadFile- Upload files to your storagedownloadFile- Download file contentgetFileMetadata- Get file information
People
findPeople- Find and resolve people by name or emailsearchPeople- Search across your organizationgetRelevantPeople- Get people most relevant to you
General
query- Natural language queries to your Microsoft data
Project Structure
/
├── mcp-adapter.cjs # MCP adapter implementation
├── dev-server.cjs # Express server for backend
├── data/ # Data storage
│ └── mcp.sqlite # SQLite database for authentication
├── logs/ # Application logs
│ └── mcp.log # Main log file
├── src/
│ ├── api/ # API endpoints
│ │ ├── controllers/ # Request handlers
│ │ └── routes.cjs # Route definitions
│ ├── auth/ # Authentication services
│ │ └── msal-service.cjs # Microsoft authentication
│ ├── core/ # Core services
│ │ ├── auth-service.cjs # Authentication
│ │ ├── monitoring-service.cjs # Logging and monitoring
│ │ ├── storage-service.cjs # Data storage
│ │ └── tools-service.cjs # Tool definitions
│ ├── graph/ # Microsoft Graph integration
│ │ ├── graph-client.cjs # Graph API client
│ │ ├── mail-service.cjs # Mail operations
│ │ ├── calendar-service.cjs # Calendar operations
│ │ ├── files-service.cjs # Files operations
│ │ ├── people-service.cjs # People/contacts operations
│ │ └── normalizers.cjs # Data normalization
│ ├── llm/ # LLM integration
│ │ └── llm-service.cjs # Language model service
│ ├── main/ # Electron main process
│ │ ├── index.cjs # Entry point
│ │ ├── combined-server.cjs # Combined server for Electron
│ │ ├── menu.cjs # Application menu
│ │ └── tray.cjs # System tray integration
│ ├── modules/ # Functional modules
│ │ ├── module-registry.cjs # Module management
│ │ ├── mail/ # Mail module
│ │ ├── calendar/ # Calendar module
│ │ ├── files/ # Files module
│ │ └── people/ # People module
│ ├── nlu/ # Natural language understanding
│ │ └── intent-router.cjs # Intent routing
│ └── renderer/ # Electron renderer process
│ ├── app.js # Main application
│ ├── components/ # UI components
│ ├── index.html # Main HTML
│ └── index.js # Renderer entry point
└── test/ # Tests
├── unit/ # Unit tests
├── integration/ # Integration tests
└── e2e/ # End-to-end tests
Development
Adding New Capabilities
To add a new Microsoft Graph capability:
- Implement Graph Service: Create/update a service in
src/graph/ - Add Data Normalizer: Add normalizer in
src/graph/normalizers.cjs - Implement Module: Add capability to appropriate module
- Create API Endpoint: Implement controller in
src/api/controllers/ - Register Route: Update routes in
src/api/routes.cjs - Define Tool: Add tool definition in
src/core/tools-service.cjs - Add to MCP Adapter: Update capability mapping in
mcp-adapter.cjs
See ProductRoadmap.md for more details on implementing new capabilities and the project's future direction.
Testing
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests
npm run test:integration
Design Principles
- Asynchronous Operations: All operations use async/await with proper Promise handling
- Error Handling: Consistent error creation, logging, and recovery
- Modular Architecture: Independent modules with clear interfaces
- Data Normalization: Standardized response formats for all Graph data
- Secure Authentication: Proper token management and refresh
- Centralized Logging: All components log to a central service with consistent formatting
- Electron Integration: Proper desktop application experience with tray and menu support
Logging System
MCP Desktop uses a comprehensive logging system based on Winston with the following features:
- Centralized Logging: All logs are written to
logs/mcp.log - Console Output: Formatted logs appear in the console during development
- Log Categories: Each log entry includes a category (e.g., 'api', 'graph', 'auth')
- Log Levels: Support for error, warn, info, and debug levels
- UI Integration: View logs directly in the application UI
- Event-based Architecture: Components can subscribe to log events
Log format in the console:
[MCP CATEGORY] Message
Log format in the file (JSON):
{
"timestamp": "2025-01-01T12:00:00.000Z",
"level": "info",
"message": "Log message",
"category": "graph",
"context": { /* Additional data */ },
"pid": 1234,
"hostname": "computer-name",
"version": "0.1.0"
}
Contributing
We welcome contributions! Please see our ProductRoadmap.md for planned features and enhancement ideas.