outlook-cli 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,994 @@
1
+ # outlook-cli
2
+
3
+ Production-ready CLI and MCP server for Microsoft Outlook through Microsoft Graph.
4
+
5
+ **GitHub:** https://github.com/selvin-paul-raj/outlook-cli
6
+
7
+ ---
8
+
9
+ ## What This Package Gives You
10
+
11
+ - Global CLI command: `outlook-cli`
12
+ - One-time OAuth token storage — reused across runs and updates
13
+ - Human-friendly commands with rich terminal output, plus machine-friendly `--json` mode
14
+ - 19 MCP tools available to Claude and other AI assistants via the shared tool registry
15
+ - Full email, calendar, folder, and rules management through Microsoft Graph API
16
+
17
+ ---
18
+
19
+ ## Install
20
+
21
+ ### Global (recommended)
22
+
23
+ ```bash
24
+ npm i -g outlook-cli
25
+ ```
26
+
27
+ ```bash
28
+ outlook-cli --help
29
+ ```
30
+
31
+ ### Local development
32
+
33
+ ```bash
34
+ npm install
35
+ npm run cli -- --help
36
+ ```
37
+
38
+ **Requirements:** Node.js >= 18.0.0
39
+
40
+ ---
41
+
42
+ ## Azure App Setup (Required)
43
+
44
+ Before using this package you need an Azure app registration:
45
+
46
+ 1. Go to [portal.azure.com](https://portal.azure.com) → Azure Active Directory → App registrations → New registration
47
+ 2. Set redirect URI to: `http://localhost:3333/auth/callback`
48
+ 3. Under API Permissions, add Microsoft Graph delegated permissions:
49
+ - `Mail.Read`, `Mail.ReadWrite`, `Mail.Send`
50
+ - `Calendars.Read`, `Calendars.ReadWrite`
51
+ - `User.Read`
52
+ - `offline_access`
53
+ 4. Under Certificates & Secrets → New client secret — copy the **Value** (not the Secret ID)
54
+ 5. Copy your Application (client) ID from the Overview page
55
+
56
+ ---
57
+
58
+ ## Quick Start
59
+
60
+ ### 1. Set credentials
61
+
62
+ **PowerShell (Windows):**
63
+ ```powershell
64
+ $env:OUTLOOK_CLIENT_ID="your-client-id-here"
65
+ $env:OUTLOOK_CLIENT_SECRET="your-client-secret-value-here"
66
+ ```
67
+
68
+ **Bash/zsh (Linux/Mac):**
69
+ ```bash
70
+ export OUTLOOK_CLIENT_ID="your-client-id-here"
71
+ export OUTLOOK_CLIENT_SECRET="your-client-secret-value-here"
72
+ ```
73
+
74
+ **Or use a `.env` file (copy from `.env.example`):**
75
+ ```bash
76
+ cp .env.example .env
77
+ # Edit .env with your credentials
78
+ ```
79
+
80
+ ### 2. Start the auth server (required for first-time login)
81
+
82
+ ```bash
83
+ npm run auth-server
84
+ # or
85
+ outlook-cli auth server --start
86
+ ```
87
+
88
+ This starts an OAuth callback server on port 3333. Keep it running during authentication.
89
+
90
+ ### 3. Authenticate once
91
+
92
+ ```bash
93
+ outlook-cli auth login --open --start-server --wait
94
+ ```
95
+
96
+ This opens your browser to the Microsoft login page. After you approve, tokens are saved to `~/.outlook-mcp-tokens.json` and reused for all future runs.
97
+
98
+ ### 4. Verify and explore
99
+
100
+ ```bash
101
+ outlook-cli auth status # confirm authenticated
102
+ outlook-cli tools list # see all available tools
103
+ outlook-cli email list # list recent inbox emails
104
+ outlook-cli calendar list # list upcoming events
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Environment Variables
110
+
111
+ ### Required
112
+
113
+ | Variable | Description |
114
+ |---|---|
115
+ | `OUTLOOK_CLIENT_ID` | Azure app Application (client) ID |
116
+ | `OUTLOOK_CLIENT_SECRET` | Azure app client secret **value** (not the Secret ID) |
117
+
118
+ ### Optional
119
+
120
+ | Variable | Default | Description |
121
+ |---|---|---|
122
+ | `OUTLOOK_REDIRECT_URI` | `http://localhost:3333/auth/callback` | OAuth redirect URL |
123
+ | `OUTLOOK_SCOPES` | `offline_access Mail.Read Mail.ReadWrite Mail.Send User.Read Calendars.Read Calendars.ReadWrite` | Microsoft Graph permission scopes |
124
+ | `OUTLOOK_TOKEN_STORE_PATH` | `~/.outlook-mcp-tokens.json` | Where tokens are saved on disk |
125
+ | `OUTLOOK_TOKEN_ENDPOINT` | Microsoft consumer OAuth endpoint | Token exchange URL |
126
+ | `OUTLOOK_AUTH_SERVER_URL` | `http://localhost:3333` | Auth server base URL |
127
+ | `USE_TEST_MODE` | `false` | Use mock data instead of real API calls |
128
+
129
+ **Legacy aliases** (backward-compatible): `MS_CLIENT_ID`, `MS_CLIENT_SECRET`, `MS_REDIRECT_URI`, `MS_SCOPES`, `MS_TOKEN_STORE_PATH`, `MS_TOKEN_ENDPOINT`, `MS_AUTH_SERVER_URL`
130
+
131
+ ---
132
+
133
+ ## Command Groups
134
+
135
+ ### `auth` — Authentication
136
+
137
+ | Command | Description | Example |
138
+ |---|---|---|
139
+ | `auth status` | Show current authentication status | `outlook-cli auth status` |
140
+ | `auth login` | Start authentication flow | `outlook-cli auth login --open --start-server --wait` |
141
+ | `auth url` | Show the OAuth URL without opening browser | `outlook-cli auth url` |
142
+ | `auth logout` | Clear stored tokens | `outlook-cli auth logout` |
143
+
144
+ **Flags for `auth login`:**
145
+ - `--open` — Automatically open the auth URL in your browser
146
+ - `--start-server` — Start the OAuth callback server automatically
147
+ - `--wait` — Wait for authentication to complete before returning
148
+
149
+ **Examples:**
150
+ ```bash
151
+ # Full login with browser open and wait
152
+ outlook-cli auth login --open --start-server --wait
153
+
154
+ # Just get the URL to open manually
155
+ outlook-cli auth url
156
+
157
+ # Check if you're logged in
158
+ outlook-cli auth status
159
+
160
+ # Force re-authentication
161
+ outlook-cli auth login --open --force
162
+ ```
163
+
164
+ ---
165
+
166
+ ### `email` — Email Management
167
+
168
+ | Command | Description | Example |
169
+ |---|---|---|
170
+ | `email list` | List recent emails | `outlook-cli email list --count 20` |
171
+ | `email search` | Search emails by criteria | `outlook-cli email search --from boss@company.com` |
172
+ | `email read` | Read full email content | `outlook-cli email read --id AAMkAGVm...` |
173
+ | `email send` | Send a new email | `outlook-cli email send --to user@example.com --subject "Hi" --body "Hello"` |
174
+ | `email mark-read` | Mark email as read or unread | `outlook-cli email mark-read --id AAMkAGVm...` |
175
+
176
+ ---
177
+
178
+ #### `email list` — List Recent Emails
179
+
180
+ Lists emails from a folder, sorted newest first.
181
+
182
+ **Parameters:**
183
+
184
+ | Flag | Type | Default | Description |
185
+ |---|---|---|---|
186
+ | `--folder` | string | `inbox` | Folder to list from: `inbox`, `sent`, `drafts`, `deleted`, `junk`, `archive`, or any custom folder name |
187
+ | `--count` | number | `10` | Number of emails to return (1–50) |
188
+
189
+ **Examples:**
190
+ ```bash
191
+ # Default: 10 most recent inbox emails
192
+ outlook-cli email list
193
+
194
+ # Last 25 inbox emails
195
+ outlook-cli email list --count 25
196
+
197
+ # 10 most recent sent emails
198
+ outlook-cli email list --folder sent
199
+
200
+ # 15 emails from a custom folder
201
+ outlook-cli email list --folder "Project Alpha" --count 15
202
+
203
+ # Output as JSON for scripting
204
+ outlook-cli email list --count 5 --json
205
+ ```
206
+
207
+ **Output shows:** Email ID, sender, subject, date, read/unread status, attachment indicator, body preview.
208
+
209
+ ---
210
+
211
+ #### `email search` — Search Emails
212
+
213
+ Searches emails using text and/or filter criteria. Supports multiple criteria simultaneously.
214
+
215
+ **Parameters:**
216
+
217
+ | Flag | Type | Description |
218
+ |---|---|---|
219
+ | `--query` | string | Full-text search across subject, body, and sender |
220
+ | `--folder` | string | Folder to search (default: `inbox`) |
221
+ | `--from` | string | Filter by sender email or name |
222
+ | `--to` | string | Filter by recipient email |
223
+ | `--subject` | string | Filter by subject text |
224
+ | `--hasAttachments` | boolean | Only show emails with attachments |
225
+ | `--unreadOnly` | boolean | Only show unread emails |
226
+ | `--count` | number | Max results (1–50, default: 10) |
227
+
228
+ **Examples:**
229
+ ```bash
230
+ # Search by keyword
231
+ outlook-cli email search --query "quarterly report"
232
+
233
+ # Find unread emails from a specific sender
234
+ outlook-cli email search --from manager@company.com --unreadOnly
235
+
236
+ # Find emails with attachments about invoices
237
+ outlook-cli email search --subject invoice --hasAttachments
238
+
239
+ # Search sent folder for emails to a client
240
+ outlook-cli email search --folder sent --to client@example.com
241
+
242
+ # Complex search
243
+ outlook-cli email search --from finance@company.com --subject "budget" --unreadOnly --count 20
244
+
245
+ # JSON output
246
+ outlook-cli email search --query "meeting notes" --json
247
+ ```
248
+
249
+ ---
250
+
251
+ #### `email read` — Read Full Email
252
+
253
+ Reads the complete content of one email by its ID.
254
+
255
+ **Parameters:**
256
+
257
+ | Flag | Type | Required | Description |
258
+ |---|---|---|---|
259
+ | `--id` | string | yes | Email ID from `email list` or `email search` output |
260
+
261
+ **Examples:**
262
+ ```bash
263
+ # Read a specific email
264
+ outlook-cli email read --id AAMkAGVmMDAwAT...
265
+
266
+ # Read and output as JSON
267
+ outlook-cli email read --id AAMkAGVmMDAwAT... --json
268
+ ```
269
+
270
+ **Output shows:** From, To, CC, BCC, Subject, Date, Importance, Attachment status, full Body text (HTML auto-converted to plain text).
271
+
272
+ **Tip:** Get email IDs from `email list` or `email search` output first.
273
+
274
+ ---
275
+
276
+ #### `email send` — Send Email
277
+
278
+ Composes and sends an email from the user's account.
279
+
280
+ **Parameters:**
281
+
282
+ | Flag | Type | Required | Default | Description |
283
+ |---|---|---|---|---|
284
+ | `--to` | string | yes | — | Recipient(s), comma-separated for multiple |
285
+ | `--subject` | string | yes | — | Email subject |
286
+ | `--body` | string | yes | — | Email body (plain text or HTML) |
287
+ | `--cc` | string | no | — | CC recipient(s), comma-separated |
288
+ | `--bcc` | string | no | — | BCC recipient(s), comma-separated |
289
+ | `--importance` | string | no | `normal` | Priority: `normal`, `high`, or `low` |
290
+ | `--saveToSentItems` | boolean | no | `true` | Save copy to Sent folder |
291
+
292
+ **Examples:**
293
+ ```bash
294
+ # Simple email
295
+ outlook-cli email send \
296
+ --to colleague@company.com \
297
+ --subject "Meeting notes" \
298
+ --body "Here are today's action items..."
299
+
300
+ # Email to multiple recipients with CC and high priority
301
+ outlook-cli email send \
302
+ --to "team@company.com,manager@company.com" \
303
+ --cc hr@company.com \
304
+ --subject "URGENT: System outage" \
305
+ --body "We are investigating..." \
306
+ --importance high
307
+
308
+ # Email without saving to sent folder
309
+ outlook-cli email send \
310
+ --to test@example.com \
311
+ --subject "Test" \
312
+ --body "Hello" \
313
+ --saveToSentItems false
314
+ ```
315
+
316
+ **Notes:**
317
+ - HTML body is detected automatically when the body contains `<html`.
318
+ - Attachments are not supported — body text only.
319
+
320
+ ---
321
+
322
+ #### `email mark-read` — Mark Email Read/Unread
323
+
324
+ Changes the read status of an email.
325
+
326
+ **Parameters:**
327
+
328
+ | Flag | Type | Required | Default | Description |
329
+ |---|---|---|---|---|
330
+ | `--id` | string | yes | — | Email ID |
331
+ | `--isRead` | boolean | no | `true` | `true` = mark read, `false` = mark unread |
332
+
333
+ **Examples:**
334
+ ```bash
335
+ # Mark as read (default)
336
+ outlook-cli email mark-read --id AAMkAGVmMDAwAT...
337
+
338
+ # Mark as unread
339
+ outlook-cli email mark-read --id AAMkAGVmMDAwAT... --isRead false
340
+ ```
341
+
342
+ ---
343
+
344
+ ### `calendar` — Calendar Management
345
+
346
+ | Command | Description |
347
+ |---|---|
348
+ | `calendar list` | List upcoming events |
349
+ | `calendar create` | Create a new event |
350
+ | `calendar decline` | Decline an event invitation |
351
+ | `calendar cancel` | Cancel an event you organized |
352
+ | `calendar delete` | Delete an event |
353
+
354
+ ---
355
+
356
+ #### `calendar list` — List Upcoming Events
357
+
358
+ Lists upcoming calendar events starting from now, ordered by start time.
359
+
360
+ **Parameters:**
361
+
362
+ | Flag | Type | Default | Description |
363
+ |---|---|---|---|
364
+ | `--count` | number | `10` | Number of events to return (1–50) |
365
+
366
+ **Examples:**
367
+ ```bash
368
+ # Next 10 events (default)
369
+ outlook-cli calendar list
370
+
371
+ # Next 30 events
372
+ outlook-cli calendar list --count 30
373
+
374
+ # JSON output
375
+ outlook-cli calendar list --count 5 --json
376
+ ```
377
+
378
+ **Output shows:** Event ID, subject, location, start time, end time, organizer, attendees list.
379
+
380
+ **Tip:** Copy the Event ID from the output to use with `decline`, `cancel`, or `delete` commands.
381
+
382
+ ---
383
+
384
+ #### `calendar create` — Create Calendar Event
385
+
386
+ Creates a new event on the calendar. Optionally invites attendees.
387
+
388
+ **Parameters:**
389
+
390
+ | Flag | Type | Required | Description |
391
+ |---|---|---|---|
392
+ | `--subject` | string | yes | Event title |
393
+ | `--start` | string | yes | Start datetime: `YYYY-MM-DDTHH:MM:SS` |
394
+ | `--end` | string | yes | End datetime: `YYYY-MM-DDTHH:MM:SS` |
395
+ | `--attendees` | string | no | Comma-separated attendee email addresses |
396
+ | `--body` | string | no | Event description/agenda |
397
+
398
+ **Examples:**
399
+ ```bash
400
+ # Simple personal event
401
+ outlook-cli calendar create \
402
+ --subject "Focus time" \
403
+ --start "2026-04-10T09:00:00" \
404
+ --end "2026-04-10T11:00:00"
405
+
406
+ # Team meeting with attendees and agenda
407
+ outlook-cli calendar create \
408
+ --subject "Q2 Planning" \
409
+ --start "2026-04-15T14:00:00" \
410
+ --end "2026-04-15T15:30:00" \
411
+ --attendees "alice@company.com,bob@company.com" \
412
+ --body "Agenda: review Q1, plan Q2 roadmap, assign owners"
413
+
414
+ # All-day event (use midnight to midnight)
415
+ outlook-cli calendar create \
416
+ --subject "Company holiday" \
417
+ --start "2026-04-25T00:00:00" \
418
+ --end "2026-04-25T23:59:00"
419
+ ```
420
+
421
+ **Notes:**
422
+ - Datetime must be in `YYYY-MM-DDTHH:MM:SS` format without timezone offset.
423
+ - The server uses Central European Standard Time by default.
424
+
425
+ ---
426
+
427
+ #### `calendar decline` — Decline Event Invitation
428
+
429
+ Declines a received event invitation, optionally with a message to the organizer.
430
+
431
+ **Parameters:**
432
+
433
+ | Flag | Type | Required | Description |
434
+ |---|---|---|---|
435
+ | `--eventId` | string | yes | Event ID from `calendar list` |
436
+ | `--comment` | string | no | Message to send to the organizer |
437
+
438
+ **Examples:**
439
+ ```bash
440
+ # Decline without a message
441
+ outlook-cli calendar decline --eventId AAMkAGVmMDAwAT...
442
+
443
+ # Decline with a reason
444
+ outlook-cli calendar decline \
445
+ --eventId AAMkAGVmMDAwAT... \
446
+ --comment "Sorry, I have a conflict. Can we reschedule to next week?"
447
+ ```
448
+
449
+ ---
450
+
451
+ #### `calendar cancel` — Cancel Your Event
452
+
453
+ Cancels an event you organized and notifies all attendees.
454
+
455
+ **Parameters:**
456
+
457
+ | Flag | Type | Required | Description |
458
+ |---|---|---|---|
459
+ | `--eventId` | string | yes | Event ID from `calendar list` |
460
+ | `--comment` | string | no | Cancellation reason sent to attendees |
461
+
462
+ **Examples:**
463
+ ```bash
464
+ # Cancel without message
465
+ outlook-cli calendar cancel --eventId AAMkAGVmMDAwAT...
466
+
467
+ # Cancel with explanation
468
+ outlook-cli calendar cancel \
469
+ --eventId AAMkAGVmMDAwAT... \
470
+ --comment "This meeting is no longer needed. Details will follow by email."
471
+ ```
472
+
473
+ **Note:** Use `cancel` (not `delete`) when you want attendees to receive a cancellation notification.
474
+
475
+ ---
476
+
477
+ #### `calendar delete` — Delete Event
478
+
479
+ Permanently removes an event from the calendar without notifying attendees.
480
+
481
+ **Parameters:**
482
+
483
+ | Flag | Type | Required | Description |
484
+ |---|---|---|---|
485
+ | `--eventId` | string | yes | Event ID from `calendar list` |
486
+
487
+ **Examples:**
488
+ ```bash
489
+ outlook-cli calendar delete --eventId AAMkAGVmMDAwAT...
490
+ ```
491
+
492
+ **Tip:** Use `cancel` instead of `delete` for meetings with attendees so they receive proper notification.
493
+
494
+ ---
495
+
496
+ ### `folder` — Mail Folder Management
497
+
498
+ | Command | Description |
499
+ |---|---|
500
+ | `folder list` | List all mail folders |
501
+ | `folder create` | Create a new folder |
502
+ | `folder move` | Move emails to another folder |
503
+
504
+ ---
505
+
506
+ #### `folder list` — List Mail Folders
507
+
508
+ Lists all mail folders in the account. Optionally shows item counts and subfolder hierarchy.
509
+
510
+ **Parameters:**
511
+
512
+ | Flag | Type | Default | Description |
513
+ |---|---|---|---|
514
+ | `--includeItemCounts` | boolean | `false` | Show total and unread message counts |
515
+ | `--includeChildren` | boolean | `false` | Show nested subfolders |
516
+
517
+ **Examples:**
518
+ ```bash
519
+ # Simple folder list
520
+ outlook-cli folder list
521
+
522
+ # With message counts
523
+ outlook-cli folder list --includeItemCounts
524
+
525
+ # Full hierarchy with counts
526
+ outlook-cli folder list --includeItemCounts --includeChildren
527
+
528
+ # JSON output for scripting
529
+ outlook-cli folder list --includeItemCounts --json
530
+ ```
531
+
532
+ **Tip:** Use this to discover custom folder names before using them in `email list`, `email search`, `folder move`, or `rule create`.
533
+
534
+ ---
535
+
536
+ #### `folder create` — Create Mail Folder
537
+
538
+ Creates a new mail folder at the root level or inside an existing folder.
539
+
540
+ **Parameters:**
541
+
542
+ | Flag | Type | Required | Default | Description |
543
+ |---|---|---|---|---|
544
+ | `--name` | string | yes | — | Name for the new folder |
545
+ | `--parentFolder` | string | no | root | Name of existing parent folder |
546
+
547
+ **Examples:**
548
+ ```bash
549
+ # Create top-level folder
550
+ outlook-cli folder create --name "Project Alpha"
551
+
552
+ # Create subfolder inside an existing folder
553
+ outlook-cli folder create --name "2026 Invoices" --parentFolder "Finance"
554
+
555
+ # Create a subfolder under inbox
556
+ outlook-cli folder create --name "Action Required" --parentFolder inbox
557
+ ```
558
+
559
+ ---
560
+
561
+ #### `folder move` — Move Emails
562
+
563
+ Moves one or more emails from one folder to another.
564
+
565
+ **Parameters:**
566
+
567
+ | Flag | Type | Required | Default | Description |
568
+ |---|---|---|---|---|
569
+ | `--emailIds` | string | yes | — | Comma-separated email ID(s) |
570
+ | `--targetFolder` | string | yes | — | Destination folder name |
571
+ | `--sourceFolder` | string | no | `inbox` | Source folder (for context) |
572
+
573
+ **Examples:**
574
+ ```bash
575
+ # Move one email to archive
576
+ outlook-cli folder move \
577
+ --emailIds AAMkAGVmMDAwAT... \
578
+ --targetFolder archive
579
+
580
+ # Move multiple emails to a custom folder
581
+ outlook-cli folder move \
582
+ --emailIds "AAMkAGVm...,BBMkAHXn...,CCMkAIYo..." \
583
+ --targetFolder "Project Alpha"
584
+
585
+ # Move from a non-inbox folder
586
+ outlook-cli folder move \
587
+ --emailIds AAMkAGVmMDAwAT... \
588
+ --sourceFolder "Junk" \
589
+ --targetFolder inbox
590
+ ```
591
+
592
+ **Output:** Reports success count, failure count, and error details for any failed moves (up to 3 error messages shown).
593
+
594
+ ---
595
+
596
+ ### `rule` — Inbox Rules
597
+
598
+ | Command | Description |
599
+ |---|---|
600
+ | `rule list` | List all inbox rules |
601
+ | `rule create` | Create a new inbox rule |
602
+ | `rule sequence` | Change a rule's execution order |
603
+
604
+ ---
605
+
606
+ #### `rule list` — List Inbox Rules
607
+
608
+ Lists all inbox rules sorted by sequence (execution order — lower runs first).
609
+
610
+ **Parameters:**
611
+
612
+ | Flag | Type | Default | Description |
613
+ |---|---|---|---|
614
+ | `--includeDetails` | boolean | `false` | Show full conditions and actions |
615
+
616
+ **Examples:**
617
+ ```bash
618
+ # Just rule names and enabled status
619
+ outlook-cli rule list
620
+
621
+ # Full detail — conditions and actions for each rule
622
+ outlook-cli rule list --includeDetails
623
+
624
+ # JSON for scripting
625
+ outlook-cli rule list --includeDetails --json
626
+ ```
627
+
628
+ **Output (with details) shows:**
629
+ - Conditions: fromAddresses, subjectContains, bodyContains, hasAttachment, importance
630
+ - Actions: moveToFolder, copyToFolder, markAsRead, markImportance, forwardTo, delete
631
+
632
+ ---
633
+
634
+ #### `rule create` — Create Inbox Rule
635
+
636
+ Creates an inbox rule that automatically processes incoming emails. Needs a name, at least one condition, and at least one action.
637
+
638
+ **Parameters:**
639
+
640
+ | Flag | Type | Required | Description |
641
+ |---|---|---|---|
642
+ | `--name` | string | yes | Rule name |
643
+ | `--fromAddresses` | string | condition | Comma-separated sender emails to match |
644
+ | `--containsSubject` | string | condition | Text that must appear in subject |
645
+ | `--hasAttachments` | boolean | condition | Match only emails with attachments |
646
+ | `--moveToFolder` | string | action | Folder name to move matching emails to |
647
+ | `--markAsRead` | boolean | action | Auto-mark matching emails as read |
648
+ | `--isEnabled` | boolean | — | Whether rule is active (default: `true`) |
649
+ | `--sequence` | number | — | Execution order (lower = first); auto-assigned if omitted |
650
+
651
+ At least one condition (`--fromAddresses`, `--containsSubject`, `--hasAttachments`) and at least one action (`--moveToFolder`, `--markAsRead`) are required.
652
+
653
+ **Examples:**
654
+ ```bash
655
+ # Auto-move emails from boss to Important folder
656
+ outlook-cli rule create \
657
+ --name "Boss emails" \
658
+ --fromAddresses boss@company.com \
659
+ --moveToFolder Important
660
+
661
+ # Auto-file newsletters and mark as read
662
+ outlook-cli rule create \
663
+ --name "Newsletter handler" \
664
+ --fromAddresses "news@service.com,digest@news.com" \
665
+ --moveToFolder Newsletters \
666
+ --markAsRead \
667
+ --sequence 10
668
+
669
+ # Rule based on subject text
670
+ outlook-cli rule create \
671
+ --name "Invoice sorter" \
672
+ --containsSubject invoice \
673
+ --hasAttachments \
674
+ --moveToFolder Finance
675
+
676
+ # Disabled rule (create but don't activate yet)
677
+ outlook-cli rule create \
678
+ --name "Temp filter" \
679
+ --fromAddresses test@example.com \
680
+ --markAsRead \
681
+ --isEnabled false
682
+ ```
683
+
684
+ **Notes:**
685
+ - The `moveToFolder` target must already exist. Create it first with `folder create`.
686
+ - If `--sequence` is not provided, the rule is placed after all existing rules.
687
+
688
+ ---
689
+
690
+ #### `rule sequence` — Change Rule Execution Order
691
+
692
+ Changes the sequence (execution order) of an existing rule. Lower sequence numbers run first.
693
+
694
+ **Parameters:**
695
+
696
+ | Flag | Type | Required | Description |
697
+ |---|---|---|---|
698
+ | `--ruleName` | string | yes | Exact name of the rule to reorder |
699
+ | `--sequence` | number | yes | New sequence number |
700
+
701
+ **Examples:**
702
+ ```bash
703
+ # Make boss email rule run first
704
+ outlook-cli rule sequence --ruleName "Boss emails" --sequence 1
705
+
706
+ # Push newsletter rule later in the order
707
+ outlook-cli rule sequence --ruleName "Newsletter handler" --sequence 500
708
+ ```
709
+
710
+ ---
711
+
712
+ ### `tools` — Tool Inspection
713
+
714
+ | Command | Description | Example |
715
+ |---|---|---|
716
+ | `tools list` | List all available MCP tools | `outlook-cli tools list` |
717
+ | `tools schema` | Show schema for a specific tool | `outlook-cli tools schema list-emails` |
718
+
719
+ **Examples:**
720
+ ```bash
721
+ # See all tools
722
+ outlook-cli tools list
723
+
724
+ # Inspect a tool's parameters
725
+ outlook-cli tools schema send-email
726
+ outlook-cli tools schema create-event
727
+ ```
728
+
729
+ ---
730
+
731
+ ### `call` — Generic Tool Invocation
732
+
733
+ Invoke any MCP tool directly by name with JSON arguments.
734
+
735
+ ```bash
736
+ outlook-cli call <tool-name> --args-json '<json>'
737
+ ```
738
+
739
+ **Examples:**
740
+ ```bash
741
+ # List emails via generic call
742
+ outlook-cli call list-emails --args-json '{"folder":"inbox","count":5}'
743
+
744
+ # Send email via generic call
745
+ outlook-cli call send-email --args-json '{"to":"user@example.com","subject":"Hi","body":"Hello"}'
746
+
747
+ # With JSON output
748
+ outlook-cli call list-events --args-json '{"count":10}' --json
749
+ ```
750
+
751
+ ---
752
+
753
+ ### `doctor` — Diagnostics
754
+
755
+ Runs a series of diagnostic checks and reports what's working and what needs fixing.
756
+
757
+ ```bash
758
+ outlook-cli doctor
759
+ ```
760
+
761
+ Checks: Node.js version, environment variables, token file presence, token validity, server connectivity.
762
+
763
+ ---
764
+
765
+ ### `update` — Update the CLI
766
+
767
+ ```bash
768
+ # Check for updates
769
+ outlook-cli update
770
+
771
+ # Run the update automatically
772
+ outlook-cli update --run
773
+ ```
774
+
775
+ Or update via npm directly:
776
+ ```bash
777
+ npm i -g outlook-cli@latest
778
+ ```
779
+
780
+ ---
781
+
782
+ ## Output Flags (All Commands)
783
+
784
+ | Flag | Description |
785
+ |---|---|
786
+ | `--json` | Output raw JSON instead of human-readable text |
787
+ | `--plain` | No colors or formatting |
788
+ | `--no-color` | Disable color only |
789
+ | `--no-animate` | Disable spinner animations |
790
+
791
+ **Examples:**
792
+ ```bash
793
+ outlook-cli auth status --json
794
+ outlook-cli email list --count 10 --json
795
+ outlook-cli calendar list --plain
796
+ ```
797
+
798
+ ---
799
+
800
+ ## Complete MCP Tool Catalog
801
+
802
+ All 19 tools are available through the shared MCP tool registry — used by Claude and other AI assistants, and also callable via `outlook-cli call <tool-name>`.
803
+
804
+ ### Authentication Tools
805
+
806
+ | Tool | What it does | Required | Optional |
807
+ |---|---|---|---|
808
+ | `about` | Returns server name, version, description | none | none |
809
+ | `authenticate` | Starts OAuth flow, returns auth URL | none | `force` (boolean) |
810
+ | `check-auth-status` | Returns current auth status | none | none |
811
+
812
+ ### Calendar Tools
813
+
814
+ | Tool | What it does | Required | Optional |
815
+ |---|---|---|---|
816
+ | `list-events` | List upcoming calendar events | none | `count` (1–50) |
817
+ | `create-event` | Create a new event | `subject`, `start`, `end` | `attendees` (array), `body` |
818
+ | `decline-event` | Decline an event invitation | `eventId` | `comment` |
819
+ | `cancel-event` | Cancel an event and notify attendees | `eventId` | `comment` |
820
+ | `delete-event` | Delete an event silently | `eventId` | none |
821
+
822
+ ### Email Tools
823
+
824
+ | Tool | What it does | Required | Optional |
825
+ |---|---|---|---|
826
+ | `list-emails` | List recent emails from a folder | none | `folder`, `count` |
827
+ | `search-emails` | Search with text and filter criteria | none | `query`, `folder`, `from`, `to`, `subject`, `hasAttachments`, `unreadOnly`, `count` |
828
+ | `read-email` | Read full content of one email | `id` | none |
829
+ | `send-email` | Send a new email | `to`, `subject`, `body` | `cc`, `bcc`, `importance`, `saveToSentItems` |
830
+ | `mark-as-read` | Mark email read or unread | `id` | `isRead` (boolean, default `true`) |
831
+
832
+ ### Folder Tools
833
+
834
+ | Tool | What it does | Required | Optional |
835
+ |---|---|---|---|
836
+ | `list-folders` | List all mail folders | none | `includeItemCounts`, `includeChildren` |
837
+ | `create-folder` | Create a new folder | `name` | `parentFolder` |
838
+ | `move-emails` | Move emails to another folder | `emailIds` (comma-separated), `targetFolder` | `sourceFolder` |
839
+
840
+ ### Rules Tools
841
+
842
+ | Tool | What it does | Required | Optional |
843
+ |---|---|---|---|
844
+ | `list-rules` | List inbox rules by execution order | none | `includeDetails` |
845
+ | `create-rule` | Create inbox rule (1 condition + 1 action minimum) | `name` + condition + action | `isEnabled`, `sequence` |
846
+ | `edit-rule-sequence` | Change rule execution order | `ruleName`, `sequence` | none |
847
+
848
+ ---
849
+
850
+ ## MCP Server Mode (for Claude and AI Assistants)
851
+
852
+ Run as a standard MCP stdio server for use with Claude Desktop or other MCP clients:
853
+
854
+ ```bash
855
+ npm run mcp-server
856
+ # or
857
+ node index.js
858
+ ```
859
+
860
+ ### Claude Desktop Configuration
861
+
862
+ Add to your Claude Desktop config file (`claude-config-sample.json` is included as a reference):
863
+
864
+ ```json
865
+ {
866
+ "mcpServers": {
867
+ "outlook": {
868
+ "command": "node",
869
+ "args": ["/path/to/outlook-mcp/index.js"],
870
+ "env": {
871
+ "OUTLOOK_CLIENT_ID": "your-client-id",
872
+ "OUTLOOK_CLIENT_SECRET": "your-client-secret"
873
+ }
874
+ }
875
+ }
876
+ }
877
+ ```
878
+
879
+ Or if installed globally:
880
+ ```json
881
+ {
882
+ "mcpServers": {
883
+ "outlook": {
884
+ "command": "outlook-cli",
885
+ "args": ["mcp-server"],
886
+ "env": {
887
+ "OUTLOOK_CLIENT_ID": "your-client-id",
888
+ "OUTLOOK_CLIENT_SECRET": "your-client-secret"
889
+ }
890
+ }
891
+ }
892
+ }
893
+ ```
894
+
895
+ ### AI Assistant Skill
896
+
897
+ A complete skill reference for AI assistants (Claude and others) is in [skill/outlook-mcp.md](skill/outlook-mcp.md). This document covers every tool, every parameter, common workflows, and examples — useful for RAG systems or as a system prompt addition.
898
+
899
+ ---
900
+
901
+ ## Token Behavior
902
+
903
+ - Tokens are stored at `~/.outlook-mcp-tokens.json` (Windows: `%USERPROFILE%\.outlook-mcp-tokens.json`)
904
+ - Tokens survive package updates and reinstalls — no need to re-authenticate after upgrading
905
+ - Access tokens auto-refresh when expired (using the refresh token)
906
+ - Force re-authentication anytime with `outlook-cli auth login --force` or `authenticate { force: true }`
907
+
908
+ ---
909
+
910
+ ## Test Mode
911
+
912
+ ```bash
913
+ USE_TEST_MODE=true outlook-cli email list
914
+ ```
915
+
916
+ With `USE_TEST_MODE=true`, all API calls use mock data — no real Microsoft account needed. Useful for development and CI testing.
917
+
918
+ ---
919
+
920
+ ## Troubleshooting
921
+
922
+ | Problem | Solution |
923
+ |---|---|
924
+ | `AADSTS7000215` error | You're using the Secret ID instead of the secret **Value** in Azure |
925
+ | Auth server won't start | Run `npx kill-port 3333` then try again |
926
+ | "Not authenticated" after token exists | Token expired with no refresh token — run `auth login` again |
927
+ | `create-rule` fails on folder | Folder doesn't exist — run `folder create` first |
928
+ | `move-emails` partial failure | Some email IDs were invalid — verify IDs with `email list` |
929
+ | Missing dependencies | Run `npm install` |
930
+
931
+ ---
932
+
933
+ ## AI Assistant Skill
934
+
935
+ The `skills/outlook-automation/` folder contains a structured skill for Claude Code, OpenAI Codex, and VS Code.
936
+
937
+ ### Install the skill
938
+
939
+ ```bash
940
+ # Claude Code — personal
941
+ uv run python tools/install_skill.py --personal
942
+
943
+ # Claude Code — project/team
944
+ uv run python tools/install_skill.py --project
945
+
946
+ # OpenAI Codex
947
+ uv run python tools/install_skill.py --codex
948
+
949
+ # Verify
950
+ uv run python tools/install_skill.py --verify --personal
951
+ ```
952
+
953
+ > **Note:** OpenAI Codex skills require the experimental feature flag. Add to `~/.codex/config.toml`:
954
+ > ```toml
955
+ > [features]
956
+ > skills = true
957
+ > ```
958
+
959
+ ### Skill structure
960
+
961
+ | File | Contents |
962
+ |---|---|
963
+ | [skills/outlook-automation/SKILL.md](skills/outlook-automation/SKILL.md) | Main skill entry — overview, behavioral rules, quick examples, install instructions |
964
+ | [skills/outlook-automation/reference/cli.md](skills/outlook-automation/reference/cli.md) | Complete CLI command reference — every command, flag, and example |
965
+ | [skills/outlook-automation/reference/json-schema.md](skills/outlook-automation/reference/json-schema.md) | JSON schemas for all 19 MCP tools |
966
+ | [skills/outlook-automation/reference/security.md](skills/outlook-automation/reference/security.md) | OAuth flow, token lifecycle, permission scopes, AI safety rules |
967
+ | [skills/outlook-automation/reference/troubleshooting.md](skills/outlook-automation/reference/troubleshooting.md) | Common errors, diagnostic checklist, step-by-step fixes |
968
+
969
+ ---
970
+
971
+ ## Documentation
972
+
973
+ | File | Contents |
974
+ |---|---|
975
+ | [docs/REFERENCE.md](docs/REFERENCE.md) | Full parameter-by-parameter API reference |
976
+ | [CLI.md](CLI.md) | CLI quick reference card |
977
+ | [QUICKSTART.md](QUICKSTART.md) | Setup walkthrough for new users |
978
+ | [docs/PROJECT-STRUCTURE.md](docs/PROJECT-STRUCTURE.md) | Codebase architecture and module overview |
979
+ | [docs/PUBLISHING.md](docs/PUBLISHING.md) | Publishing checklist for maintainers |
980
+ | [claude-config-sample.json](claude-config-sample.json) | Sample Claude Desktop MCP config |
981
+
982
+ ---
983
+
984
+ ## Scripts Reference
985
+
986
+ | Script | Command | Description |
987
+ |---|---|---|
988
+ | `npm start` | `node cli.js` | Run the CLI |
989
+ | `npm run mcp-server` | `node index.js` | Run as MCP stdio server |
990
+ | `npm run cli` | `node cli.js` | CLI alias |
991
+ | `npm run auth-server` | `node outlook-auth-server.js` | Start OAuth callback server on port 3333 |
992
+ | `npm run doctor` | `node cli.js doctor` | Run diagnostics |
993
+ | `npm run inspect` | MCP Inspector | Test MCP server interactively |
994
+ | `npm test` | Jest | Run unit tests |