Skip to content

Releases

v3.3.1

Choose a tag to compare

@fatherlinux fatherlinux released this 11 Nov 23:03
3f07ccf

Fixed

  • The container installed its dependencies from a fresh resolve of
    pyproject.toml instead of the committed, Dependabot-maintained
    uv.lock. pip install . reads only the floor pins, so the image
    shipped whatever had been released that morning -- a dependency set
    no test had ever run against. This is the same bug that shipped
    google-genai 3.0.0 to production in mcp-gemini while CI tested 2.34.0,
    causing an outage there (Part of RT#1564). The builder now exports the
    lock to a requirements file in a dedicated stage and installs from it
    with --no-deps, so pip cannot re-resolve anything the lock already
    decided.

v3.3.0 — the cap was checked after the body was already in memory

Choose a tag to compare

@fatherlinux fatherlinux released this 09 Nov 05:57
eecda68

RT #1601, the fleet's outbound HTTP contract. Three read paths here — the API, a content download and the OAuth token exchange — and all three had the same defect.

  • The cap was checked after the body was in memory. Each path compared len(response.content) > MAX_RESPONSE_SIZE once the whole body had arrived. All three now stream, measured before each chunk is copied in, because aiter_bytes() promises nothing about chunk size: one chunk can be the whole body. The token exchange gets its own, smaller cap — a token response is a handful of JSON fields, and anything page-sized answering on that URL is not a token.
  • Requests were nameless. All three paths now send mcp-pcloud-crunchtools/<version> (+<repo>), the version read from installed package metadata so it cannot drift from pyproject.toml.
  • Malformed JSON from listfolder blamed the parser for what is usually a challenge page. Errors now name the method, the full requested URL, the status, the content-type and a bounded snippet.

A pCloud content URL is signed, so naming it is only safe because the signature comes out first: userinfo is dropped and credential-shaped query parameters are replaced. The token exchange quotes no body at all — it is the one endpoint whose body is a credential.

Two things review caught that are worth recording:

  • Replacing response.text lost the declared charset, so a Latin-1 document would have come back with replacement characters where its accents were. It decodes with response.encoding now.
  • The old suite patched httpx.AsyncClient.get and httpx.Client.post. A patch on a method the code no longer calls does not fail — it lets the test reach the real network, which is how three tests were briefly talking to api.pcloud.com. The suite rides a MockTransport now, which has no live socket to fall through to.

Constitution pin v1.31.0 → v1.36.0.

v3.2.2

Choose a tag to compare

@fatherlinux fatherlinux released this 07 Nov 22:55
38d719e

fastmcp 4.1.4 → 4.1.6 and pytest-asyncio 1.4.1 → 1.4.1.post1, both inside their declared ranges (#67, #68).

This is also the first release of this service deployed by the RT Deploy queue rather than by the nightly fleet auto-update. Its unit carries io.crunchtools.deploy=deployer and no io.containers.autoupdate label, so a change reaches production when a ticket names a commit — with a maintenance window, a health probe that has to hold, and one automatic rollback — and not because a container happened to restart.

v3.2.1

Choose a tag to compare

@ashigaru-crunchtools ashigaru-crunchtools released this 31 Oct 23:06
72f66b8

Security

  • Upgraded locked dependencies within their declared ranges to clear the
    advisories the fleet dependency audit found (authlib, certifi, dnspython, fastmcp, joserfc, opentelemetry-api, pyjwt).

v3.2.0

Choose a tag to compare

@fatherlinux fatherlinux released this 24 Oct 16:54
74e889d

Fixed

  • pcloud_search failed at / (pCloud error 1101) and on large folders such as
    /Documents, where one recursive listfolder outgrew the 10 MB response
    limit. It now walks the tree breadth-first with one non-recursive
    listfolder per folder. The depth (8) and result (100) bounds are unchanged;
    a new bound of 200 listings stops the walk and tells the caller to narrow the
    path (RT #1542).

v3.1.0

Choose a tag to compare

@ashigaru-crunchtools ashigaru-crunchtools released this 20 Oct 17:06
300153b

Changed

  • Container base images pinned to quay.io/hummingbird/python:3.14* instead of
    latest, which moved to Python 3.15.0 on 2026-10-20 (crunchtools/constitution#66).

v3.0.1

Choose a tag to compare

@ashigaru-crunchtools ashigaru-crunchtools released this 17 Oct 01:20
38b4dee

Fixed

  • pcloud_search called search, which is not a published pCloud method and
    timed out or matched nothing against the live API. It now lists path with
    listfolder (recursive=1) and matches names case-insensitively by
    substring. The walk is bounded to 8 levels and 100 results; the output says
    when it truncated. The tool name and signature are unchanged.

v3.0.0

Choose a tag to compare

@fatherlinux fatherlinux released this 11 Oct 03:09
edeb92a

Changed

  • BREAKING: path is now required on pcloud_list_folder and
    pcloud_search; it no longer defaults to /. Both tools now publish
    readOnlyHint: true. A required argument is never dropped by a gateway, so
    an annotated call cannot widen to the whole account.

Fixed

  • pcloud_read_text_file called gettextfile but parsed a getfilelink
    response, so it failed on every call (pCloud rejected the credential with
    "Log in required"). It now calls getfilelink, as the code already expected.
  • The content download no longer sends the Authorization: Bearer header to
    the content host. It uses a separate client with no base URL and no
    credential; the content URL is already signed.

v2.6.0

Choose a tag to compare

@fatherlinux fatherlinux released this 10 Oct 12:02
a5f3f25

Added

  • Six tools that only read (pcloud_get_file_info, pcloud_read_text_file,
    pcloud_get_checksum, pcloud_get_file_link, pcloud_get_user_info,
    pcloud_auth_status) publish readOnlyHint: true. A gateway uses it to
    decide whether an invalid optional argument may be dropped or must refuse the
    call (crunchtools/constitution#35). pcloud_list_folder and pcloud_search
    also only read but stay unannotated: their optional path defaults to /,
    so a dropped path would widen the call to the whole account.
  • Tests pin every registered tool into READ_ONLY or WRITES, and check that
    each read-only tool calls only pCloud API methods from a named read set and
    leaves the token store untouched.

Changed

  • Inherits constitution v1.22.0; the workflow pins move with it.
  • Constitution is now a v1.18.0 manifest: only repo-specific facts remain;
    fleet and profile rules apply by reference.
  • Constitution validation is pinned via .github/workflows/constitution.yml.
  • Dependabot auto-merges GitHub Actions minor and patch updates.

v2.5.0

Choose a tag to compare

@fatherlinux fatherlinux released this 20 Sep 00:14
e6b84a7

Browser authorization, driven through MCP

Re-authorizing a containerized pCloud server is now a tool call instead of a runbook. Nothing is copied by hand.

Added

  • pcloud_auth_status — whether the server holds a usable credential, and if not, what is missing. Verifies a stored token against pCloud rather than assuming its presence means it works.
  • pcloud_auth_start — returns the URL to open. The user approves in a browser; pCloud redirects back and the token is stored server-side.
  • pcloud_auth_result — what the last redirect did, for when status alone cannot tell whether one ever arrived.
  • A /callback route on the server's own HTTP port via FastMCP's custom_route. This is what removes the copy-and-paste step: the exchange happens before the page renders. No second listener, no extra port.
  • PCLOUD_OAUTH_REDIRECT_URI is now read by the server as well as the CLI.

Security

  • The CSRF state outlives the tool call in a single-slot holder: expires after 10 minutes, single-use, and superseded rather than duplicated when a second authorization starts. Two outstanding valid states would be two ways in.
  • A redirect's reported region is honoured only when it is a known pCloud endpoint, so it cannot aim the client at an arbitrary host.

Tool count is now 18.

Full Changelog: v2.4.0...v2.5.0