Atlas / MCP servers / metaneutrons / eule-mcp

eule-mcpBLOCK

mcp/metaneutrons/eule-mcp

MCP server for office work with mail & calendar (MS365, iCloud, Gmail, IMAP)

Verdict
BLOCK
Grade
D
Trust score
64 /100
Exposed tools
63 42r · 14w · 7d
Transport
stdio
License
NOASSERTION
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

MCP server for an office assistant — E-Mail/Calendar integration, tasks & resource planning

[!WARNING] This project is under active development. Things will break, APIs will change, and features may be incomplete until v1.0. Use at your own risk — and feel free to contribute! Versioning follows that: while the major version is 0, a breaking change bumps the minor (0.3.0 → 0.4.0), it does not promote the project to 1.0.0. Reaching 1.0 will be a deliberate decision, not a side effect of a BREAKING CHANGE footer.

Why "Eule"?

Eule is the German word for owl — a symbol of wisdom, sharp vision, and the ability to see clearly in the dark. Like an owl surveying its territory, Eule gives your AI assistant a clear view across your entire office landscape: emails, calendars, tasks, and contacts — all through a single, unified interface.

Concept

Eule is a Model Context Protocol (MCP) server that turns any MCP-compatible AI assistant into a full office agent. Instead of switching between Outlook, task managers, and calendars, your AI assistant connects to all of

Read from source at commit ddb1ad836cc6OBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code
claude mcp add eule-mcp -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "eule-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ]
    }
  }
}
03

Exposed tools (63)

42 read · 14 write · 7 destructive. Blast radius: 7 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
account_addwrite
account_listread
account_removedestructive
auth_accountsread
auth_loginread
auth_logoutread
auth_proberead
auth_statusread
calendar_calendarsread
calendar_createwrite
calendar_deletedestructive
calendar_listread
calendar_todayread
calendar_updatewrite
chat_listread
chat_readread
chat_sendwrite
config_getread
config_set_oauthwrite
connector_capabilitiesread
connector_configureread
contact_addwrite
contact_listread
contact_searchread
credential_rotateread
credential_statusread
doc_bulkread
doc_downloadread
doc_listread
doc_readread
doc_searchread
doc_tagread
doc_uploadwrite
file_downloadread
file_listread
file_readread
file_searchread
file_uploadwrite
google_oauth_configureread
google_oauth_removedestructive
m365_password_configureread
m365_password_removedestructive
mail_attachment_getread
mail_bulk_updatewrite
mail_draftread
mail_listread
mail_readread
mail_searchread
mail_sendwrite
mail_send_draftwrite
mail_updatewrite
role_listread
role_removedestructive
role_upsertread
task_addwrite
task_completeread
task_deletedestructive
task_listread
task_listsread
task_searchread
task_updatewrite
totp_configureread
totp_removedestructive
04

Trust audit

BLOCKgrade D · trust 64/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (6 observation(s))
Network
declared (5 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (25)

HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/config/config-manager.ts:355
const raw = yaml.load(readFileSync(CONFIG_PATH, "utf-8"));
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/index.ts:129
console.log(`  ${account}: tier ${token.tier}${expired}`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/index.ts:253
console.log(`\n✅ Success! ${token.account} (tier ${token.tier})`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/index.ts:254
console.log(`   Expires: ${new Date(token.expiresAt).toLocaleString()}`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/index.ts:293
console.log(`\n✅ Success! ${token.account} (tier ${token.tier})`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
src/cli/index.ts:294
console.log(`   Expires: ${new Date(token.expiresAt).toLocaleString()}`);
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
account_remove, calendar_delete, google_oauth_remove, m365_password_remove, role_remove, task_delete, totp_remove
Why it matters. 7 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.gitleaks.toml
.gitleaks.toml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.release-please-manifest.json
.release-please-manifest.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
test/config-example.test.ts:13
const raw = yaml.load(readFileSync("config.example.yaml", "utf-8"));
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
test/outgoing-attachments.test.ts:43
expect(() => resolveAttachmentPaths([join(homedir(), ".ssh", "id_rsa")])).toThrow(
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
test/path-sandbox.test.ts:146
expect(() => secureReadPath("~/.ssh/id_rsa")).toThrow(/Access denied/);
Why it matters. touches a credential store
LOWFilesystem / path · fs.credential_store · CWE-22, CWE-59
test/path-sandbox.test.ts:148
expect(() => secureReadPath("~/Downloads/../.ssh/id_rsa")).toThrow(/Access denied/);
Why it matters. touches a credential store
LOWFilesystem / path · fs.system_paths · CWE-22, CWE-59
test/outgoing-attachments.test.ts:42
expect(() => resolveAttachmentPaths(["/etc/passwd"])).toThrow(/Access denied/);
LOWFilesystem / path · fs.system_paths · CWE-22, CWE-59
test/path-sandbox.test.ts:147
expect(() => secureReadPath("/etc/passwd")).toThrow(/Access denied/);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
helper/src/credential.rs:126
assert!(validate_reference("connector/../../escape").is_err());
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
helper/src/prompt.rs:58
let logo = include_str!("../../assets/logo.svg");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/providers/caldav/caldav-calendar.ts:8
} from "../../types/index.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/providers/caldav/caldav-calendar.ts:9
import { assertSecureUrl, escapeICalText, unescapeICalText } from "../../utils/security.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/providers/caldav/caldav-tasks.ts:9
} from "../../types/index.js";
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
test/outgoing-attachments.test.ts:38
it("refuses paths outside the sandbox (secret exfiltration guard)", () => {
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
test/path-sandbox.test.ts:140
it("blocks reading secrets from ~/.eule (exfiltration guard)", () => {
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/security.test.ts:79
expect(assertSecureUrl("http://127.0.0.1:8080/")).toBe("http://127.0.0.1:8080/");
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/security.test.ts:92
await expect(fetchWithTimeout("http://127.0.0.1:9/never", {}, 1)).rejects.toThrow();
LOWPrivilege escalation / persistence · priv.escalate · CWE-269, CWE-250
.github/workflows/ci.yml:62
sudo apt-get update
Why it matters. asks for elevated privileges

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha ddb1ad836cc6full audit observations/trust-audit/mcp-server/metaneutrons__eule-mcp.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11ddb1ad836cc6BLOCKD64first audit
06

Questions

What is the eule-mcp MCP server?

MCP server for office work with mail & calendar (MS365, iCloud, Gmail, IMAP)

What tools does eule-mcp expose?

63 in total: 42 read-only, 14 that write, and 7 that can delete or overwrite (account_remove, calendar_delete, google_oauth_remove, m365_password_remove, role_remove). Every one is listed on this page with its risk.

Is eule-mcp safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (64/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 7 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does eule-mcp need?

No credential environment variables were found in its source, so it appears to need none.

How does eule-mcp run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as eule-mcp at 0.8.0.

How current is this page?

The grade is for one exact copy of the source (ddb1ad836cc6), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement