RELEASE NOTES

Chilkat v11.6.0 / v11.6.1

New platforms · AI tooling · MCP · dozens of fixes

NOTICE
Chilkat v11.6.1 is a patch release with nine changes. Nothing else in v11.6.0 is affected; upgrade if one of these applies to you:
  • Rust (new) — Chilkat for Rust is now available as the chilkat crate on crates.io: cargo add chilkat, and the prebuilt Chilkat library for Windows, Linux, Alpine Linux, or macOS is downloaded automatically at build time. Details
  • ActiveX — members added in v11.6.0 were not callable from the ActiveX; they are now. Details
  • Java — the per-JDK downloads are replaced by one download per OS/architecture that works with every JDK from Java 8 up. Details
  • Lazarus / Free Pascal — fixes to the .pas wrapper units: four units that would not compile, and five that raised Entry point not found at startup. Details
  • Perl — Perl 5.42 and 5.44 are added, and the 32-bit x86 and armv7l Linux/Alpine builds are retired. Details
  • PHP — the PHP extension is rebuilt on an improved code generator with no API changes; installing it is now one command (a Composer package, chilkat/chilkat, or an install script); and the 32-bit Alpine Linux builds (x86 and armv7l) are retired. Details
  • Python (CkPython) — the chilkat module is rebuilt on an improved code generator with no API changes and now targets the CPython stable ABI, so one download per platform (and one pip wheel) works with every Python from 3.7 onward; Windows ARM64 is added; Python 3.6 and earlier, and the 32-bit x86 and armv7l Alpine builds, are retired. Details
  • Ruby — the Ruby extension is rebuilt on an improved code generator with no API changes, and Ruby 3.2 is retired. Details
  • Tcl — Tcl 9.0 is now available for Windows, the two 64-bit Tcl 8.6 downloads have become one, and strings are UTF-8 by default. Details

This release adds several major new capabilities — Chilkat for B4X, cross-platform Delphi DLL and Lazarus / Free Pascal editions, Model Context Protocol (MCP) support, AI structured output and web search, and Argon2 password hashing — along with a broad set of fixes and improvements across the crypto, email, HTTP/REST, and text-processing classes.

✨ Release Highlights

AreaWhat’s new
🧩 New platformsChilkat for B4X (B4A + B4J), cross-platform Delphi DLL (Linux, macOS, iOS, Android, Win-ARM), and Lazarus / Free Pascal
🤖 AIMCP client + Ai.UseMcp, JSON-Schema structured output, provider-hosted web search
🔐 CryptoArgon2 (id/i/d) password hashing & key derivation in Crypt2
🛡️ ReliabilityStrict JSON/XML loading, StringBuilder.IsWellFormed, secrets-aware unlock & JSON load
🧰 FixesJWE, JWS, MIME, PrivateKey/PublicKey, Socket, IMAP, REST, HtmlToText, PCRE2

✨ New Features & Additions

📱 Chilkat for B4X (B4A and B4J)

Chilkat is now available for B4X: B4A (Android) and B4J (Windows, Linux, macOS).

  • One download, two libraries — ChilkatB4A.jar and ChilkatB4J.jar (each with its .xml), installed by copying into the IDE’s additional-libraries folder.
  • Familiar, prefixed classes — every Chilkat class appears as a Chilkat-prefixed B4X type (ChilkatHttp, ChilkatCrypt2, ChilkatZip, …) with full IDE autocomplete. The API is identical in B4A and B4J, so code moves between them unchanged.
  • Self-contained jars — native libraries for all supported CPUs are inside: packaged into the APK automatically on Android (armeabi-v7a, arm64-v8a, x86, x86_64; 16 KB-page aligned), and loaded automatically on the desktop (Windows x64, Linux x86_64/arm64/arm, macOS Intel and Apple Silicon).
  • Progress events — long-running calls raise the standard AbortCheck, PercentDone, and ProgressInfo events as ordinary B4X event Subs.
  • Requirements — Android 7.0+ (minSdkVersion 24) on B4A; Java 8+ on B4J.

🧡 Chilkat for Lazarus / Free Pascal

Chilkat is now available for Lazarus / Free Pascal (FPC) — a fully generated Object Pascal API in which each Chilkat class is wrapped by its own self-contained Pascal unit (Chilkat.Http.pas, Chilkat.Zip.pas, …), each providing a Pascal class (THttp, TZip, …) derived from TChilkatBase.

  • No compile-time linking — the units resolve all functions at runtime from the native Chilkat C bridge library via CkDllLoader.pas.
  • Plain Pascal strings — string throughout; UTF-8 conversion is handled internally.
  • No circular uses — object parameters and return values are typed as TChilkatBase, so you add only the units you actually use.

Supported platforms (the chilkat_c_bridge runtime library):

OSArchitectures
Windowsx86, x64, ARM64
Linuxx86_64, arm64, x86, armhf
macOSUniversal (Apple Silicon + Intel)

CkDllLoader.pas selects the correct library for the current OS and architecture automatically, and a custom load path can be specified.

uses
  Chilkat.Base, Chilkat.Http;
var
  http: THttp;
begin
  http := THttp.Create;
  if not http.IsValid then
    raise Exception.Create('Failed to load the Chilkat library.');
  WriteLn(http.QuickGetStr('https://www.example.com/'));
  http.Free;
end;

Event-capable classes provide the three synchronous callbacks as Pascal of object event properties — OnAbortCheck, OnPercentDone, and OnProgressInfo (handler types declared in Chilkat.Base.pas). The HeartbeatMs property controls OnAbortCheck frequency, and returning True from OnAbortCheck or OnPercentDone aborts the running method.

⚙️ Scope synchronous API only: no async (*Async) variants, and no Task / TaskChain classes.

🔷 Chilkat Delphi DLL — Now Cross-Platform

The Chilkat Delphi DLL API, previously available only as a Windows 32-bit/64-bit DLL, is now provided as a native library for every major Delphi target. The same flat API (CkHttp_QuickGetStr, CkZip_Unzip, …) that Delphi applications call on Windows can now be used unchanged in FireMonkey (FMX) applications on Linux, macOS, iOS, and Android, and on Windows-on-ARM devices.

PlatformDelivered as
Linuxshared libraries for x86_64 and arm64
macOSa universal (Apple Silicon + Intel) dylib, code-signed with a Developer ID certificate and secure-timestamped for notarization
iOSa static library linked directly into the application, per Apple’s requirements for device deployment
Androidnative libraries for the standard Android ABIs
Windows on ARMa new ARM64 (ARM64EC) DLL — native ARM code on Windows-on-ARM devices, including within existing x64 Delphi apps running under emulation

🤖 Model Context Protocol (MCP)

Chilkat v11.6.0 adds support for the Model Context Protocol (MCP) — an open protocol that standardizes how applications provide tools, resources, and prompts to AI models. This release introduces a new Mcp class (an MCP client) and integrates MCP tools into the existing Ai class through a new UseMcp method.

New class: Mcp

The Mcp class connects to an MCP server and gives an application unified access to the server’s tools, resources, and prompts. It uses the MCP Streamable HTTP transport (protocol version 2025-06-18): a single endpoint URL handles the JSON-RPC exchange over HTTP POST, and a server response may arrive either as a single JSON object or as a Server-Sent-Events stream — both handled transparently. The stdio transport is not supported in this release.

CapabilityDetails
ConnectingConnect performs the MCP initialize handshake, then SessionId, ProtocolVersion, ServerName, ServerVersion, and ServerInstructions are populated and Connected is true. Chilkat sends the MCP-Protocol-Version and Mcp-Session-Id headers automatically; Close terminates the session (HTTP DELETE).
ToolsListTools returns each tool’s name, description, and inputSchema; CallTool invokes a tool by name and returns its content array and isError flag. A tool that runs but reports failure returns success with isError true.
Resources & promptsListResources / ReadResource (text or base64 blob) and ListPrompts / GetPrompt.
Auth & settingsAuthToken for a bearer token; SetConnectionSettings copies proxy, bind-IP, and TLS options from a Socket. Timeouts via IdleTimeoutMs (180000) and ConnectTimeoutMs (30000); HeartbeatMs controls the AbortCheck interval.

MCP tools in the Ai class: UseMcp

Mcp mcp;
mcp.Connect("https://example.com/mcp");

Ai ai;
ai.put_Provider("openai");
ai.put_ApiKey(myKey);
ai.put_Model("gpt-5.1");
ai.NewConvo("chat","You are a helpful assistant","");

// Register the MCP server's tools with the model.
ai.UseMcp(mcp,"myserver");

ai.InputAddText("Use the available tools to answer: ...");
ai.Ask("text");

UseMcp registers the connected server’s tools with the model, namespacing each tool name with the supplied prefix so tools from different servers (and JavaScript tools) cannot collide. Because MCP tools are presented as ordinary function tools, UseMcp works with every provider the Ai class supports — OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity. When the model requests a tool during an Ask, Chilkat automatically routes the call via Mcp.CallTool, adds the result to the conversation, and continues — no application code is required to run the tool. This works in both the standard Ask and in streaming mode (surfacing as a js_function_call event handled by StreamingJsToolCall). An informational ProgressInfo event named McpToolCall is emitted before each automatic MCP tool call.

📝 Notes Automatic tool use requires a selected conversation (not a stateless query). The Mcp object passed to UseMcp must remain connected and valid for as long as its tools are used.

🎯 Ai — Structured Output (JSON Schema)

Supply a JSON Schema and the AI model returns a response that conforms to it — ideal for reliable data extraction and function-argument generation.

Call SetOutputSchema(name, schema, strict) to request schema-constrained output, then retrieve the parsed result with GetOutputJson. The same code works across OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity — Chilkat translates your one schema into each provider’s native format. When strict is enabled, Chilkat automatically augments the schema (adding additionalProperties: false and required-property lists) for the providers that need it. Refusals are surfaced distinctly via the LastResponseRefused and RefusalText properties.

📘 See Chilkat AI Structured Output for full details, the provider-support matrix, and examples.

🔎 Ai — Web Search

Unified, provider-hosted web search for the Ai class. When enabled, the AI provider performs a live web search while generating its response and answers using the retrieved results, returning citations. A single Chilkat API drives web search across providers, so the same application code works whether the provider is OpenAI, Anthropic Claude, Google Gemini, xAI Grok, or Perplexity.

Enabling web search — turned on per-request through a new web_search object passed to SetAskParams. Only enabled is required; every other field is optional, and Chilkat silently ignores fields a given provider does not support.

{
  "web_search": {
    "enabled": true,
    "max_uses": 3,
    "allowed_domains": [ "wikipedia.org", "nasa.gov" ],
    "blocked_domains": [ ],
    "recency": "week",
    "user_location": {
      "country": "US",
      "city": "Chicago",
      "region": "Illinois",
      "timezone": "America/Chicago"
    }
  }
}
FieldMeaning
enabledTurns web search on for the Ask. For Perplexity, search is always on (no-op).
max_usesMaximum searches the model may perform — the primary cost-control knob.
allowed_domains / blocked_domainsRestrict results to, or exclude, specific domains.
recencyLimit results by age: day, week, month, or year.
user_locationOptional country, city, region, timezone to localize results.

Retrieving the sources — a new GetSearchResults method returns the sources the model used in the most recent Ask, normalizing each provider’s citation format into one flat structure (url, title, snippet, page_age). The complete, unmodified provider response remains available via GetLastJsonData. Streaming — when Streaming is enabled, a standardized web_search_call event is delivered through NextAiEvent while the provider searches.

Provider support:

Fieldopenaiclaudegooglexaiperplexity
enabledYesYesgroundingYesalways on
max_uses—Yes—max results—
allowed_domainsYesYes—YesYes
blocked_domains—Yes—YesYes
recency———date rangeYes
user_locationYesYes———

📝 Notes Google Gemini web search (grounding) is available only through the native Gemini API, not the OpenAI-compatible path. deepseek and mistral (chat) have no web-search tool: if web_search is set, the Ask proceeds without search and a note is written to LastErrorText, so provider-switching code degrades gracefully. Most providers bill web searches separately from tokens — use max_uses to bound per-request cost.

🔐 Crypt2 — Argon2

Chilkat now implements Argon2, the memory-hard password hashing and key-derivation function specified in RFC 9106 and winner of the Password Hashing Competition. All three variants are supported: Argon2id (the recommended default), Argon2i, and Argon2d. Its memory cost makes large-scale cracking on GPUs and custom hardware impractical, which is why Argon2 is now the recommended choice over PBKDF2 and bcrypt for new applications.

MethodPurpose
Argon2DeriveKeyDerives a key of any length from a password (for encryption keys and other key-derivation uses).
Argon2HashPasswordHashes a password for storage, returning a PHC-format string such as $argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>. A random salt is generated automatically.
Argon2VerifyPasswordVerifies a password against a stored PHC-format hash. All parameters are read from the stored hash.

Options are passed as a JSON string rather than many new properties. Every member is optional — an empty string uses defaults suitable for password hashing (Argon2id, version 19, 3 iterations, 64 MB memory, 32-byte hash, 16-byte random salt):

{
  "variant": "argon2id",
  "iterations": 3,
  "memoryCostKb": 65536,
  "parallelism": 1,
  "keyLen": 32,
  "salt": "cmFuZG9tc2FsdDEyMzQ="
}

The short RFC 9106 / PHC parameter names (t, m, p, v) are accepted as aliases, and the optional RFC 9106 secret (a pepper) and associated data inputs are supported.

  • Hash strings are standard PHC format and interoperate with other Argon2 implementations in both directions.
  • If a stored hash string is malformed, Argon2VerifyPassword returns false and LastMethodSuccess is false, distinguishing a bad hash string from a wrong password.
  • A maxMemoryKb option caps allocation — important when verifying hashes from an untrusted source, since the memory cost is read from the stored string.
  • Version 0x10 (16) hashes can be verified for compatibility; new hashes use version 0x13 (19).

🔑 Secrets-Aware Methods

Chilkat.Global.UnlockBundle and JsonObject.Load are now secrets aware. Each can accept a secret specification string (beginning with !!) in place of a literal value, and Chilkat resolves it from the Windows Credential Manager (Windows) or Apple Keychain (macOS). Secrets are identified by the structured format !![appName|]service[|domain]|username, letting applications resolve credentials at runtime instead of embedding them in code.

📝 There is no EnableSecrets property — UnlockBundle is always secrets aware. If the secret is not present in a local manager, the spec is used as-is, causing UnlockBundle to either fail or succeed in trial mode.

🧪 Strict Loading for Xml and JsonObject

Chilkat’s XML and JSON parsers are deliberately tolerant: given input that is not well-formed they parse what they can, report success, and leave a partially populated document. That is the wrong behavior when a silently dropped element or member changes what the application does. Both classes now have a Strict property that closes this off.

PropertyBehavior when true
Xml.Strict
(default false)
Checks the input is well-formed XML before parsing; on failure the load fails and the object is left unchanged. Applies to LoadXml, LoadXml2, LoadSb, LoadBd, LoadXmlFile, LoadXmlFile2. (Well-formedness only, not validating.)
JsonObject.Strict
(default false)
Validates the text against the full JSON grammar first; on failure leaves existing contents unchanged. Applies to Load, LoadSb, LoadBd, LoadFile, LoadPredefined.

Both default to false, so existing applications are unaffected. Turn Strict on for input carrying configuration, credentials, signed content, or security parameters.

✔️ StringBuilder.IsWellFormed

A new method, IsWellFormed(format), returns true if the contents of the StringBuilder are well-formed JSON or XML. The format argument must be "json" or "xml" (case insensitive). It answers the question the tolerant parsers do not — about text already in hand, with no JsonObject or Xml object created first.

sb.LoadFile("config.json","utf-8");
if (!sb.IsWellFormed("json")) {
    // the file is not well-formed JSON
}

For "json", the full RFC 8259 grammar is checked; for "xml", XML 1.0 well-formedness (the same checks Strict applies). Empty contents are not well-formed. The contents are never modified, and deeply nested input is rejected at a nesting limit of 256 (validation is iterative, so no depth can exhaust the call stack).

📊 HtmlToText — Table Rendering

HtmlToText now renders HTML tables as fixed-width text tables. Previously a <table> was converted by placing each cell on its own line, losing the row-and-column relationship; tables are now drawn as aligned, bordered text tables that preserve the original structure. No code changes are required to benefit.

⚠️ Output change because this changes the text produced for tables, review the notes below if your application compares HtmlToText output against saved or expected strings.

  • Rows and columns preserved — drawn with | separators and +/- borders, every column aligned.
  • Header rows set apart — <th> cells are centered and underlined with a row of =.
  • Columns sized to content and kept within RightMargin; long cell text wraps inside the cell rather than overflowing.
  • Rich cell contents — paragraphs, ordered/unordered lists (including nested), <pre> blocks, line breaks, and basic inline formatting render within the cell’s column.
  • Merged and nested tables honored — colspan and rowspan are supported, and a table inside a cell is drawn as its own bordered table. A <caption> is centered above the table.
  • Links in cells follow the same link settings as the rest of the document (shared “References” list with bracketed numbers by default).

🖼️ See the HTML Table to Plain Text Gallery for examples rendered with the improved v11.6.0 HtmlToText.

➕ Smaller Additions

  • Url.Scheme — added the Scheme property to Chilkat.Url. The scheme is the first part of a URL (e.g. https in https://www.example.com/page); common schemes include http, https, ftp, file, and mailto.
  • Ssh.GetReceivedSb — added to the Ssh class, for retrieving received data into a StringBuilder.
  • MailMan.RequireHostnameMatch and MailMan.SniHostName — added properties. RequireHostnameMatch (default false) requires the TLS hostname to match a name in the server certificate’s Subject Alternative Name extension; it is enforced independently of RequireSslCertVerify. SniHostName sets the DNS hostname sent in the TLS Server Name Indication for SMTP and POP3 connections (normally left empty, in which case SmtpHost / MailHost is used); set it when connecting by IP address or through an alternate endpoint, and it is also the name compared when RequireHostnameMatch is true.
  • JsonArray.FindStartIndex — added property.
  • Azure Key Vault cloud signing — an application may now specify the access_token directly instead of client_id / client_secret / tenant_id, so it can obtain its own token (for example via a Managed Identity) and pass it straight to Chilkat:
    jsonAzure.UpdateString("service", "azure_keyvault");
    jsonAzure.UpdateString("access_token", accessToken);
    jsonAzure.UpdateString("vault_name", "VAULT_NAME");
    jsonAzure.UpdateString("cert_name", "CERT_NAME");
    jsonAzure.UpdateString("cert_version", "CERT_VERSION");
    See Sign PDF in the Cloud using Azure Key Vault.
  • iOS builds — updated makeUniversalLib.sh and added a new script for building an XCFramework; the iOS download page was updated following removal of the obsolete armv7 and armv7s slices.

🛠️ Fixes & Improvements

🌐 HTTP / REST

⚠️ Breaking change AllowHeaderFolding (on both Chilkat.Rest and Chilkat.Http) now defaults to false. HTTP header folding is obsolete (RFC 7230 says a sender must not generate folded headers), and modern servers increasingly reject folded headers with 400 Bad Request — which previously happened whenever a header value was long (e.g. a lengthy Authorization header). Applications that require folded headers can restore the old behavior by explicitly setting AllowHeaderFolding = true.

Rest — response body after ReadResponseHeader. In the manual request/response pattern (explicit steps rather than a FullRequest* method), the response body was not readable after ReadResponseHeader: the object incorrectly moved to an idle state for all verbs, so every body-read call failed with “not in the state to read the response body.” Fixed — after a valid status code, the object now correctly enters the body-reading state for any request that can have a body. A HEAD request (no body) still correctly stops after the header. FullRequest* methods were never affected.

Rest — ReadRespBodyStream and EndOfStream. Fixed a spurious read failure when downloading a response body into a Stream and reading it on another thread. After the full body was received, EndOfStream could remain false, so a loop on EndOfStream made one extra read that failed. Now EndOfStream becomes true once the body is delivered and consumed, and a read at the very end returns success with no bytes rather than an error. No code changes required.

📄 HtmlToText — Correctness Fixes

A number of correctness and reliability fixes. Existing code does not need to change; items that alter the exact output are marked (output change).

  • Fixed a possible crash or garbage output on invalid or truncated UTF-8. Malformed multi-byte characters near a line-wrap boundary could cause the converter to read past the end of the text. Such input is now handled safely.
  • Right-margin wrapping for non-ASCII text (output change) — words with multi-byte characters (accented letters, CJK, emoji) are now measured by display width rather than byte count, so lines wrap at the intended margin.
  • Removed spurious spaces around hyperlinks (output change) — e.g. (link) instead of ( link ), and no space before punctuation following a link.
  • Links cross-referenced to the References list (output change) — each link is followed by a bracketed reference number matching the References list; duplicate URLs share a number.
  • Ordered lists numbered correctly (output change) — items counted correctly even with stray content in an <ol>; the start attribute is honored.
  • List markers no longer leak into nested lists, and line up consistently (output change).
  • Removed a leading blank line (output change) before the first heading, paragraph, or list.

🔒 Crypto — JWE, JWS, Keys

JWE — ECDH-ES key wrapping. ECDH-ES+A128KW / A192KW / A256KW now produce standards-compliant, interoperable output in all cases. The content-encryption key had been sized to twice the key-wrap key length instead of the size required by the chosen enc algorithm, so behavior depended on whether the two happened to line up:

OutcomePairings
UnaffectedValid & interoperable — “aligned” pairings: A128KW+A128CBC-HS256, A192KW+A192CBC-HS384, A256KW+A256CBC-HS512, and A128KW+A256GCM
FailedCBC-HMAC enc whose required size didn’t match — e.g. A128KW+A256CBC-HS512
Wrong outputAES-GCM enc pairings where sizes didn’t align (non-interoperable, or failed)

The content-encryption key is now always generated at the correct size and wrapped correctly. Only JWEs from the affected combinations need to be regenerated; those from the unaffected pairings remain fully compatible.

JWS — CreateJwsSb serialization. Fixed: CreateJwsSb now respects PreferCompact and PreferFlattened. Previously it always produced the general JSON serialization, even when compact output was requested. To keep the old always-general output, set PreferCompact = false (and, for a single signature, PreferFlattened = false).

PrivateKey — fixes and changes (verified with RSA, P-256 EC, and Ed25519 keys)

  • Fixed SavePemFile and SavePkcs8PemFile, which had been reversed — SavePemFile now writes the traditional representation, SavePkcs8PemFile writes PKCS #8.
  • Ed25519 DER/PEM export now uses the correct OID 1.3.101.112 (was sometimes the X25519 OID 1.3.101.110).
  • Ed25519 XML from GetXml now loads successfully.
  • JWK validation: an unsupported kty now fails instead of silently leaving the object empty.
  • GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of silently using SHA-1.
  • Pkcs8EncryptAlg: names normalized consistently; unsupported/empty resets to the default 3des.
  • EC PEM labeling corrected (EC PRIVATE KEY, PRIVATE KEY, or ENCRYPTED PRIVATE KEY) so the label agrees with the DER structure.

PublicKey — fixes and changes (verified with RSA, EC, and Ed25519 keys)

  • GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of using SHA-1.
  • JWK validation now fails on missing required members, unsupported key type, or a zero RSA exponent, without leaving a partially initialized object.
  • LoadEd25519 requires exactly 32 bytes (64 hex chars) and rejects prefixes, whitespace, and bad lengths; LoadEcdsa rejects malformed/short coordinates, prefixes, whitespace, empty and all-zero values, and unsupported curves.
  • Standardized failure behavior across all load methods: a failed load clears the object (Empty = true, KeyType = "empty", KeySize = 0, LastMethodSuccess = false) and preserves no previous key.

📦 MIME

  • Convert8Bit — MIME parts using Content-Transfer-Encoding: 8bit or binary are now correctly converted to Base64, keeping the serialized MIME, child Encoding properties, and headers consistent.
  • UrlEncodeBody — URL-encoded text now replaces the existing body instead of being appended; invalid charset names no longer duplicate the body.
  • RemovePart — an out-of-range index returns false and leaves the tree unchanged.
  • SetBodyFromEncoded — improved validation; rejects malformed data and unsupported encodings, preserving existing content on failure.
  • PartsToFiles — the returned StringTable now contains the actual sanitized paths, and no nonexistent paths are added when extraction fails.

🔌 Sockets

  • SoReuseAddr on Linux — the property (default true) was not being applied: SO_REUSEADDR was never set via setsockopt before the internal bind(), so BindAndListen could fail with EADDRINUSE when the port had a socket in TIME_WAIT (e.g. after a server restart). The option is now set prior to binding.
  • ClientPort — now clamped to the valid range 0–65535; out-of-range values leave the property unchanged.

📧 Email — IMAP & MailMan

  • Large UID handling — fixed mailboxes mixing ordinary and very large UIDs, where UID-based searches previously mishandled the large values.
  • Imap.FetchRange — no longer appends an empty Email (with an invalid ckx-imap-uid of 0) when requesting sequence numbers past the end of the mailbox.
  • Imap.QueryMbx with the special new-email criterion — a caller-supplied MessageSet is now cleared when no new messages are found, instead of retaining prior state.
  • Imap.GetMailFlag — now returns -1 when the required ckx-imap-* metadata is missing from the Email.
  • MessageSet — improved, better-defined error handling for FromCompactString, and improved performance for larger id sets.
  • Fixed a crash bug in MailMan.FetchUidlSet.

🧮 JSON, PCRE2, Objective-C

  • JsonObject.StringOfEquals — case-sensitivity was reversed (behavior change). Previously caseSensitive = true compared case-insensitively and vice-versa. Now corrected: true = case-sensitive, false = case-insensitive. If you had compensated for the old behavior, review those calls.
  • PCRE2 — upstream bug fix (present in 10.45/10.46, fixed in 10.47). pcre2_callout_enumerate() crashed with an out-of-bounds read on any pattern containing a Unicode character class (e.g. \p{L}, \d, [[:alpha:]] in Unicode mode). Chilkat’s bundled PCRE2 now uses the corrected offset calculation.
  • Objective-C — 64-bit widening. Several NSNumber-returning functions were widened to correctly represent large 64-bit sizes and counts: ContentLength64, XferByteCount64, GetSize64, GetSizeByName64, UncompressedLength64, CompressedLength64, and FileSize64.

📦 Deprecations

  • Dkim — DomainKeys deprecated. The Dkim class’s DomainKeys-related methods and properties are deprecated. DomainKeys (an older Yahoo protocol) was superseded by DKIM, the standardized protocol used by modern email systems, and should be considered obsolete.
  • Ftp2.DetermineSettings and Ftp2.DetermineProxyMethod are deprecated. These can be replaced with simple examples showing what the methods did internally.

🦀 Chilkat v11.6.1 — Rust: the new chilkat crate

Chilkat for Rust is new in v11.6.1: the chilkat crate on crates.io brings the full Chilkat API — all 99 classes — to Rust, with an API that follows Rust conventions.

Installation

cargo add chilkat

or add chilkat = "11.6" under [dependencies] in Cargo.toml. There is nothing to download by hand: on the first build, the crate’s build script downloads the prebuilt Chilkat static library for the build target from chilkatdownload.com, checks its SHA-256 against the checksums compiled into the crate, caches it in the user cache directory for every later build and project, and links it statically. No C or C++ compiler is needed. For build machines without internet access, set CHILKAT_LIB_DIR to a directory containing the library, and nothing is downloaded. Rust 1.70 or later is required.

Platforms

  • Windows (MSVC): x64, x86, and ARM64. Each package includes the library for both the dynamic CRT (/MD, the default) and the static CRT (/MT, used automatically with -C target-feature=+crt-static).
  • Linux (glibc): x86_64, aarch64, armv7, and i686.
  • Alpine Linux (musl): x86_64, aarch64, armv7, and i686 — including rust:*-alpine Docker images and fully static binaries.
  • macOS: Apple silicon and Intel.

A Rust API

use chilkat::{Http, JsonObject};

fn main() -> chilkat::Result<()> {
    chilkat::unlock_bundle("Anything for 30-day trial")?;

    let http = Http::new();
    let body = http.quick_get_str("https://api.github.com/repos/rust-lang/rust")?;

    let json = JsonObject::new();
    json.load(&body)?;
    println!("{} stars", json.int_of("stargazers_count"));
    Ok(())
}
  • Errors are Results. A method that can fail returns chilkat::Result<T>: Result<()> where other languages return a success/failure bool, and Result<String> or Result<Cert> where they return a string or an object that is null on failure, so ? works as usual. The error carries the object’s LastErrorText from the moment of the failure, along with the class and method names, and implements std::error::Error. Methods that answer a question (HasMember, TagEquals, IsValid, …) return a plain bool.
  • Rust naming. The class names are the same (Http, Zip, JsonObject; CkDateTime is DateTime). Methods are snake_case (QuickGetStr is quick_get_str), and a property AllowGzip is the pair allow_gzip() / set_allow_gzip(..).
  • Ownership. Objects are created with new() and freed when they go out of scope; there is nothing to dispose. Every method takes &self, so an object never needs to be declared mut. Objects are Send, so one can be moved to another thread, but not Sync.
  • Bytes are &[u8] in and Vec<u8> out.
  • Events. AbortCheck, PercentDone, and ProgressInfo are delivered through the chilkat::EventHandler trait (set_event_handler) or through closures (on_percent_done(|pct| ..)). Returning true from abort_check or percent_done aborts the running method.
  • No async. Chilkat calls are synchronous: the *Async methods and the Task and TaskChain classes are not included. From an async runtime, run Chilkat calls on a blocking thread (for example, tokio::task::spawn_blocking).

📝 Scope Chilkat for Rust is a new product; no other Chilkat product is affected. See the Chilkat for Rust page for installation, supported targets, and offline builds, the Rust reference documentation for the Rust signature of every class member, and the Rust examples. The crates are chilkat and chilkat-sys (the low-level declarations the chilkat crate is built on).

🔩 Chilkat v11.6.1 — ActiveX fix

Fixed: methods and properties added in v11.6.0 were not callable from the ActiveX.

A build problem caused a small number of members added in v11.6.0 to be left out of the ActiveX component. Applications calling them received an error such as Object doesn't support this property or method (or a similar “member not found” error, depending on the language). Everything else in v11.6.0 worked normally.

The affected members are now available:

ClassMember
Crypt2Argon2DeriveKey(password, json, bdKey) — method
Crypt2Argon2HashPassword(password, json) — method
Crypt2Argon2VerifyPassword(password, json, phcHash) — method
JsonObjectStrict — property
XmlStrict — property
StringBuilderIsWellFormed(format) — method

📝 Scope This fix affects the ActiveX only — no other Chilkat products are affected, and no application code changes are needed. If you use any of the members above, replace your v11.6.0 ActiveX with v11.6.1 and re-register it. The other changes in v11.6.1 are the Java download repackaging, the Lazarus / Free Pascal fixes, and the Perl, PHP, Ruby, and Tcl updates described next.

☕ Chilkat v11.6.1 — Java: one download per OS/architecture

The separate Java downloads for each JDK version have been replaced by a single download per operating system and CPU architecture.

Previously, Chilkat for Java was offered as a separate package for each JDK release (JDK 8, 11, 17, 21, 25, …), and each new JDK release required a new set of packages. Starting with v11.6.1 there is one package per OS/architecture, and each package works with every JDK from Java 8 up, including future releases. The chilkat.jar is compiled for Java 8 bytecode (so it loads on any later JDK), and the native JNI library uses only the JNI 1.6 interface, which every JDK since Java 6 provides and which later JDKs only extend. Pick the download for the operating system and the architecture of your JVM; the JDK version no longer matters.

  • Windows: chilkat-java-x64, chilkat-java-win32, and chilkat-java-arm64 (Windows on ARM is new in this release).
  • Linux, Alpine Linux, and macOS: chilkatjava-<arch>-linux, chilkatjava-<arch>-alpine, and chilkatjava-<arch>-macosx.
  • Android is unchanged.

📝 Scope This is a packaging change only. The com.chilkatsoft package, class names, and method signatures are identical to v11.6.0, so no application code changes are needed — simply replace the old chilkat.jar and native library with the new ones. JDK 6 and JDK 7 are no longer supported. See the Chilkat for Java download page.

🧡 Chilkat v11.6.1 — Lazarus / Free Pascal fixes

Fixes for the Chilkat for Lazarus/FPC API introduced in v11.6.0.

📂 What changed These are fixes to the .pas source files — the Chilkat.*.pas wrapper units in the Chilkat for Lazarus/FPC download. The C bridge shared libraries (chilkat_c_bridge_*.dll, libchilkat_c_bridge_*.so, libchilkat_c_bridge.dylib) are unchanged. To upgrade, replace the .pas files in your project with those from the v11.6.1 download and rebuild; there is no need to replace the shared library.

.pas files that would not compile

Four of the .pas units failed to compile:

  • Chilkat.Crypt2 — SetIV and SetSecretKey were each declared twice without the overload directive.
  • Chilkat.Gzip — the same problem with SetExtraData.
  • Chilkat.Mcp — CallTool had a parameter named result, which collides with a function’s implicit Result.
  • Chilkat.SFtp — methods taking an SFTP file handle declared two parameters named handle.

In the v11.6.1 .pas files, argument names that collide with a Pascal reserved word, with a type used in the signature, or with an identifier used internally by the wrapper are renamed with an A prefix (result becomes Aresult), and a method name declared more than once in a class carries the overload directive.

“Entry point not found” at program startup

The Chilkat.Crypt2, Chilkat.Dsa, Chilkat.Gzip, Chilkat.HttpResponse, and Chilkat.Xml .pas files declared bridge functions that the Chilkat shared library does not export. Those are resolved in each unit’s initialization section, so any program using one of these units raised Entry point not found before reaching the first line of application code — even though the project compiled cleanly.

The affected members have been removed from the .pas files:

  • The byte-array properties TCrypt2.IV, TCrypt2.Salt, TCrypt2.SecretKey, TDsa.Hash, TDsa.Signature, TGzip.ExtraData, and THttpResponse.Body. Use the encoded-string equivalents instead — SetEncodedIV, SetEncodedKey, SetEncodedSalt, SetEncodedHash, SetEncodedSignature, SetExtraData(encodedData, encoding) — or, for the HTTP response body, GetBodyBd.
  • TXml.SearchForTag, SearchForContent, SearchForAttribute, SearchAllForContent, and their 2 variants.

The reference documentation was updated to match, and no longer lists the removed properties and methods.

✅ Result With the v11.6.1 .pas files, all 99 Chilkat classes compile, load, and instantiate.

🐪 Chilkat v11.6.1 — Perl: New Perl versions, and a slimmer platform matrix

Chilkat for Perl adds support for Perl 5.42 and 5.44, and the 32-bit x86 and armv7l builds have been retired on Linux and Alpine Linux.

String arguments accept any defined scalar

Where a method expects a string, you can now pass any defined Perl scalar and Chilkat uses its string value, exactly as Perl itself would — a number, for example, no longer has to be converted to a string first.

New Perl versions, and a slimmer platform matrix

Chilkat for Perl now builds for Perl 5.42 and 5.44 in addition to the earlier versions, including a 5.42 build for Windows (Strawberry Perl). On Linux, Alpine Linux, and macOS each platform offers both a standard module and a Perl with Threads module (pick the one matching your perl); 64-bit Alpine Linux now offers the Perl with Threads build as well.

The 32-bit downloads have been retired on Linux and Alpine Linux: the x86 (32-bit) and armv7l Perl modules are no longer produced, leaving x86_64 and arm64 on both. Builds for earlier Chilkat versions remain available on the older-versions page.

📝 Scope The Perl API is unchanged — the same chilkat::CkXxx classes and methods — so existing scripts run as-is. To upgrade, replace the Chilkat Perl module (chilkat.pm and its shared library) with the one from the v11.6.1 download for your Perl version and platform. See the Chilkat Perl download page.

🐘 Chilkat v11.6.1 — PHP: A rebuilt extension, one-command installation, and a slimmer platform matrix

The PHP extension has been rebuilt on an improved code generator, a stub file has been added for IDE autocompletion, and the 32-bit Alpine Linux builds have been retired.

A rebuilt extension

The layer that connects PHP to the native Chilkat library — the code that turns a PHP method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, replacing the previous SWIG-based generator. This keeps the PHP extension in step with the rest of the library and makes it easier to maintain and fix.

This is a change of implementation, not of functionality: the same CkXxx classes, the same method names, the same arguments and return values, behaving as they did before. Your scripts still include 'chilkat.php' exactly as before, and no application code changes are needed.

IDE autocompletion

Each download now includes a chilkat_stubs.php file alongside chilkat.php. It declares the same classes and methods with their parameter and return types but no bodies, so editors and IDEs can offer autocompletion, argument hints, and type information as you write. It is for tooling only and is never included at runtime — your scripts continue to include chilkat.php as before.

One-command installation

Installing the PHP extension used to mean choosing the right download for your PHP version, CPU, and thread-safety, finding extension_dir, and editing php.ini. That is now automated in two ways:

Composer. The extension is on Packagist as chilkat/chilkat. The package provides the CkXxx classes through Composer's autoloader (one class per file, so only what a script uses is loaded, with PHPDoc for IDE autocompletion) and a command that installs the native extension for the PHP that runs it:

composer require chilkat/chilkat
vendor/bin/chilkat-install

chilkat-install detects the PHP version, architecture, and thread-safety, downloads the matching build, verifies its SHA-256, places chilkat.so/chilkat.dll in extension_dir, enables it (phpenmod on Debian/Ubuntu, a conf.d entry on Alpine, RHEL, Homebrew and the official Docker images, or php.ini on Windows), and verifies that a fresh PHP loads it. --dry-run shows what would be done, --uninstall reverses it. The package version is the Chilkat version, so the classes and the extension always match, and composer update followed by chilkat-install upgrades both.

Without Composer. The same installer exists as a shell script for Linux, Alpine Linux and macOS, and a PowerShell script for Windows:

curl -fsSL https://chilkatdownload.com/php/install-php.sh | sudo sh
irm https://chilkatdownload.com/php/install-php.ps1 | iex

The manual download-and-configure steps remain on the install pages for anyone who prefers them.

A slimmer platform matrix

The 32-bit Alpine Linux downloads have been retired: the x86 (32-bit) and armv7l Alpine PHP extensions are no longer produced, leaving x86_64 and arm64 on Alpine Linux. The 32-bit x86 and armv7l builds for standard (glibc) Linux are unchanged. Builds for earlier Chilkat versions remain available on the older-versions page.

📝 Scope The PHP API is unchanged — the same CkXxx classes and methods — so existing scripts run as-is. To upgrade, run composer update chilkat/chilkat && vendor/bin/chilkat-install, re-run the install script, or replace the Chilkat PHP files (chilkat.php and the extension, chilkat.dll or chilkat.so) with those from the v11.6.1 download for your PHP version and platform. See the Chilkat PHP download page.

🐍 Chilkat v11.6.1 — Python (CkPython): A rebuilt extension, one download for every Python 3.7+, and Windows ARM64

The CkPython extension (the chilkat module) has been rebuilt on an improved code generator and now targets the CPython stable ABI, so one download per platform works with every Python from 3.7 onward. Windows ARM64 is new; Python 3.6 and earlier, and the 32-bit x86 and armv7l Alpine builds, have been retired.

A rebuilt extension

The layer that connects Python to the native Chilkat library — the code that turns a Python method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, replacing the previous SWIG-based generator. This keeps the Python extension in step with the rest of the library and makes it easier to maintain and fix.

This is a change of implementation, not of functionality: the same CkXxx classes, the same method names, the same arguments and return values, the same ownership rules for returned objects, the same overridable progress classes (CkBaseProgress, CkHttpProgress, …) and the same error messages. Your scripts still import chilkat exactly as before, and no application code changes are needed.

One download works with every Python from 3.7 onward

Until now each Chilkat Python download was built for exactly one Python version — a separate package for 3.12, 3.13, 3.14, and so on, per operating system and processor — and a new Python release meant waiting for a matching Chilkat build. The v11.6.1 extension is built against the CPython stable ABI (the limited API of Python 3.7), so a single _chilkat.pyd or _chilkat.so loads into any CPython from 3.7 on, including versions released after the build.

The download names no longer carry a Python version: chilkat-python-x64.zip, chilkat-python-x86_64-linux.tar.gz, chilkat-python-arm64-macosx.tar.gz, and so on — one per operating system and processor. installChilkat.py copies the module into the site-packages of whichever Python runs it, so the same download can be installed into several Python versions on one machine. On PyPI, pip install chilkat now installs a single cp37-abi3 wheel per platform instead of one wheel per Python version.

Platforms

  • New: Windows ARM64. A native build for an ARM64 Python on Windows on ARM (chilkat-python-arm64). An x64 Python running under emulation continues to use the 64-bit build.
  • Retired: Python 3.6 and earlier, including Python 2.7. The stable-ABI module requires Python 3.7 or later. The last builds for older Pythons (Chilkat v11.6.0) remain available at their existing download links but receive no further updates.
  • Retired: 32-bit x86 Linux, 32-bit x86 Alpine Linux, and armv7l Alpine Linux. The remaining platforms are Windows (x64, win32, ARM64), Linux (x86_64, aarch64, armv7l — the 32-bit ARM build for Raspberry Pi stays), Alpine Linux (x86_64, aarch64), and macOS (Apple silicon, Intel).

Fixes

  • The 64-bit event parameters — the byte counts in UploadRate and DownloadRate, and the sizes in NextTarFile — are now passed correctly on 64-bit Linux, where these events previously did not reach the Python handler.
  • CkByteData.getRange now returns the requested range rather than the data from the start.
  • CkBinData.GetDataChunk is clamped to the buffer, and CkBinData.AppendData accepts only bytes-like data, with the length clamped to the object passed, instead of reading past it.
  • A progress object passed to put_EventCallbackObject is now kept alive by the Chilkat object for as long as it may be called back. Previously a script that dropped its own reference could have events delivered to a freed object.
  • The result of __disown__() can be passed directly to put_EventCallbackObject, as in the SWIG-era examples.
  • The module no longer exports the library’s internal symbols: the files are smaller and import faster.

📝 Scope The Python API is unchanged — the same chilkat.CkXxx classes and methods — so existing scripts run as-is on Python 3.7 or later. To upgrade, run pip install --upgrade chilkat, or replace chilkat.py and the extension (_chilkat.pyd or _chilkat.so) with those from the v11.6.1 download for your platform — there is no longer a separate download per Python version. See the Chilkat Python download page.

Chilkat v11.6.1 — Ruby: A rebuilt extension, and Ruby 3.2 retired

The Ruby extension has been rebuilt on an improved code generator, and Ruby 3.2 has been retired.

A rebuilt extension

The layer that connects Ruby to the native Chilkat shared library — the code that turns a Ruby method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, which keeps the Ruby extension in step with the rest of the library and makes it easier to maintain and fix.

This is a change of implementation, not of functionality: the same classes, the same method names, the same arguments and return values, behaving as they did before. No application code changes are needed.

Ruby versions

Chilkat for Ruby builds for Ruby 3.3, 3.4, and 4.0. Ruby 3.2 reached end-of-life in April 2026 and its downloads have been retired; builds for earlier Chilkat versions remain available on the older-versions page.

📝 Scope The Ruby API is unchanged — the same Chilkat::CkXxx classes and methods — so existing scripts run as-is. To upgrade, install the v11.6.1 gem for your Ruby version and platform. See the Chilkat Ruby download page.

📜 Chilkat v11.6.1 — Tcl: Tcl 9.0 on Windows, and UTF-8 by default

Tcl 9.0 is now available for Windows, a Windows download now works with any distribution of its Tcl line, and non-ASCII text no longer needs extra setup.

Chilkat for Tcl already offered Tcl 9.0 builds for Linux, macOS, and Alpine Linux. v11.6.1 adds a Tcl 9.0 build for 64-bit Windows, so both the Tcl 8.6 and Tcl 9.0 lines are now available on every supported platform.

Windows: one download per Tcl line and CPU architecture

32-bit and 64-bit are still separate downloads, as they must be — a 32-bit tclsh can only load a 32-bit DLL, and a 64-bit one only a 64-bit DLL. What changed is that 64-bit Tcl 8.6 no longer needs two of them.

Windows Tcl distributions disagree about what the core library is called: some ship tcl86.dll and others tcl86t.dll, so Chilkat published chilkat-tcl8.6-x64 for the first and a second package, chilkat-tcl8.6.7-x64, for the other. The v11.6.1 extension binds to whichever interpreter loads it rather than to a particular core library file name, so one chilkat-tcl8.6-x64 now works with any Tcl 8.6 distribution, including future patch releases. chilkat-tcl8.6.7-x64 has been removed.

  • Windows: chilkat-tcl9.0-x64 (new in v11.6.1), chilkat-tcl8.6-x64, and chilkat-tcl8.6-win32. Tcl 9.0 on Windows is 64-bit only.
  • Linux, Alpine Linux, and macOS: unchanged — Tcl 8.6 and Tcl 9.0 builds for each architecture.

Strings are UTF-8 by default

Tcl passes strings to an extension as UTF-8, but Chilkat objects used to start with the Utf8 property turned off, so a script had to turn it on itself — on each object, or once through the global default:

set http [new_CkHttp]
CkHttp_put_Utf8 $http 1        ;# no longer necessary

Leaving it out silently corrupted any text outside the ASCII range. In v11.6.1 every Chilkat object is created with Utf8 already on, which is the correct setting for Tcl. Scripts that set it themselves keep working — the call is simply redundant now — and ASCII-only scripts are unaffected.

📝 Scope The Tcl command set is unchanged — the same command names taking the same arguments — so existing scripts run as-is. To upgrade, replace the Chilkat shared library (chilkat.dll, chilkat.so, or chilkat.dylib) with the one from the v11.6.1 download for your Tcl version and platform. Tcl 8.4 and Tcl 8.5 are no longer supported — the minimum is Tcl 8.6. See the Chilkat Tcl download page.

For previous versions and archived updates, visit the Release Notes Archive.