cymdeveloppement / roundcube-ai
AI assistant for Roundcube: write and rewrite messages, summarize conversations, suggest quick replies and proofread before sending
Package info
github.com/CymDeveloppement/roundcube-ai
Type:roundcube-plugin
pkg:composer/cymdeveloppement/roundcube-ai
Requires
- php: >=8.0
- league/commonmark: ^2.2
- roundcube/plugin-installer: >=0.3.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-23 15:12:23 UTC
README
AI assistant for Roundcube webmail: write and rewrite messages, summarize conversations, suggest quick replies and proofread your mail before sending it.
Works with any OpenAI-compatible Chat Completions API: OpenAI, OpenRouter, Mistral, Ollama, vLLM, LocalAI...
Features
- Writing assistant in the compose screen: a free prompt or one of the predefined prompts (more formal, shorter, fix spelling, translate...), applied to the selected text or to the whole message. The answer can be edited, then inserted at the cursor or used to replace the text.
- Conversation summary from the message list (hover menu or message menu) and from the message being read. The whole thread is collected, including the replies stored in the Sent folder, which Roundcube threads never show together. Summaries are cached until a new message arrives in the thread.
- Quick replies: the AI suggests up to 4 replies suited to the last message ("accept", "ask for a delay", "decline politely"...). One click opens the reply and writes it, in the language of the conversation.
- Review before sending (optional): spelling, tone, missing subject, an attachment announced but missing, and - when replying - any figure or commitment that contradicts the exchange. Only a warning, never a block.
- Per user budget with a monthly counter, a progress bar in the settings (no amount shown to users) and a command line report for administrators.
- 12 languages for the AI answers, set globally and overridable per user.
Requirements
- Roundcube 1.6 or later, Elastic skin (only tested with 1.7.4)
- PHP 8.0 or later
league/commonmark(shipped with Roundcube 1.7) to render the answers- An API key for the AI provider of your choice
Installation
composer require cymdeveloppement/roundcube-ai
Then copy and edit the configuration file:
cp plugins/roundcube_ai/config.inc.php.dist plugins/roundcube_ai/config.inc.php
Add the plugin to your Roundcube configuration:
$config['plugins'] = ['roundcube_ai'];
Quick start with OpenRouter
$config['roundcube_ai_api_url'] = 'https://openrouter.ai/api/v1'; $config['roundcube_ai_api_key'] = 'sk-or-...'; $config['roundcube_ai_model'] = 'google/gemini-2.5-flash'; // Reasoning models are slower and their thinking tokens count in max_tokens $config['roundcube_ai_extra_params'] = ['reasoning' => ['enabled' => false]];
A summary of a 5 message conversation costs about $0.0015 with this model, a rewrite about $0.0002.
Trying it without an API key
$config['roundcube_ai_mock_response'] = 'OK';
The plugin then answers with this text and the current date, without calling any provider. Useful to check the interface, and to develop.
Configuration
The plugin uses an OpenAI-compatible Chat Completions API (OpenAI, Mistral, Ollama, vLLM...). See docs/openai-api.md for the request and response format.
Provider
| Option | Type | Default | Description |
|---|---|---|---|
roundcube_ai_api_url |
string | 'https://api.openai.com/v1' |
Base URL of the API, without /chat/completions |
roundcube_ai_api_key |
string | '' |
API key (Bearer token). Blank if not required |
roundcube_ai_model |
string | 'gpt-4o-mini' |
Model name |
Generation
| Option | Type | Default | Description |
|---|---|---|---|
roundcube_ai_temperature |
float | 0.3 |
Sampling temperature (0 to 2) |
roundcube_ai_max_tokens |
int | 1024 |
Maximum tokens per answer |
roundcube_ai_general_prompt |
string | '' |
General prompt sent first in every request (company, products, tone...) |
roundcube_ai_system_prompt |
string | see dist file | System prompt sent before every request |
roundcube_ai_language |
string | 'en' |
Global AI language, used unless the user chooses another one in Settings > AI assistant (en, fr, de, es, it, pt, nl, pl, ru, zh, ja, ar) |
roundcube_ai_summary_prompt |
string | see dist file | Prompt to summarize a conversation from the message list. The conversation and "Answer in: " are always appended |
roundcube_ai_extra_params |
array | array() |
Extra request fields for provider specific options (e.g. OpenRouter reasoning) |
roundcube_ai_suggestions |
int | 4 |
Number of quick replies suggested in the summary dialog (0: disabled) |
roundcube_ai_suggestions_prompt |
string | see dist file | Prompt asking for the quick replies, in JSON, with the summary |
roundcube_ai_reply_prompt |
string | see dist file | Prompt of the "Reply" button of the summary dialog: opens a reply and generates its text from the conversation |
roundcube_ai_prompts |
array | see dist file | Predefined prompts listed in the dialog: array('title' => ..., 'prompt' => ...) |
Review before send
| Option | Type | Default | Description |
|---|---|---|---|
roundcube_ai_review_on_send |
bool | false |
Proofread the message when the user clicks Send (warning only, never blocks) |
roundcube_ai_review_conversation |
bool | true |
When replying, send the last 3 messages of the conversation with the review (spots contradictions, about 3x the cost) |
roundcube_ai_review_prompt |
string | see dist file | Prompt of the review. {language} and {attachments} are replaced. The answer must be JSON |
Budget
| Option | Type | Default | Description |
|---|---|---|---|
roundcube_ai_budget |
float | 0 |
Monthly budget per user, in the currency of the provider (0: unlimited) |
roundcube_ai_budgets |
array | array() |
Budgets of specific users, by Roundcube login or identity email |
roundcube_ai_price_input |
float | 0 |
Price per million input tokens, when the provider does not return the cost |
roundcube_ai_price_output |
float | 0 |
Price per million output tokens, when the provider does not return the cost |
Usage is counted per calendar month in the Roundcube preferences of each user.
Users see a progress bar in Settings > AI assistant, without any amount.
Administrators get the figures with bin/usage.php.
HTTP
| Option | Type | Default | Description |
|---|---|---|---|
roundcube_ai_extra_headers |
array | array() |
Extra HTTP headers (e.g. OpenRouter HTTP-Referer, X-Title) |
roundcube_ai_timeout |
int | 60 |
Request timeout in seconds |
roundcube_ai_verify_ssl |
bool | true |
Verify the TLS certificate of the API |
roundcube_ai_debug |
bool | false |
Log full requests and responses to the roundcube_ai log (API key masked). Contains email contents |
roundcube_ai_mock_response |
string | '' |
Development mode: returned as the AI answer without calling the provider. Blank to disable |
Usage report
$ plugins/roundcube_ai/bin/usage.php
USER PERIOD REQUESTS TOKENS COST
alice@example.com 2026-09 42 38104 0.0374
TOTAL (1 users) 42 38104 0.0374
--period=YYYY-MM filters on a month, --csv writes CSV.
Privacy
The text of the emails handled by the plugin (the message being written, or the
whole conversation for a summary or a reply) is sent to the configured
provider. Check that your provider and its data region match your obligations,
and tell your users. roundcube_ai_debug also writes the email contents to the
Roundcube log: use it only to diagnose a problem.
Notes
- Only the Elastic skin is supported (the only skin shipped with Roundcube 1.7).
- On touch devices the AI action is in the message menu, the hover menu of the list being unavailable there.
- The AI answers are converted from Markdown to HTML server side, with the HTML they may contain escaped.
Credits
Maintained by Yann Challet (CymDeveloppement).
License
MIT - see LICENSE.