Skip to content

Releases: hculap/emodul

v0.1.10 — auto-downsample get_temperature_history

21 May 12:04
e8d7845

Choose a tag to compare

What's new

`get_temperature_history` MCP tool now auto-downsamples to at most 600 points per zone via bucket-averaging. Unblocks 7-day / month charts in Claude Desktop without hitting the client's ~1 MB tool-result cap.

Empirical (8 zones × 10080 per-minute samples, 7-day window)

Bytes MB Total points
Before 2,733,887 2.61 80,640
After 161,612 0.154 4,744

17× smaller, comfortably under 1 MB and under the 25k-token soft-warn threshold. Day fetches stay ~45 KB.

Why not raise the cap

The ~1 MB cap is enforced client-side in Anthropic apps (`MAX_MCP_OUTPUT_TOKENS`, default ~25k tokens). No FastMCP / MCP SDK server-side setting exists for this. Downsampling at the server is the canonical mitigation per Anthropic docs.

Behavior

  • Tool signature unchanged
  • Series shape unchanged (`[{x, y}, ...]`)
  • New `downsample` key in response with per-zone `original` and `returned` sample counts so the agent can disclose precision to the user
  • Server `instructions` updated with a one-line note

Upgrade

```bash
pipx upgrade emodul

restart Claude Desktop

ask: "Pull last 7 days of temperature for each zone and create an interactive line chart"

```

Now the chart artifact gets the full week. Previously the agent had to fall back to 24h.

Full diff

v0.1.9...v0.1.10

v0.1.9 — keychain diagnostics + CLI logout symmetry

19 May 14:27
105befc

Choose a tag to compare

What's new

`logout` (both MCP tool and `emodul auth logout` CLI) now returns a precise `keychain_status` so you can tell apart "no entry to remove" from "delete failed" from "config has no email to look up." Each error case includes a manual recovery hint.

`emodul auth logout --clear-keychain` is also new — does in one step what previously required `auth logout && auth forget-password`.

Status codes

  • `skipped` — clear_keychain was False
  • `no_email` — requested but config has no email
  • `not_found` — email valid, no keychain entry (often: already removed)
  • `deleted` — entry existed and was removed
  • `error` — delete_password raised

Upgrade

```bash
pipx upgrade emodul
```

Full diff

v0.1.8...v0.1.9

v0.1.8 — logout MCP tool

19 May 14:15
5c06be6

Choose a tag to compare

What's new

New MCP tool `logout(clear_keychain=False)`:

  • Drops `token` + `user_id` from `~/.config/emodul/config.json`
  • Optionally removes the keychain password (auto-refresh disabled until next login)
  • `destructiveHint=true` → client confirms before invoking

The CLI already had `emodul auth logout` and `emodul auth forget-password`; this just exposes them as a single MCP tool so chat-client users can ask "log me out" and the agent has somewhere to call.

Tool count: 16 → 17 (9 read + 5 write + 3 auth).

Upgrade

```bash
pipx upgrade emodul

restart Claude Desktop

```

Full diff

v0.1.7...v0.1.8

v0.1.7 — browser login form fix

19 May 14:08
3ff0531

Choose a tag to compare

Hotfix

The HTML login form (`emodul auth login --browser` and MCP `login_browser`) was sending `multipart/form-data` but the local Python server only parsed `application/x-www-form-urlencoded` — so every submit came in with empty email + password and the server returned 400 "Email and password are required".

Broken in 0.1.2 through 0.1.6. Hidden because demos used the CLI terminal path, and the MCP `login_browser` tool timed out before users could click Submit. Surfaced as soon as v0.1.6 made login_browser non-blocking and someone actually completed the form.

Fix

JS submit handler now wraps FormData in URLSearchParams so fetch sends the right Content-Type:

```js
const params = new URLSearchParams(new FormData(form));
fetch('/submit?...', { method: 'POST', body: params });
```

Verified end-to-end: server now parses fields correctly and forwards to the eModul API.

Upgrade

Anyone trying browser login on 0.1.6 must upgrade:

```bash
pipx upgrade emodul
```

Full diff

v0.1.6...v0.1.7

v0.1.6 — non-blocking login_browser

19 May 13:53
cf1abaf

Choose a tag to compare

The fix

`login_browser` MCP tool now defaults to `wait=False` — returns the login URL in <1s instead of blocking 5min. The local server keeps running in a background thread; agent shows URL to user, user submits credentials, server persists the token + keychain entry in the background. Agent then polls `whoami` to detect completion.

This was previously broken in Claude Desktop / Cursor chat / Continue / Cline / Zed — clients without `resetTimeoutOnProgress` killed the tool call at the ~60s ceiling, before the user could finish typing the password, so the token never came back through that call.

Compatibility

  • `login_browser(wait=False)` — new default for chat clients
  • `login_browser(wait=True)` — opt-in for Claude Code / Codex CLI agents that DO support long-running tools
  • `emodul auth login --browser` (terminal CLI) — unchanged

Refactor

`web_login_flow` decomposed into `start_login_server` + `wait_for_login` + `cancel_login`. Existing `web_login_flow` API preserved as a composition wrapper.

Upgrade

```bash
pipx upgrade emodul

restart Claude Desktop, ask agent to log in — flow takes seconds, not minutes.

```

Full diff

v0.1.5...v0.1.6

v0.1.5 — MCP server instructions

19 May 13:44
4e25a12

Choose a tag to compare

What's new

Expanded the MCP server's `instructions` field (returned in `InitializeResult`) from 1 sentence to 365 words covering when-to-use triggers (English + Polish), 16-tool roster, recommended workflow, conventions, result envelope semantics, and safety rules.

Per the MCP spec, clients inject `instructions` into the LLM's system prompt on every turn — this is the standard mechanism for delivering skill-like persistent context to clients like Claude Desktop, Cursor chat, Continue, Cline, Zed, where filesystem skill discovery doesn't apply.

Why this matters

`~/.claude/skills/` is read by Claude Code only — Claude Desktop uses a separate UI-upload mechanism for its built-in Skills feature. Before this release, the SKILL_MCP.md file we drop during `emodul install claude-desktop` was invisible to Claude Desktop. Now the skill content travels with the MCP server itself.

Upgrade

```bash
pipx upgrade emodul

restart Claude Desktop (⌘+Q + reopen)

```

The new instructions are visible in Claude Desktop's logged system prompt under the `## emodul` heading.

Full diff

v0.1.4...v0.1.5

v0.1.4 — emodul install command

19 May 13:27
6378941

Choose a tag to compare

Highlights

A single command now wires emodul into Claude Code AND Claude Desktop (skill + MCP server config) — no more manual JSON editing.

pipx install emodul
emodul auth login --browser
emodul install --all              # both Claude Code + Claude Desktop
# OR just one:
emodul install claude-desktop
emodul install claude-code
emodul install --dry-run claude-desktop   # preview only
emodul uninstall claude-desktop           # reverse

What's new

  • emodul install <target> — drops the right skill flavor (CLI-flavored for Claude Code, MCP-flavored for Claude Desktop) and, for Claude Desktop, atomically merges mcpServers.emodul into claude_desktop_config.json with a timestamped backup.
  • emodul uninstall <target> — clean reversal: removes the skill file + the mcpServers.emodul entry while preserving all sibling entries (preferences, other MCP servers).
  • SKILL_MCP.md — new MCP-flavored skill instructions (16-tool inventory, {ok: false} envelope semantics, no shell examples). Targets Claude Desktop / Cursor chat / Continue / Cline / Zed via description keywords.
  • Backward compatemodul skill install / uninstall keep working unchanged.

Safety

The config writer never overwrites silently:

  • Strict JSON parse (fails loud if your claude_desktop_config.json has comments or non-object root — refuses to silently rewrite)
  • Atomic write via tempfile + os.replace
  • Timestamped .bak-YYYYMMDDTHHMMSS (keep last 5)
  • fcntl.flock serializes concurrent invocations
  • Shallow merge preserves every sibling top-level key
  • Conflict detection: if mcpServers.emodul already exists with different args (e.g. you edited it manually), the install exits with a diff and requires --force to overwrite

Install

pipx install emodul

Full diff

v0.1.3...v0.1.4

v0.1.3 — MCP server + Python 3.10 floor

19 May 13:16
a659b91

Choose a tag to compare

Highlights

  • MCP server: emodul now ships a bundled Model Context Protocol server (16 tools) — drive heating zones from Claude Desktop, Cursor chat, Continue, Cline, Zed, or JetBrains AI Assistant. Add {"command": "emodul", "args": ["mcp"]} to your client's MCP config.
  • Python 3.10 floor (down from 3.11): unblocks Cowork sandboxes and Ubuntu 22.04 LTS users.
  • Browser-based login: emodul auth login --browser opens a local form so AI agents never see the password.
  • 3-path AGENT.md restructure: MCP / CLI-agent / sandbox-fallback runtime decision tree.
  • LoginFlowError replaces SystemExit in web_auth.web_login_flow — MCP server now survives login timeouts and bind failures (fix for PR #1 review finding).

Install

pipx install emodul

CI

Matrix passes on Python 3.10/3.11/3.12/3.13 × {ubuntu-latest, macos-latest}.

Full diff

v0.1.2...v0.1.3

v0.1.2 — browser login flow (no password in agent context)

19 May 10:27

Choose a tag to compare

The "your AI agent never sees your password" release.

New

  • emodul auth login --browser — opens a local sign-in form at http://127.0.0.1:<random-port>/ and waits for the user to enter credentials in the browser. Token is captured, password stored in the OS keychain — the CLI exit code 0 is the only thing the calling agent ever sees.

    Same trust model as gh auth login, gcloud auth login, etc. Critical when a non-technical user pastes the AGENT.md setup prompt into Claude Desktop / Codex CLI / etc.

  • Apple-system UI: dark-mode aware, animated success state, explicit safety disclaimer ("🔒 Your password is sent only to emodul.pl. The AI agent never sees it.")

  • Auto-flow selection: --browser is the default when stdin is not a TTY (agent context), --terminal when interactive. Override with explicit flags.

  • Flags: --port N, --no-open (print URL only), --timeout SECONDS (default 300).

Security

  • Binds 127.0.0.1 only (never 0.0.0.0)
  • Random CSRF state token (24 bytes urlsafe) in the URL; mismatched requests → 403
  • Single-use server: shuts down after first successful auth
  • Request log suppressed so state tokens don't leak to stderr
  • No new dependencies — pure stdlib (http.server, secrets, webbrowser, threading)

Install / upgrade

pipx upgrade emodul
# or
pip install --upgrade emodul

Then either:

emodul auth login --browser     # one-time setup, opens browser
emodul skill install            # tell Claude Code about the skill

…or hand the AGENT.md setup URL to your AI agent and let it do everything.

v0.1.1 — bundled Claude Skill + AGENT.md

19 May 10:06

Choose a tag to compare

The one-line setup release. Now pipx install emodul && emodul skill install is all an AI agent needs.

New

  • SKILL.md is now packaged in the wheelpip install emodul puts it at <site-packages>/emodul/SKILL.md. No more "I installed the CLI but the agent doesn't see the skill" surprise.
  • emodul skill subcommand group:
    • emodul skill path — abs path to packaged SKILL.md
    • emodul skill show — print contents
    • emodul skill install [--to PATH] [--symlink|--copy] [--force] — drops to ~/.claude/skills/emodul/SKILL.md by default
    • emodul skill uninstall
  • AGENT.md — copy-paste setup prompt for AI agents. Paste the RAW URL into Claude Code / Codex / Gemini CLI and the agent installs the CLI, the skill, and configures auth in one shot.
  • CI now also verifies that SKILL.md is in the wheel + tests the new skill subcommand on every PR.

Security / infra

  • Switched to PyPI Trusted Publishing (OIDC) — no token in repo secrets, GitHub-issued ephemeral credentials.
  • GitHub Actions bumped to v5/v6 — no more Node 20 deprecation warnings.

Install

```bash
pipx install emodul # recommended
emodul skill install # → ~/.claude/skills/emodul/SKILL.md
```

Or use the AGENT.md setup prompt — give your AI agent one URL and walk away.