This project is a local MCP server for working with messages from an Microsoft Outlook PST archive.
Outlook PST MCP Server
This project is a local MCP server for working with messages from an Outlook PST archive.
The server treats the source PST file as read-only input. It imports messages through readpst, stores editable mailbox state in a workspace, exposes CRUD tools over MCP, and exports the final mailbox state as an EML folder tree with a manifest.json file.
Repository: https://github.com/EvilFreelancer/outlook-pst-mcp
What It Does
- Imports Outlook PST content through
readpstfromlibpst. - Indexes folders and messages in SQLite.
- Stores editable message payloads as canonical
.emlfiles. - Exposes MCP tools for folder browsing, message search, reading, creating, updating, deleting, moving, and exporting messages.
- Exports edited state as an EML directory tree that can be imported by mail software.
What It Does Not Do
- It does not modify the original PST file.
- It does not write a new PST file.
- It does not connect to Outlook, Exchange, IMAP, Microsoft Graph, or any remote mailbox.
- It does not provide a web UI.
Requirements
- Go 1.24 or newer.
- GCC and CGO support for the SQLite driver.
readpstinstalled and available onPATHfor real PST imports.
On Debian or Ubuntu, readpst is usually provided by pst-utils:
sudo apt install pst-utils
Build
Clone the repository and enter the project directory:
git clone https://github.com/EvilFreelancer/outlook-pst-mcp.git
cd outlook-pst-mcp
make build
The command creates bin/outlook-pst-mcp.
Install
Install to ~/.local/bin:
make install
Without parameters, make install installs:
~/.local/bin/outlook-pst-mcp
Install to another prefix:
make install PREFIX=/usr/local
Install to an exact binary directory:
make install BINDIR=/custom/bin
Install a Release Binary
Prebuilt binaries are published in GitHub Releases when a SemVer tag such as
1.2.3 is released.
Linux:
curl -fsSL https://raw.githubusercontent.com/EvilFreelancer/outlook-pst-mcp/main/install.sh | bash
Windows PowerShell:
irm https://raw.githubusercontent.com/EvilFreelancer/outlook-pst-mcp/main/install.ps1 | iex
Install a specific release:
./install.sh --version 0.1.1
The scripts download the latest release from GitHub Releases, install the binary
to ~/.local/bin/outlook-pst-mcp on Linux or %LOCALAPPDATA%\Programs\outlook-pst-mcp\outlook-pst-mcp.exe on Windows, and print an MCP client configuration with a stable workspace path.
Release assets use these names:
outlook-pst-mcp_<version>_<os>_<arch>.tar.gz
outlook-pst-mcp_<version>_<os>_<arch>.zip
Install readpst before importing real PST files. The install scripts install
only the MCP server binary.
On Debian or Ubuntu, readpst is provided by pst-utils:
sudo apt install pst-utils
On Windows, pst-utils is not an apt package. Put a Windows build of
readpst.exe on PATH, or run the Linux binary in WSL and install pst-utils
there.
Run
Run the MCP server over stdio:
make run
Without -workspace, data is stored under .outlook-pst-mcp_data in the process current working directory (the project root when Cursor starts the MCP server from this repo).
The workspace stores:
.outlook-pst-mcp_data/
mailbox.db
extracted/
messages/
export/
Import a PST
Use the import_pst MCP tool from a connected client, or the CLI subcommand:
./bin/outlook-pst-mcp import -pst /absolute/path/to/backup.pst
Both write into the same workspace database (default .outlook-pst-mcp_data).
MCP Client Configuration
Example client configuration:
{
"mcpServers": {
"outlook-pst": {
"command": "/home/USER/.local/bin/outlook-pst-mcp",
"args": ["-workspace", "/home/USER/.local/share/outlook-pst-mcp"]
}
}
}
Replace USER with the local account name, or use any other absolute binary and
workspace paths accepted by the MCP client. The workspace stores the SQLite
database, extracted EML files, edited messages, and exports.
After adding the server to the MCP client, import a PST with the import_pst
tool:
{
"pst_path": "/absolute/path/to/backup.pst"
}
The source PST is treated as read-only input. After import, use list_folders,
list_messages, get_message, and the other MCP tools below.
Cursor uses newline-delimited JSON for stdio MCP servers. The server also
accepts Content-Length framed messages for compatibility with other clients
that use header-framed stdio. After changing server code, run make build before
reloading the MCP server in Cursor so the configured binary is up to date.
Tools
import_pst
Imports a PST file into the workspace. Use this when the server has no mailbox data yet.
{
"pst_path": "/absolute/path/to/backup.pst"
}
Response fields: workspace, folder_count, message_count, skipped_count.
list_folders
Lists indexed mailbox folders.
{}
list_messages
Lists message summaries.
{
"folder_id": "fld_...",
"query": "invoice",
"limit": 50,
"offset": 0,
"include_deleted": false
}
get_message
Reads one message.
{
"message_id": "msg_...",
"include_body": true,
"include_headers": false
}
create_message
Creates a new message in a folder.
{
"folder_id": "fld_...",
"subject": "New message",
"from": "sender@example.com",
"to": ["recipient@example.com"],
"cc": [],
"body_text": "Message body",
"headers": {
"X-Source": "outlook-pst-mcp"
}
}
update_message
Updates message fields.
{
"message_id": "msg_...",
"subject": "Updated subject",
"body_text": "Updated body"
}
delete_message
Soft-deletes a message. The EML payload remains on disk, but the message is skipped during export by default.
{
"message_id": "msg_..."
}
move_message
Moves a message to another folder.
{
"message_id": "msg_...",
"folder_id": "fld_..."
}
export_eml
Exports the current workspace state as an EML folder tree.
{
"output_dir": "/absolute/path/to/export",
"include_deleted": false
}
Test
make test
make test uses GOCACHE=/tmp/outlook-pst-mcp-go-build by default so tests work in restricted environments.
Make Targets
make help
make fmt
make check
make test
make build
make install
make run
make clean
make check runs go vet ./....
Release Flow
Pull requests run GitHub Actions verification with:
make check
make test
make build
After changes are merged to main, GitHub Actions bumps the latest patch SemVer
tag, pushes the new tag, and calls the release binary workflow. The release
workflow builds the archives, writes SHA256SUMS, and uploads everything to the
matching GitHub Release.
Documentation
Project documentation lives in docs/:
docs/product.md: product goal, constraints, non-goals, and workflow.docs/architecture.md: packages, runtime flow, data model, and boundaries.docs/file-workflow.md: PST,readpst, EML, SQLite, and export file handling.docs/mcp.md: MCP transport, tools, arguments, responses, and errors.docs/development.md: workflow, Makefile targets, test, build, and install behavior.docs/implementation-plan.md: implementation plan and completed task map.
Development Notes
- Project-facing text is written in English.
- Documentation lives in
docs/. - Tests are written before implementation code.
- The source PST file is always treated as read-only input.
- Source packages under
internal/must not be hidden by local runtime ignore rules. - Use
make check,make test, andmake buildbefore considering changes complete.