Skip to main content

MorgenMCP

PyPI version

An unofficial MCP server for the Morgen calendar API.

Installation

Run MorgenMCP locally from PyPI, without cloning this repository.

  1. Install uv: brew install uv on macOS, or winget install astral-sh.uv on Windows. For Linux and other installation methods, follow the uv link.
  2. Get an API key from the Morgen Developer Portal.
  3. Choose your client below. uv manages the required Python version (3.12 or newer).
Client Setup
Claude Desktop Extension bundle or configuration file
Claude Code CLI command
Cursor Install button and configuration
VS Code Install button and configuration
Other MCP clients Generic stdio configuration

The server uses stdio: your client starts uvx morgenmcp; no server URL or port is needed. If it cannot find uvx, use its absolute path as described in Troubleshooting.

Claude Desktop

You can install MorgenMCP as a desktop extension bundle or configure it manually.

Desktop extension (.mcpb)

  1. Download the morgenmcp-X.Y.Z.mcpb bundle from the latest GitHub Release.
  2. Verify the download against its signed Sigstore provenance.
  3. Open the .mcpb file in Claude Desktop.
  4. Enter your API key when prompted in the extension settings (and optionally enable Read-only mode).

Claude displays an installation warning that developer info has not been verified by Anthropic; this is expected for community extensions. Then verify the connection.

Manual configuration

Open Settings → Developer → Edit Config. The file is ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows.

Merge the generic configuration into the file, replace your_api_key_here with your key, and restart Claude Desktop. Preserve any other servers already configured. Then verify the connection.

Claude Code

Replace the placeholder and run this command in your terminal:

claude mcp add --scope user --env MORGEN_API_KEY=your_api_key_here --transport stdio morgen -- uvx morgenmcp

This adds MorgenMCP to your personal configuration across projects. The key is stored in that configuration; entering it literally can also leave it in shell history. Use your shell's private-input mechanism if needed. In Claude Code, run /mcp to check the server status, then verify the connection.

See the Claude Code MCP guide for scopes and environment-variable configuration.

Cursor

Install in Cursor

The button opens Cursor with a proposed local server configuration. Replace your_api_key_here in the server's env configuration with your Morgen key before using it. The button contains only a placeholder; never put a real key in a shared install link.

For manual setup, open Cursor Settings → Tools & MCP, or edit your personal ~/.cursor/mcp.json. Merge the generic configuration, replace the key placeholder, and enable the server. Keep credentials in your personal configuration rather than a committed project file. Then verify the connection.

See Cursor's MCP documentation and install-link format.

VS Code

Install in VS Code

The button opens VS Code's installation flow with a password input for your Morgen API key. Review the configuration and install it in your user profile. If the browser does not open the app, use the manual setup below.

Run MCP: Open User Configuration from the Command Palette and merge this configuration, preserving any existing servers and inputs:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "morgen-api-key",
      "description": "Morgen API key",
      "password": true
    }
  ],
  "servers": {
    "morgen": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "morgenmcp"
      ],
      "env": {
        "MORGEN_API_KEY": "${input:morgen-api-key}"
      }
    }
  }
}

Start morgen from the MCP configuration editor and enter your key when prompted. Then verify the connection.

These input prompts are supported in VS Code's Local harness; servers requiring interactive inputs are not forwarded to Copilot harness sessions. See the VS Code configuration reference for supported credential options in your session.

Other MCP clients

Merge this into your client's MCP configuration and replace the key placeholder:

{
  "mcpServers": {
    "morgen": {
      "command": "uvx",
      "args": [
        "morgenmcp"
      ],
      "env": {
        "MORGEN_API_KEY": "your_api_key_here"
      }
    }
  }
}

If your client asks for separate fields, use command uvx, arguments morgenmcp, and environment variable MORGEN_API_KEY. Follow your client's configuration format; not every client uses the mcpServers wrapper.

Verify the connection

Ask your assistant: “List my Morgen calendars.” Check that it invokes list_accounts and/or list_calendars and returns your calendars. You can also try “What is on my Morgen calendar today?”

If startup fails or the tools do not appear, see Troubleshooting.

Read-only mode and version pinning

To expose only read tools, change args to ["morgenmcp", "--read-only"]. For the Claude Code command, append --read-only after uvx morgenmcp.

To pin a release, use ["morgenmcp==0.2.1"] (replace the version with your chosen release). To run an unreleased commit, use ["--from", "git+https://github.com/k3KAW8Pnf7mkmdSMPHz27/MorgenMCP@main", "morgenmcp"].

Available Tools

Tools across accounts, calendars, events, tasks, and tags — read-only and mutating:

  • Accounts & calendars: list_accounts, list_calendars, update_calendar_metadata
  • Events: list_events, create_event, update_event, delete_event, batch_update_events, batch_delete_events
  • Tasks: list_tasks, list_task_lists, get_task, create_task, update_task, move_task, complete_task, reopen_task, delete_task, batch_delete_tasks
  • Tags: list_tags, get_tag, create_tag, update_tag, delete_tag

Pass --read-only (or set MORGENMCP_READ_ONLY=1) to expose only the read-only tools. For the exact live list with schemas and annotations, connect any MCP client or run the MCP Inspector.

Configuration

MORGEN_API_KEY is required; everything else is optional. Each setting has an equivalent CLI flag, and the flag wins over the environment variable.

Environment variable CLI flag Default Description
MORGEN_API_KEY — (required) Morgen API key. The server refuses to start without it.
MORGENMCP_READ_ONLY --read-only off Truthy (1/true/yes/on) exposes only the read tools, disabling every mutating one.
MORGENMCP_TASKS_LIMIT --tasks-limit N 100 Default limit sent to /tasks/list. Integer 1–100.
MORGENMCP_TAGS_LIMIT --tags-limit N (unset) Default limit sent to /tags/list. Integer ≥ 1, no upper bound. Unset returns all tags.
MORGENMCP_DISPLAY_TZ — system local IANA timezone (e.g. America/Chicago) for rendering compact event times.
MORGENMCP_DATA_DIR — platform data dir Override the virtual-ID persistence directory.

An invalid limit fails at startup with a clear error rather than silently returning fewer results:

$ uv run morgenmcp --tasks-limit 500
morgenmcp: error: --tasks-limit must be <= 100 (got 500)

The two list limits are deliberately asymmetric, because Morgen documents the two endpoints differently: /tasks/list documents a default of 1 and a maximum of 100, while /tags/list documents neither and returns all tags when the parameter is omitted. A per-call limit argument on the tool always overrides both the flag and the environment variable.

Note: MORGENMCP_TASKS_LIMIT defaults to 100, which is MorgenMCP's own choice rather than Morgen's. /tasks/list returns a single task when limit is omitted — its documented default is 1, and the API docs tell callers to always set the parameter explicitly, so the server never leaves it to Morgen. This is only a fallback: the tool asks the model to pass a limit suited to the request, and a per-call value always wins. Set this variable to bound what a model can pull in one call, not to express a typical page size.

Troubleshooting

MORGEN_API_KEY is not set — provide the key through your client's setup above: the env block, VS Code password prompt, or Claude Code configuration. Desktop clients may not inherit your terminal's environment. Get a key from the Morgen Developer Portal.

uvx: command not found, or the server never starts — desktop clients are launched by the OS, not by your shell, so they see a minimal PATH that usually excludes ~/.local/bin, /opt/homebrew/bin, and version-manager shims. Use an absolute path instead:

which uvx   # e.g. /opt/homebrew/bin/uvx
"command": "/opt/homebrew/bin/uvx"

Nothing appears in the client — check the client's MCP log. Both failures above surface there and nowhere else, because a stdio server's stderr goes to the client, not to a terminal.

Development

Use Python 3.12 or newer. uv provisions the version pinned in .python-version for this checkout. mise is optional; see Environment Setup if you already use it.

# Clone the repository
git clone https://github.com/k3KAW8Pnf7mkmdSMPHz27/MorgenMCP.git
cd MorgenMCP

# Install dependencies
uv sync --all-extras

# Run tests
uv run pytest

Environment Setup

The server reads MORGEN_API_KEY from the process environment — it does not load a .env file itself. Either of the following supplies it. Both keep the key in a gitignored file; neither is required if the variable is already exported in your shell.

With uv alone. Put the key in a .env file (already gitignored) and let uv load it:

echo 'MORGEN_API_KEY=your_api_key' > .env
UV_ENV_FILE=.env uv run morgenmcp

Export UV_ENV_FILE=.env in your shell profile to skip the prefix. uv run --env-file .env <cmd> works the same way for one-off commands.

If uv is itself installed through mise (a shim under ~/.local/share/mise/shims/uv), every uv call routes through mise, and mise refuses to run against this repo's untrusted mise.toml — so uv run fails until you mise trust. That is a property of that install, not of this project; a standalone uv (brew install uv) is unaffected.

With mise (optional, recommended if you already use it). This repo ships a mise.toml declaring MORGEN_API_KEY as required, so a missing key fails immediately with setup instructions instead of surfacing on the first tool call. mise set writes to a gitignored mise.local.toml, never the committed config:

mise trust
mise set --file mise.local.toml MORGEN_API_KEY=your_api_key
uv run morgenmcp

mise also puts the interpreter from .python-version on PATH in a plain shell, so a bare python3 in a clone is the right one — useful because the source requires Python 3.12 or newer (see Development).

Local Debugging with MCP Inspector

The MCP Inspector provides a web UI for testing tools and inspecting requests/responses:

npx @modelcontextprotocol/inspector uv run morgenmcp

Opens at http://localhost:6274

Releasing

After main-branch CI (including desktop bundle checks) passes, Conventional Commits determine the next release: feat: bumps minor and fix: bumps patch. Breaking changes (! or BREAKING CHANGE:) bump minor below 1.0 and major thereafter; start 1.0 with a deliberate manual release. Other commits do not release. Use these prefixes on PR titles when squash merging.

The automation creates an annotated tag and dispatches release.yml using GITHUB_TOKEN. Manual stable tag pushes also work. If dispatch or publication fails after tagging, retry with gh workflow run release.yml --ref vX.Y.Z instead of creating another version.

Stable vX.Y.Z tags trigger the GitHub Actions release workflow, which runs tests, builds wheel and sdist distributions and a desktop bundle, and requires verified Sigstore provenance for every release artifact before publishing to PyPI and GitHub Releases. The workflow uses the existing pypi environment and PyPI trusted publishing. Verified files are retained as an Actions artifact for 30 days if publication needs recovery.

Verify a release download

Release assets include provenance.sigstore.json and SHA256SUMS. With a recent GitHub CLI, replace vX.Y.Z below with your release:

REPO=k3KAW8Pnf7mkmdSMPHz27/MorgenMCP
TAG=vX.Y.Z
COMMIT="$(gh api "repos/$REPO/commits/$TAG" --jq .sha)"
gh release download "$TAG" --repo "$REPO" --dir release-download \
  --pattern '*.mcpb' --pattern provenance.sigstore.json

gh attestation verify "release-download/morgenmcp-${TAG#v}.mcpb" \
  --bundle release-download/provenance.sigstore.json \
  --repo "$REPO" --signer-workflow "$REPO/.github/workflows/release.yml" \
  --source-ref "refs/tags/$TAG" --source-digest "$COMMIT" \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  --predicate-type https://slsa.dev/provenance/v1 --deny-self-hosted-runners

Proceed only if verification succeeds. Use a separately reviewed commit SHA for COMMIT if you want to pin it independently of the current GitHub tag. The same command can verify a downloaded wheel, source archive, or checksums file. Sigstore verifies build provenance; it does not confer Anthropic-verified publisher status in Claude Desktop. The manual provenance-trial.yml workflow exercises signing, verification, and tamper rejection without publishing a release.

Contributing

See AGENTS.md for environment setup, conventions, and the checks to run before handing off changes.

AI-assisted contributions are welcome and must be disclosed — see AI_POLICY.md, adapted from the Ghostty project's AI policy (MIT).

License

Apache 2.0 - See LICENSE and NOTICE for details.

Metadata

Release files for morgenmcp 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for morgenmcp 0.3.1
File Size Uploaded Provenance Actions
morgenmcp-0.3.1.tar.gz 183.5 kB Without provenance Details for morgenmcp-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for morgenmcp 0.3.1
File Interpreter ABI Platform Actions
morgenmcp-0.3.1-py3-none-any.whl Python 3 none any Details for morgenmcp-0.3.1-py3-none-any.whl

Total release size: 243.0 kB

Release files / morgenmcp-0.3.1.tar.gz

Download URL morgenmcp-0.3.1.tar.gz
Size 183.5 kB
Tags Source
SHA-256 checksum
How to use checksums
711f1bbaba860e2bbbb3d66a1fa24d15c936f21aeca9e7ea504eef8b959de853
BLAKE2b-256 checksum
How to use checksums
48694600ca7e6b8da07623642b40f00b7e6511f6e6ee7dbdbd4c5bb92fc0822f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / morgenmcp-0.3.1-py3-none-any.whl

Download URL morgenmcp-0.3.1-py3-none-any.whl
Size 59.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4b0ab6b7986732a82dc28daeb6dc61b7e426098d8b86602ec55c87b558b590b
BLAKE2b-256 checksum
How to use checksums
d7b88ae8c80b48b4c82b80c7b22845f0266bd9e2aebe5139a9169a5c505c3168
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for morgenmcp 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page