Repository navigation
docs: explain Miftah 0.5 features and workflows (#40) #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| # What is in Miftah 0.5 | ||
|
|
||
| Install `@lubab/miftah@0.5.0` when you want Miftah to guide setup instead of assembling a multi-account configuration by hand: | ||
|
|
||
| ```bash | ||
| npm install -g @lubab/miftah@0.5.0 | ||
| miftah version | ||
| ``` | ||
|
|
||
| The short version of 0.5.0 compared with 0.4.0 is: Miftah now has guided and resumable setup, safer setup previews, account-profile maintenance commands, client-entry import, and a complete multi-account Google Search Console onboarding path. | ||
|
|
||
| Native OAuth and the optional Console first shipped in 0.4.0. 0.5.0 makes them easier to discover, configure, and maintain; it does not introduce universal OAuth support or a hosted Miftah service. | ||
|
|
||
| ## The 60-second feature map | ||
|
|
||
| | What you want to do | What 0.5 adds | Start here | | ||
| | --- | --- | --- | | ||
| | Create a configuration from what you already have | An outcome-first wizard for a known connector, remote HTTPS MCP, local executable, browser sign-in, or one existing client entry | `miftah setup` | | ||
| | Review setup before writing | A non-secret, no-write structural plan | `miftah setup --plan` with the complete inputs for your setup path | | ||
| | Continue an interrupted setup choice | A private, bounded checkpoint that stores no URL, path, command, credential, or browser state | `miftah setup --resume`, or `miftah setup --discard-draft` | | ||
| | Add another supported account | Guarded profile addition for the reviewed Google Search Console adapter or a narrow local environment-backed configuration | `miftah setup --add-profile` | | ||
| | See and maintain configured accounts | List, change the durable default, describe, rename, remove, or safely test one profile | `miftah profile list --config CONFIG_FILE` | | ||
| | Use the browser instead of the terminal wizard | The same reviewed first-run and account-management paths in the foreground local Console | `miftah dashboard` | | ||
|
|
||
| ## 1. Start with the guided setup | ||
|
|
||
| Run: | ||
|
|
||
| ```bash | ||
| miftah setup | ||
| ``` | ||
|
|
||
| The wizard asks what you already have: | ||
|
|
||
| - **connector** — a reviewed built-in connector or exact-pinned package; | ||
| - **remote HTTPS** — a strict Streamable HTTP endpoint without contacting it during generic setup; | ||
| - **local executable** — one literal executable plus argument array, with no shell; | ||
| - **browser sign-in** — a remote HTTPS MCP that advertises Miftah's supported standards-based OAuth flow; | ||
| - **import** — one explicitly selected entry from one existing client JSON file. | ||
|
|
||
| The wizard asks for environment-variable names and non-secret metadata, not token or password values. It validates the complete candidate before publication and prints client configuration for manual review. Miftah does not silently edit Claude Desktop, Claude Code, Cursor, or VS Code. | ||
|
|
||
| After merging the generated client entry, restart the MCP client. A running client process does not automatically adopt configuration or profile changes made later. | ||
|
|
||
| ## 2. Preview a complete setup without writing | ||
|
|
||
| For example, this Google Search Console plan is safe to paste even before the referenced client-secrets file exists: | ||
|
|
||
| ```bash | ||
| miftah setup gsc --preset google-search-console \ | ||
| --oauth-client-secrets-file "$HOME/.config/gsc/client-secrets.json" \ | ||
| --output "$HOME/.config/miftah/gsc.json" \ | ||
| --plan | ||
| ``` | ||
|
|
||
| The plan does not write a configuration or start an upstream. It can identify the requested publication target, but its configuration summary omits credential paths, endpoints, launch arguments, credential references, OAuth details, and secret values. | ||
|
|
||
| When the real inputs are ready, repeat the command without `--plan` to create the new file. Add `--verify` only when you want a reviewed adapter's declared read-only readiness check to run after publication. | ||
|
|
||
| If interactive setup stops after saving its bounded connector choice, continue with: | ||
|
|
||
| ```bash | ||
| miftah setup --resume | ||
| ``` | ||
|
|
||
| Discard that saved choice without creating a configuration with: | ||
|
|
||
| ```bash | ||
| miftah setup --discard-draft | ||
| ``` | ||
|
|
||
| All connection details must be entered again after resume; the checkpoint does not store them. | ||
|
|
||
| ## 3. Import one existing client entry | ||
|
|
||
| Choose **import** in `miftah setup`, provide one absolute client JSON path, and select one listed entry. Miftah displays entry names only. It does not print the source command, arguments, environment values, headers, or credentials, and it never modifies the source client file. | ||
|
|
||
| The import path accepts only a supported local STDIO entry or a credential-free HTTPS remote entry. It does not guess authentication ownership. Use `--import-file` and `--import-entry` for the equivalent explicit noninteractive path; review it first with `--plan`. | ||
|
|
||
| ## 4. Set up and maintain multiple Google accounts | ||
|
|
||
| Google Search Console is the reviewed provider-adapter example in 0.5: | ||
|
|
||
| ```bash | ||
| miftah setup gsc --preset google-search-console | ||
| ``` | ||
|
|
||
| The guided flow collects each profile name and asks which profile should be the durable default. Every generated configuration/profile pair receives a distinct `GSC_CONFIG_DIR`. The `mcp-search-console` upstream owns browser login, refresh, reauthentication, revocation, and the token cache inside that directory. Miftah never reads or copies the upstream-owned token cache. | ||
|
|
||
| Add a returning account to an existing reviewed configuration with: | ||
|
|
||
| ```bash | ||
| miftah setup --add-profile \ | ||
| --config "$HOME/.config/miftah/gsc.json" \ | ||
| --profile google-personal \ | ||
| --oauth-client-secrets-file "$HOME/.config/gsc/personal-client-secrets.json" \ | ||
| --verify | ||
| ``` | ||
|
|
||
| This is a configuration mutation, not a preview. It adds one isolated profile through the reviewed adapter contract, records a redacted lifecycle event, and runs only the declared `get_capabilities` readiness probe when `--verify` is present. That probe is health evidence; it does not prove the authorized Google account or property. | ||
|
|
||
| Read the [provider-adapter guide](provider-adapters.md) for prerequisites, service-account alternatives, cache ownership, and recovery. | ||
|
|
||
| ## 5. Inspect and maintain account profiles | ||
|
|
||
| Use `CONFIG_FILE`, `PROFILE_NAME`, and the other uppercase values below as literal safe placeholders until you substitute your reviewed values: | ||
|
|
||
| | Task | Command | | ||
| | --- | --- | | ||
| | List non-secret profile metadata | `miftah profile list --config CONFIG_FILE` | | ||
| | Change the durable default for future sessions | `miftah profile set-default --config CONFIG_FILE --profile PROFILE_NAME` | | ||
| | Add a non-secret description | `miftah profile set-description --config CONFIG_FILE --profile PROFILE_NAME --description DESCRIPTION_TEXT` | | ||
| | Rename a profile and its configuration-owned references | `miftah profile rename --config CONFIG_FILE --profile PROFILE_NAME --new-profile NEW_PROFILE_NAME` | | ||
| | Remove a profile and reassign durable references | `miftah profile remove --config CONFIG_FILE --profile PROFILE_NAME --replacement-profile REPLACEMENT_PROFILE` | | ||
| | Run one adapter-declared read-only readiness check | `miftah profile test --config CONFIG_FILE --profile PROFILE_NAME` | | ||
|
|
||
| `list` does not resolve credentials or start an upstream. The configuration-changing commands validate first, use guarded replacement and recovery backup behavior, and preserve the documented credential and provider-cache boundaries. Profile changes affect future MCP sessions; restart the MCP client when you need a new session to observe them. | ||
|
|
||
| ## 6. Pick the correct authentication owner | ||
|
|
||
| | Authentication path | What Miftah owns | Where to begin | | ||
| | --- | --- | --- | | ||
| | API key or secret reference | Resolving a configured profile-scoped reference and redacting the value | Run `miftah setup` and provide an environment-variable name or another supported secret reference. | | ||
| | Native OAuth | Supported remote discovery, browser authorization, OS-vault storage, refresh, reauth, and exact local disconnect | Use `miftah setup --native-oauth` only with a real HTTPS MCP endpoint that satisfies the documented standards. | | ||
| | upstream-owned OAuth | Passing reviewed configuration to the upstream while leaving its browser and cache lifecycle alone | Use a reviewed adapter such as Google Search Console and follow its upstream login. | | ||
|
|
||
| Miftah does not support OAuth for every MCP server or provider. A successful login, resolvable credential, or profile label is not proof of scopes or account identity. See the [OAuth guide](oauth-support.md) for native connection lifecycle commands and the exact support matrix. | ||
|
|
||
| ## 7. Use the optional local Console | ||
|
|
||
| Run: | ||
|
|
||
| ```bash | ||
| miftah dashboard | ||
| ``` | ||
|
|
||
| The Console is a foreground, literal-loopback browser UI for reviewed setup, profile maintenance, connection health, and supported OAuth lifecycle work. It is optional, does not run as a daemon, never exposes raw credentials, and cannot take over an already-running MCP client session. | ||
|
|
||
| Use `miftah dashboard --no-open` when you want the local URL printed without opening a browser. See the [Console guide](console-api.md) for its one-use bootstrap and authenticated local-control boundary. | ||
|
|
||
| ## Reliability and security changes in 0.5 | ||
|
|
||
| The release also: | ||
|
|
||
| - refuses Windows STDIO command shims and shell executables instead of silently falling back to `cmd.exe`; | ||
| - patches the MCP SDK/Hono runtime dependency chain and scoped development-toolchain advisories; | ||
| - hardens Windows configuration identity and Console ACL checks; | ||
| - improves macOS OAuth locking, audit locking, and bounded upstream process-tree cleanup. | ||
|
|
||
| These changes do not weaken redaction, audit finalization, Windows ACL verification, process containment, or existing timeouts. See the [full changelog](../CHANGELOG.md) for the issue-by-issue details. | ||
|
|
||
| ## Upgrade and validation | ||
|
|
||
| Version 0.4 already wrote configuration format v3, so a normal 0.4 configuration does not need a format change merely because the package becomes 0.5. Validate the exact file and its runtime readiness after upgrading: | ||
|
|
||
| ```bash | ||
| miftah validate --config "$HOME/.config/miftah/miftah.json" | ||
| miftah doctor --config "$HOME/.config/miftah/miftah.json" | ||
| ``` | ||
|
|
||
| If your configuration is still v1 or v2, use the dry-run-first migration path in the [CLI reference](cli.md) rather than editing version fields by hand. | ||
|
|
||
| ## What remains intentionally incomplete | ||
|
|
||
| - External multi-account and returning-user validation is still open in [#25](https://github.com/mohanagy/miftah/issues/25) and [#88](https://github.com/mohanagy/miftah/issues/88). | ||
| - Miftah is experimental and pre-1.0; minor releases can contain documented incompatible changes. | ||
| - Native OAuth is deliberately narrow. Provider-specific and local OAuth often remains upstream-owned. | ||
| - Miftah cannot prove an account identity unless the selected upstream exposes stable, bounded identity evidence. | ||
| - Generated client snippets are manual handoff artifacts. Miftah does not silently edit client settings or replace a running MCP session. | ||
|
|
||
| For every command and option, use the [CLI reference](cli.md). For the product model and first working connector, return to the [README](../README.md). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| import { existsSync, readFileSync } from "node:fs"; | ||
| import { describe, expect, it } from "vitest"; | ||
| import { CLI_COMMANDS, renderCommandHelp, type CliCommand } from "../src/cli/parse.js"; | ||
|
|
||
| const guideUrl = new URL("../docs/whats-new-in-0.5.md", import.meta.url); | ||
| const readme = readFileSync(new URL("../README.md", import.meta.url), "utf8"); | ||
| const changelog = readFileSync(new URL("../CHANGELOG.md", import.meta.url), "utf8"); | ||
| const packageManifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as { | ||
| version: string; | ||
| }; | ||
|
|
||
| function readGuide(): string { | ||
| return existsSync(guideUrl) ? readFileSync(guideUrl, "utf8") : ""; | ||
| } | ||
|
|
||
| function documentedMiftahCommands(markdown: string): string[] { | ||
| const bashBlocks = [...markdown.matchAll(/```bash\n([\s\S]*?)```/gu)].map((match) => match[1]!); | ||
| const fencedCommands = bashBlocks.flatMap((block) => | ||
| block | ||
| .replace(/\\\n\s*/gu, " ") | ||
| .split("\n") | ||
| .map((line) => line.trim()) | ||
| .filter((line) => line.startsWith("miftah ")) | ||
| ); | ||
| const inlineCommands = [...markdown.matchAll(/`(miftah [^`\n]+)`/gu)].map((match) => match[1]!); | ||
| return [...new Set([...fencedCommands, ...inlineCommands])]; | ||
| } | ||
|
|
||
| describe("Miftah 0.5 owner guide", () => { | ||
| it("publishes a linked, release-aligned explanation of the product delta", () => { | ||
| const guide = readGuide(); | ||
|
|
||
| expect(guide).not.toBe(""); | ||
| expect(guide.split("\n").length).toBeLessThanOrEqual(220); | ||
| expect(guide).toContain("# What is in Miftah 0.5"); | ||
| expect(guide).toContain(`Install \`@lubab/miftah@${packageManifest.version}\``); | ||
| expect(guide).toContain("0.5.0 compared with 0.4.0"); | ||
| expect(guide).toContain("guided and resumable setup"); | ||
| expect(guide).toContain("Native OAuth and the optional Console first shipped in 0.4.0"); | ||
| expect(guide).toContain("0.5.0 makes them easier to discover, configure, and maintain"); | ||
| expect(readme.split("\n").slice(0, 80).join("\n")).toContain( | ||
| "[What is in 0.5 and how to use it](docs/whats-new-in-0.5.md)" | ||
| ); | ||
| }); | ||
|
|
||
| it("maps the main 0.5 outcomes to exact safe starting commands", () => { | ||
| const guide = readGuide(); | ||
|
|
||
| for (const text of [ | ||
| "miftah setup", | ||
| "miftah setup gsc --preset google-search-console", | ||
| "--plan", | ||
| "--resume", | ||
| "--discard-draft", | ||
| "--import-file", | ||
| "--import-entry", | ||
| "miftah dashboard", | ||
| "miftah setup --add-profile", | ||
| "miftah profile list", | ||
| "miftah profile set-default", | ||
| "miftah profile set-description", | ||
| "miftah profile rename", | ||
| "miftah profile remove", | ||
| "miftah profile test" | ||
| ]) { | ||
| expect(guide).toContain(text); | ||
| } | ||
|
|
||
| expect(guide).toContain("The plan does not write a configuration or start an upstream."); | ||
| expect(guide).toContain("Miftah never reads or copies the upstream-owned token cache."); | ||
| }); | ||
|
|
||
| it("keeps the authentication, active-session, and validation boundaries honest", () => { | ||
| const guide = readGuide(); | ||
|
|
||
| expect(guide).toContain("Miftah does not support OAuth for every MCP server or provider."); | ||
| expect(guide).toContain("Native OAuth"); | ||
| expect(guide).toContain("upstream-owned OAuth"); | ||
| expect(guide).toContain("API key or secret reference"); | ||
| expect(guide).toContain("restart the MCP client"); | ||
| expect(guide).toContain("External multi-account and returning-user validation is still open"); | ||
| expect(guide).toContain("[#25]"); | ||
| expect(guide).toContain("[#88]"); | ||
| expect(guide).toContain("[CLI reference](cli.md)"); | ||
| expect(guide).toContain("[OAuth guide](oauth-support.md)"); | ||
| expect(guide).toContain("[provider-adapter guide](provider-adapters.md)"); | ||
| expect(guide).toContain("[full changelog](../CHANGELOG.md)"); | ||
| }); | ||
|
|
||
| it("binds every documented Miftah command and flag to generated CLI help", () => { | ||
| const commands = documentedMiftahCommands(readGuide()); | ||
| expect(commands.length).toBeGreaterThan(5); | ||
|
|
||
| for (const line of commands) { | ||
| const match = /^miftah\s+([a-z][a-z-]*)(?:\s+([a-z][a-z-]*))?/u.exec(line); | ||
| expect(match, `could not parse guide command: ${line}`).not.toBeNull(); | ||
| const primary = match![1]!; | ||
| const command = (primary === "connection" || primary === "auth" || primary === "profile" | ||
| ? `${primary} ${match![2]}` | ||
| : primary) as CliCommand; | ||
| expect(Object.keys(CLI_COMMANDS), `unknown guide command: ${command}`).toContain(command); | ||
| const supportedFlags = new Set(renderCommandHelp(command).match(/--[a-z][a-z-]*/gu) ?? []); | ||
| for (const flag of [...line.matchAll(/(?:^|\s)(--[a-z][a-z-]*)/gu)].map((flagMatch) => flagMatch[1]!)) { | ||
| expect(supportedFlags, `unsupported guide flag for ${command}: ${flag}`).toContain(flag); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| it("keeps fenced commands paste-safe and records the guide under issue 40", () => { | ||
| const guide = readGuide(); | ||
| const bashBlocks = [...guide.matchAll(/```bash\n([\s\S]*?)```/gu)].map((match) => match[1]!); | ||
|
|
||
| for (const block of bashBlocks) { | ||
| expect(block).not.toMatch(/[<>]/u); | ||
| } | ||
| expect(guide).not.toContain("oauthconn:<uuid>"); | ||
| expect(changelog).toContain("[#40](https://github.com/mohanagy/miftah/issues/40)"); | ||
| expect(changelog).toContain("Added an owner-readable Miftah 0.5 feature and usage guide"); | ||
| }); | ||
|
|
||
| it("keeps every local guide link resolvable", () => { | ||
| const links = [...readGuide().matchAll(/\[[^\]]+\]\(([^)]+)\)/gu)].map((match) => match[1]!); | ||
|
|
||
| for (const link of links) { | ||
| if (/^(?:https?:|mailto:)/u.test(link)) continue; | ||
| const path = link.split("#", 1)[0]!; | ||
| const target = new URL(path, guideUrl); | ||
| expect(existsSync(target), `missing guide link target: ${link}`).toBe(true); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| }); | ||
| }); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.