|
|
||
|---|---|---|
| .github/workflows | ||
| assets | ||
| extensions | ||
| scripts | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| CHANGELOG.md | ||
| LICENSE | ||
| outlook.config.example.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
pi-agent-outlook-tool
Pi package that adds Outlook email tools powered by Microsoft Graph and OAuth device-code login. Supports multiple accounts (e.g. work + personal) and shared mailboxes (e.g. no-reply@iflex.es) accessed through an account that has been granted Full Access.
Install
Install from npm once published:
pi install npm:pi-agent-outlook-tool
Install directly from Git:
pi install git:https://git.otmatas.com/otmatas/PI-Outlook.git
Or test without installing permanently:
pi -e git:https://git.otmatas.com/otmatas/PI-Outlook.git
Local development install from this folder:
npm install
pi install ./
Local development test:
npm install
npm run typecheck
npm test
npm pack --dry-run
pi -e ./
Azure OAuth setup
Create an Azure App Registration for a public client:
- Azure Portal → App registrations → New registration.
- Supported account types: choose your needs (single tenant or multi-tenant/personal).
- Authentication → enable Allow public client flows.
- API permissions → Microsoft Graph delegated permissions:
User.ReadMail.ReadMail.Read.Shared— required to read shared mailboxesoffline_access
- Copy the Application (client) ID into the Pi Outlook config.
Configuration
On install/startup the package creates two files:
~/.pi/agent/pi-outlook/config.json — global app settings (no secrets):
{
"clientId": "YOUR_AZURE_PUBLIC_CLIENT_APP_ID",
"tenant": "common",
"scopes": ["offline_access", "User.Read", "Mail.Read", "Mail.Read.Shared"],
"maxBodyChars": 12000,
"maxAttachmentBytes": 5000000
}
~/.pi/agent/pi-outlook/accounts.json — per-user accounts and tokens. This file contains OAuth refresh tokens and is created with restrictive file permissions where the OS supports it:
{
"defaultAccount": "it@iflex.es",
"accounts": {
"it@iflex.es": {
"displayName": "Work",
"tenant": "organizations",
"tokens": { "...": "filled in by /outlook-login" },
"sharedMailboxes": ["no-reply@iflex.es", "support@iflex.es"]
}
}
}
Only these two files are used in this development version. Custom paths, project-local config files, package-local config files, legacy paths, migrations, and environment overrides are not supported.
Multiple accounts
Run /outlook-login once per Microsoft account you want to connect. The account is keyed by the UPN discovered via Graph, so re-running with the same account refreshes its tokens, and re-running with a different account adds it alongside.
/outlook-login # work account → it@iflex.es
/outlook-login consumers # personal MSA → me@outlook.com (tenant override)
Other account commands:
/outlook-accounts— list configured accounts, default flag, and shared mailboxes./outlook-status— same, but also pings/mefor each account and warns ifMail.Read.Sharedis missing./outlook-set-default <accountUpn>— choose which account is used when tools don't specify one./outlook-logout [accountUpn]— remove stored tokens for one account (default: the default account)./outlook-remove-account <accountUpn>— remove the account entirely from the config.
Shared mailboxes
A shared mailbox (no license, e.g. no-reply@iflex.es) is accessed via Microsoft Graph at /users/{shared-upn}/messages using the same access token as a user who has Full Access to it. Two requirements:
- Exchange-side: an admin must grant the owning account Full Access on the shared mailbox (Exchange admin center → Recipients → Mailboxes → shared mailbox → Manage mailbox delegation → Read and manage). Graph permission alone is not enough.
- OAuth-side: the account's tokens must include the
Mail.Read.Sharedscope. The default scopes include it, but accounts that logged in before the scope was added must re-run/outlook-loginto upgrade.
Register a shared mailbox under its owning account:
/outlook-add-shared it@iflex.es no-reply@iflex.es
/outlook-add-shared it@iflex.es support@iflex.es
/outlook-remove-shared it@iflex.es support@iflex.es
Then any mail tool can target it with the mailbox parameter:
List the last 10 messages in no-reply@iflex.es
Login
/outlook-login
Pi will show a Microsoft device-code URL and code. Complete the browser login; refresh tokens are stored under the account's UPN in the active config file.
Tools
Tool results are returned as compact Markdown. Email HTML bodies are converted to Markdown and raw Microsoft Graph fields such as webLink, raw HTML body, and large unused metadata are not returned to reduce token usage. outlook_list_mail returns short refs like m1, m2; use those refs with outlook_read_mail and outlook_attachments instead of the long Graph message IDs. Refs remember which account/mailbox they came from.
Every tool accepts two optional routing parameters:
account— UPN/email of the account to use. Defaults todefaultAccount.mailbox— UPN of a shared mailbox to read instead of the account's own mailbox. Must be registered under that account via/outlook-add-sharedfirst.
Tools:
outlook_list_mailqueryoptional Graph mail search string.folderoptional:inbox,sent,drafts,archive,junk,deleted, or folder id.topdefault 10, max 50.unreadOnlyoptional boolean.
outlook_read_mailmessageIdshort ref fromoutlook_list_mailsuch asm1, or a full Graph message id (then passaccount/mailbox).maxBodyCharsoptional.
outlook_attachmentsmessageIdshort ref fromoutlook_list_mailsuch asm1, or a full Graph message id.attachmentIdoptional; omit to list attachments.includeContentoptional; when true includes base64contentBytesin structured details only if the attachment is undermaxAttachmentBytes.
outlook_save_attachmentmessageIdshort ref or full Graph message id.attachmentIdrequired.outputPathoptional; defaults to the attachment filename in the current working directory.- Saves content to disk instead of returning base64 to the model.
Example prompts
Busca a Outlook els últims correus de Microsoft i resumeix els assumptes.
Llegeix l'últim correu no llegit de la inbox de no-reply@iflex.es.
Llista els correus no llegits del meu compte personal.
Migration from single-account config
The old single-account shape (top-level tokens) is automatically migrated into accounts["__legacy__"] on first read. Run /outlook-login once to re-key the entry under your real UPN and pick up the new Mail.Read.Shared scope.