Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format

## [Unreleased]

## [1.1.1] - 2026-08-12

### Changed

- [#399](https://github.com/mohanagy/miftah/issues/399) Prepared the compatible v1.1.1 patch release for Claude Desktop tool-catalog compatibility. Publication remains gated on exact `development`-to-`main` promotion and protected OIDC trusted publishing, registry provenance, a fresh install, and package-signature verification.

### Fixed

- [#397](https://github.com/mohanagy/miftah/issues/397) Preserved valid JSON Schema objects when tool input names look credential-related, so Vercel and Firebase catalogs no longer fail MCP client validation after redaction. Client-visible schema-valued `true` is emitted as its equivalent `{}` form for Claude Desktop proxy compatibility, while `false` constraints, ordinary boolean values, configured-secret redaction, bearer redaction, and provider-token redaction remain unchanged.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Install Miftah, then choose the terminal wizard or the browser Console. Both use
### 1. Install the current release

```bash
npm install -g @lubab/miftah@1.1.0
npm install -g @lubab/miftah@1.1.1
miftah version
```

Expand Down
2 changes: 1 addition & 1 deletion docs/mcp-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This page is the compatibility source of truth for Miftah's downstream MCP server. It records protocol-era behavior separately from generated client-configuration support and from upstream MCP transport support. A generated snippet proves only that Miftah emitted the documented JSON shape; it does not prove that an untested host completed a protocol exchange.

- Miftah baseline: `1.1.0`
- Miftah baseline: `1.1.1`
- Locked MCP TypeScript packages: `@modelcontextprotocol/client`, `core`, `server`, `node`, and `server-legacy` `2.0.0`
- Evidence date: 2026-08-12
- Modern protocol era: `2026-07-28`
Expand Down
2 changes: 1 addition & 1 deletion docs/presets-and-clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This is the compatibility source of truth for generated `miftah init` configurat
For downstream protocol eras and real packaged-host evidence, see [MCP protocol and client compatibility](mcp-compatibility.md). The tables below validate generated configuration shapes; they do not by themselves establish a runtime exchange with Claude Desktop, Claude Code, Cursor, or VS Code.

- Catalog version: `3`
- Miftah package version: `1.1.0`
- Miftah package version: `1.1.1`
- Last tested / validation boundary: the catalog builds strict Miftah configuration that `validateConfig` accepts. The docs contract test checks generated configuration only; it does **not** construct a runtime, start, authenticate to, or smoke-test external providers.

Miftah itself requires Node.js `>=20`. That does not establish an upstream server's Node requirement.
Expand Down
4 changes: 2 additions & 2 deletions docs/whats-new-in-0.5.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# What is in Miftah 0.5

Install `@lubab/miftah@1.1.0`, the current stable release, to use the guided setup and account-management capabilities introduced in 0.5 instead of assembling a multi-account configuration by hand:
Install `@lubab/miftah@1.1.1`, the current stable release, to use the guided setup and account-management capabilities introduced in 0.5 instead of assembling a multi-account configuration by hand:

```bash
npm install -g @lubab/miftah@1.1.0
npm install -g @lubab/miftah@1.1.1
miftah version
```

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lubab/miftah",
"version": "1.1.0",
"version": "1.1.1",
"description": "Wrap any MCP. Use the right account without reconnecting.",
"keywords": [
"mcp",
Expand Down
17 changes: 8 additions & 9 deletions tests/authenticated-request-context-docs-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest";

const libraryApiPath = fileURLToPath(new URL("../docs/library-api.md", import.meta.url));
const changelogPath = fileURLToPath(new URL("../CHANGELOG.md", import.meta.url));
const packageManifestPath = fileURLToPath(new URL("../package.json", import.meta.url));
const protocolReleaseVersion = "1.1.0";

describe("authenticated request-context documentation contract", () => {
it("documents the trusted host boundary and the no-fallback compatibility path", async () => {
Expand All @@ -19,19 +19,18 @@ describe("authenticated request-context documentation contract", () => {
expect(documentation).toContain("does not synthesize verified per-chat claims");
});

it("records the additive security boundary under the package release", async () => {
it("records the additive security boundary under the v1.1.0 protocol release", async () => {
const changelog = await readFile(changelogPath, "utf8");
const manifest = JSON.parse(await readFile(packageManifestPath, "utf8")) as { version: string };
const escapedVersion = manifest.version.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
const escapedVersion = protocolReleaseVersion.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
const heading = changelog.match(new RegExp(`^## \\[${escapedVersion}\\] - \\d{4}-\\d{2}-\\d{2}$`, "mu"));
expect(heading?.index).toBeTypeOf("number");
const releaseStart = heading?.index ?? 0;
const releaseEnd = changelog.indexOf("\n## ", releaseStart + (heading?.[0].length ?? 0));
const currentRelease = changelog.slice(releaseStart, releaseEnd < 0 ? undefined : releaseEnd);
const protocolRelease = changelog.slice(releaseStart, releaseEnd < 0 ? undefined : releaseEnd);

expect(currentRelease).toContain("[#376]");
expect(currentRelease).toContain("for modern stateless handling");
expect(currentRelease).toContain("never falls back to MCP `clientInfo`");
expect(currentRelease).toContain("embedding hosts supply them through the public server factory");
expect(protocolRelease).toContain("[#376]");
expect(protocolRelease).toContain("for modern stateless handling");
expect(protocolRelease).toContain("never falls back to MCP `clientInfo`");
expect(protocolRelease).toContain("embedding hosts supply them through the public server factory");
});
});
13 changes: 6 additions & 7 deletions tests/profile-context-handle-docs-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest";

const libraryApiPath = fileURLToPath(new URL("../docs/library-api.md", import.meta.url));
const changelogPath = fileURLToPath(new URL("../CHANGELOG.md", import.meta.url));
const packageManifestPath = fileURLToPath(new URL("../package.json", import.meta.url));
const protocolReleaseVersion = "1.1.0";

describe("profile-context handle documentation contract", () => {
it("documents the trusted modern host and deployment-wide fail-closed boundary", async () => {
Expand All @@ -22,16 +22,15 @@ describe("profile-context handle documentation contract", () => {

it("records the production boundary alongside protocol negotiation", async () => {
const changelog = await readFile(changelogPath, "utf8");
const manifest = JSON.parse(await readFile(packageManifestPath, "utf8")) as { version: string };
const escapedVersion = manifest.version.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
const escapedVersion = protocolReleaseVersion.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
const heading = changelog.match(new RegExp(`^## \\[${escapedVersion}\\] - \\d{4}-\\d{2}-\\d{2}$`, "mu"));
expect(heading?.index).toBeTypeOf("number");
const releaseStart = heading?.index ?? 0;
const releaseEnd = changelog.indexOf("\n## ", releaseStart + (heading?.[0].length ?? 0));
const currentRelease = changelog.slice(releaseStart, releaseEnd < 0 ? undefined : releaseEnd);
const protocolRelease = changelog.slice(releaseStart, releaseEnd < 0 ? undefined : releaseEnd);

expect(currentRelease).toContain("[#377]");
expect(currentRelease).toContain("opt-in production profile-context boundary");
expect(currentRelease).toContain("an embedding host enables the boundary through `createMiftahServerFactory`");
expect(protocolRelease).toContain("[#377]");
expect(protocolRelease).toContain("opt-in production profile-context boundary");
expect(protocolRelease).toContain("an embedding host enables the boundary through `createMiftahServerFactory`");
});
});
17 changes: 8 additions & 9 deletions tests/release-version.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";

const releaseVersion = "1.1.0";
const releaseVersion = "1.1.1";

function readRepositoryFile(path: string): string {
return readFileSync(new URL(`../${path}`, import.meta.url), "utf8");
Expand All @@ -21,15 +21,15 @@ function releaseNotes(changelog: string, version: string): string {
return changelog.slice(match.index, end < 0 ? undefined : end);
}

describe("v1.1.0 release artifacts", () => {
describe("v1.1.1 release artifacts", () => {
it.each([
{
name: "a non-zero-padded date",
changelog: "## [1.1.0] - 2026-8-12\n\n### Changed\n"
changelog: "## [1.1.1] - 2026-8-12\n\n### Changed\n"
},
{
name: "a heading that does not start its line",
changelog: "Release candidate: ## [1.1.0] - 2026-08-12\n\n### Changed\n"
changelog: "Release candidate: ## [1.1.1] - 2026-08-12\n\n### Changed\n"
}
])("rejects $name", ({ changelog }) => {
expect(() => releaseNotes(changelog, releaseVersion)).toThrow(
Expand Down Expand Up @@ -71,18 +71,17 @@ describe("v1.1.0 release artifacts", () => {
}
});

it("documents the v1.1 MCP compatibility release and its evidence boundary", () => {
it("documents the v1.1.1 Claude compatibility patch and its evidence boundary", () => {
const changelog = readRepositoryFile("CHANGELOG.md");
const notes = releaseNotes(changelog, releaseVersion);

expect(notes).toContain("### Added");
expect(notes).toContain("### Changed");
expect(notes).toContain("### Fixed");
expect(notes).toContain("### Security");
for (const issue of [363, 365, 366, 367, 368, 376, 377, 391, 393]) {
for (const issue of [397, 399]) {
expect(notes).toContain(`[#${issue}](https://github.com/mohanagy/miftah/issues/${issue})`);
}
expect(notes).toContain("named desktop-host claims remain explicitly unverified");
expect(notes).toContain("Claude Desktop tool-catalog compatibility");
expect(notes).toContain("schema-valued `true`");
expect(notes).toContain("protected OIDC trusted publishing");
expect(notes).toContain("registry provenance");

Expand Down