FieldCure MCP Outbox Server

A multi-channel messaging Model Context Protocol (MCP) server that sends messages through Slack, Telegram, Email (Gmail, Naver, Microsoft Graph API), KakaoTalk, and Discord. Built with C# and the official MCP C# SDK.
Features
- Multiple messaging channels β Slack, Telegram, Email (Gmail, Naver, Microsoft Graph API), KakaoTalk, Discord
- 4 MCP tools β
list_channels, add_channel, send_message, remove_channel
- Cross-platform credential flow β runtime secrets can come from env vars or MCP elicitation; OAuth tokens are stored separately for refresh lifecycle
- CLI channel setup β interactive console for browser/OAuth flows where applicable
- SMTP presets β Gmail, Naver with one-command setup
- Microsoft Graph API β OAuth 2.0 browser flow for Outlook / M365 email with automatic token refresh
- KakaoTalk OAuth β localhost callback flow with automatic token refresh
- Telegram Client API β send to Saved Messages via WTelegramClient
- Stdio transport β standard MCP subprocess model via JSON-RPC over stdin/stdout
Why Outbox?
Existing MCP servers are channel-specific β one for Slack, another for Gmail, yet another for Telegram. Each requires separate installation, configuration, and the LLM must know which tool to call for each channel.
Outbox takes a different approach:
- One tool, multiple channels β
send_message abstracts away channel differences. The LLM doesn't need to know Slack API vs SMTP vs Kakao REST.
- Credential isolation β OAuth refresh tokens live in
tokens.json with current-user-only file permissions; MCP tool flows can resolve secrets at runtime via env vars or elicitation.
- Single install β
dotnet tool install -g gives you 4 channels. No need to install and configure separate servers per channel.
- KakaoTalk support β Currently the only MCP server with KakaoTalk messaging, essential for Korean users.
Installation
dotnet tool install -g FieldCure.Mcp.Outbox
After installation, the fieldcure-mcp-outbox command is available globally.
From source
git clone https://github.com/fieldcure/fieldcure-mcp-outbox.git
cd fieldcure-mcp-outbox
dotnet build
Requirements
Configuration
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"outbox": {
"command": "fieldcure-mcp-outbox"
}
}
}
VS Code (Copilot)
Add to .vscode/mcp.json:
{
"servers": {
"outbox": {
"command": "fieldcure-mcp-outbox"
}
}
}
{
"mcpServers": {
"outbox": {
"command": "dotnet",
"args": [
"run",
"--project", "C:\\path\\to\\fieldcure-mcp-outbox\\src\\FieldCure.Mcp.Outbox"
]
}
}
}
| Tool | Description | Confirmation |
|---|
list_channels | List all configured messaging channels | β |
add_channel | Add a new channel (MCP elicitation for all channel types; Microsoft/KakaoTalk require a local browser on the MCP host) | β |
send_message | Send a message through a configured channel | Required |
remove_channel | Remove a channel and its stored credentials | Required |
Channels
OAuth tokens for Microsoft/KakaoTalk are stored in tokens.json so the server can refresh them across runs (current-user-only file permissions β Windows ACL / Unix 0600).
Static secrets (Slack bot tokens, Discord webhook URLs, SMTP passwords, etc.) resolve at send time in this order: in-memory cache β env var OUTBOX_{CHANNEL_ID}_{FIELD} β plaintext in channels.json β MCP elicitation. The CLI add_channel flow writes directly into channels.json for a zero-configuration local experience. This is an intentional local-trust choice with the same same-user boundary as tokens.json, documented in ADR-001 Principle 2. For shared hosts, CI, or headless deployments, set the env vars explicitly and leave channels.json secret fields empty.
| Channel | Protocol | Setup |
|---|
| Slack | Web API (chat.postMessage) | Guide |
| Telegram | Client API (WTelegramClient) | Guide |
| Gmail | SMTP | Guide |
| Naver | SMTP | Guide |
| Microsoft | Graph API (/me/sendMail) | Guide |
| KakaoTalk | Kakao REST API | Guide |
| Discord | Webhook API | Guide |
| Custom SMTP | User-defined | Guide |
Static Secret Environment Variables
When a channel requires a static secret at send time, Outbox looks for an environment variable named:
OUTBOX_<CHANNEL_ID>_<FIELD>
Examples:
OUTBOX_MICROSOFT_1_CLIENT_SECRET
OUTBOX_KAKAOTALK_1_API_KEY
OUTBOX_KAKAOTALK_1_CLIENT_SECRET
OUTBOX_SMTP_GMAIL_1_PASSWORD
If the variable is unset and the MCP client supports elicitation, Outbox prompts for it interactively and caches it for the current session.
CLI Commands
fieldcure-mcp-outbox
fieldcure-mcp-outbox add slack
fieldcure-mcp-outbox add telegram
fieldcure-mcp-outbox add gmail
fieldcure-mcp-outbox add naver
fieldcure-mcp-outbox add smtp
fieldcure-mcp-outbox add microsoft
fieldcure-mcp-outbox add kakaotalk
fieldcure-mcp-outbox add discord
fieldcure-mcp-outbox list
fieldcure-mcp-outbox remove <id>
Data Storage
| Data | Location |
|---|
| Channel metadata | %LOCALAPPDATA%\FieldCure\Mcp.Outbox\channels.json |
| OAuth tokens | %LOCALAPPDATA%\FieldCure\Mcp.Outbox\tokens.json |
| Telegram sessions | %LOCALAPPDATA%\FieldCure\Mcp.Outbox\sessions\ |
tokens.json is stored in plain JSON and protected by filesystem permissions:
- Windows: ACL restricted to the current user
- Linux/macOS: mode
0600
This protects against other local users on the same machine, but not against compromise of the same OS user account.
Project Structure
src/FieldCure.Mcp.Outbox/
βββ Program.cs # Entry point: MCP server vs CLI branching
βββ Channels/
β βββ IChannel.cs # Channel interface + SendRequest/SendResult
β βββ ChannelFactory.cs # Channel instantiation by type
β βββ SlackChannel.cs # Slack Web API
β βββ TelegramChannel.cs # WTelegramClient
β βββ SmtpChannel.cs # MailKit SMTP
β βββ MicrosoftChannel.cs # Microsoft Graph API
β βββ KakaoTalkChannel.cs # Kakao REST API
β βββ DiscordChannel.cs # Discord Webhook API
βββ Tools/
β βββ ListChannelsTool.cs # list_channels
β βββ AddChannelTool.cs # add_channel (elicitation + browser OAuth for Kakao/Microsoft)
β βββ RemoveChannelTool.cs # remove_channel
β βββ SendMessageTool.cs # send_message
βββ Interaction/
β βββ IElicitGate.cs # Minimal MCP elicitation surface for tests
β βββ McpServerElicitGate.cs # Production adapter around McpServer
βββ OAuth/
β βββ BrowserOAuthFlow.cs # Localhost callback + Process.Start + elicit race (MCP and CLI entry points)
βββ Credentials/
β βββ OutboxSecretResolver.cs # cache β env β channels.json β elicitation
βββ Setup/
β βββ SetupRunner.cs # CLI router (diagnostic path)
β βββ ConsoleHelper.cs # Masked input, prompts
β βββ SlackSetup.cs
β βββ TelegramSetup.cs
β βββ SmtpSetup.cs
β βββ MicrosoftSetup.cs
β βββ KakaoTalkSetup.cs
β βββ DiscordSetup.cs
βββ Configuration/
βββ ChannelStore.cs # channels.json persistence (metadata + static-secret fallback)
βββ OAuthTokenStore.cs # tokens.json persistence (OAuth access/refresh, user-only file perms)
βββ SmtpPresets.cs # SMTP preset definitions
Development
dotnet build
dotnet test
dotnet pack src/FieldCure.Mcp.Outbox -c Release
See Also
Part of the AssistStudio ecosystem.
License
MIT