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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. The format

### Added

- [#204](https://github.com/mohanagy/miftah/issues/204) Added guided multi-account Google Search Console onboarding through the CLI and local Console, including an explicit opt-in first-success check that resolves only the selected target, verifies audit/policy/identity boundaries before its one declared read-only probe, and cancels with the requesting Console session. The check trusts only the catalog's reviewed launch envelope and fails closed without launching a process after execution-affecting customization. It creates named profiles with an explicit durable default and separate upstream-owned OAuth state directories per generated configuration file and profile, while continuing to keep browser login, token-cache contents, reauthentication, revocation, and account identity verification outside Miftah. A returning provider-owned account can now be added atomically through the reviewed adapter contract in either CLI or Console, with a fresh isolated state directory, a redacted fail-closed lifecycle record, and no token-cache access. It also adds explicitly acknowledged local STDIO setup and client-entry import: literal executable plus bounded argument array, no shell, no secret-shaped values, no generic-command launch during onboarding, read-only default policy, destructive handling for unknown tools, and Windows-only direct absolute `.exe`/`.com` requirements to avoid a command-shell fallback.
- [#204](https://github.com/mohanagy/miftah/issues/204) Added guided multi-account Google Search Console onboarding through the CLI and local Console, including an explicit opt-in first-success check that resolves only the selected target, verifies audit/policy/identity boundaries before its one declared read-only probe, and cancels with the requesting Console session. The check trusts only the catalog's reviewed launch envelope and fails closed without launching a process after execution-affecting customization. It creates named profiles with an explicit durable default and separate upstream-owned OAuth state directories per generated configuration file and profile, while continuing to keep browser login, token-cache contents, reauthentication, revocation, and account identity verification outside Miftah. A returning provider-owned account can now be added atomically through the reviewed adapter contract in either CLI or Console, with a fresh isolated state directory, a redacted fail-closed lifecycle record, and no token-cache access. It also adds a separate returning-user path for a simple local STDIO environment credential binding: CLI and Console accept a variable name rather than a secret, require every existing profile to share the same narrow binding, enforce multi-profile safeguards, use guarded audited replacement, and refuse remote HTTP, provider-adapter, OAuth, named-upstream, mixed-profile, duplicate-source, and arbitrary-override configurations. It also adds explicitly acknowledged local STDIO setup and client-entry import: literal executable plus bounded argument array, no shell, no secret-shaped values, no generic-command launch during onboarding, read-only default policy, destructive handling for unknown tools, and Windows-only direct absolute `.exe`/`.com` requirements to avoid a command-shell fallback.

### Changed

Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,23 @@ This works only for an unchanged reviewed provider-adapter configuration whose e

The local dashboard offers the same returning-user flow: run `miftah dashboard --config ~/.config/miftah/gsc.json`, then choose **Add another provider account**. The form appears only when the selected configuration meets the reviewed provider-adapter boundary. It asks for a new profile, optional description, and credential-file path; it never shows an existing path or provider cache, and it does not replace native OAuth controls for other kinds of MCP.

### Add another local environment-backed account

Some local STDIO MCPs use one environment variable for their credential rather than provider-owned OAuth. When the existing configuration has exactly that simple shape, add a second, third, or later account without hand-editing JSON:

```bash
miftah setup --add-profile \
--config ~/.config/miftah/sentry.json \
--profile personal \
--description "Personal Sentry account" \
--credential-env SENTRY_PERSONAL_ACCESS_TOKEN \
--make-default
```

`--credential-env` is the **name** of an environment variable, never its value. Miftah stores a reference such as `${SENTRY_PERSONAL_ACCESS_TOKEN}`, never reads the credential, and does not start the upstream. This deliberately applies only to one local `stdio` upstream with one direct credential binding per profile, the same destination and policy for every existing account, no provider adapter, and no native OAuth or named upstreams. Each account must use a different source environment variable. Remote HTTP MCPs are refused because profile environments do not authenticate HTTP requests.

There is no generic `--verify` here: Miftah does not guess a safe command for an arbitrary upstream. Set the new environment variable in the application environment that launches Miftah, restart or reconnect the MCP client, then use the service's normal safe validation path. The local dashboard offers the same flow under **Add another environment-backed account** when the selected configuration meets this exact boundary.

### Change the durable default later

Once two or more profiles already exist, you can choose which one new Miftah sessions start with without adding an account or editing JSON:
Expand Down
6 changes: 4 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Documented command names, options, JSON success forms, and exit categories are c
| `miftah validate --config <file>` | `--config` | `--config <file>` | Validates the JSON configuration without starting an upstream. Writes a JSON object with `ok`, `name`, and `profiles`. |
| `miftah doctor --config <file>` | `--config` | `--config <file>`, `--json` | Validates configuration and checks upstream readiness. Default output is a human-readable report; `--json` writes only the JSON report. A healthy or degraded report exits `0`; a failed report exits `1`. |
| `miftah schema` | none | none | Writes the Miftah JSON Schema as pretty-printed JSON. |
| `miftah setup [name]` | none, or `--add-profile --config <file>` | The safe preset options accepted by `init`, except `--interactive`, plus `--verify`; `--import-file <file>` with `--import-entry <name>`; or `--add-profile --config <file> --profile <name> --oauth-client-secrets-file <file>` for a reviewed provider-owned account | Opens the guided first-configuration flow. It asks for no secret value, validates the complete candidate, creates the output exclusively with owner-restricted permissions, and can print client JSON for manual review. For `local-stdio`, it collects literal argv elements, shows a no-secret review summary, and requires acknowledgement before saving; it never starts that generic local executable. For Google Search Console it can collect one or more named accounts and an explicit default. `--add-profile` adds one later account only when the selected existing configuration remains wholly inside a reviewed provider-adapter boundary. `--verify` opts into one provider-declared read-only check for every created reviewed adapter profile, or just the newly added account, after the write; it is rejected for a client-entry import because no reviewed adapter is inferred. The explicit import path accepts one selected local stdio or credential-free HTTPS remote entry and never edits a client configuration file. |
| `miftah setup [name]` | none, or `--add-profile --config <file>` | The safe preset options accepted by `init`, except `--interactive`, plus `--verify`; `--import-file <file>` with `--import-entry <name>`; `--add-profile --config <file> --profile <name> --oauth-client-secrets-file <file>` for a reviewed provider-owned account; or `--add-profile --config <file> --profile <name> --credential-env <name>` for a simple local environment-backed account | Opens the guided first-configuration flow. It asks for no secret value, validates the complete candidate, creates the output exclusively with owner-restricted permissions, and can print client JSON for manual review. For `local-stdio`, it collects literal argv elements, shows a no-secret review summary, and requires acknowledgement before saving; it never starts that generic local executable. For Google Search Console it can collect one or more named accounts and an explicit default. `--add-profile` either adds one later reviewed provider account or, only for a single simple local credential binding, a new environment-backed account. `--verify` opts into one provider-declared read-only check for every created reviewed adapter profile, or just the newly added account; it is unavailable for generic environment-backed addition and client-entry import because Miftah does not infer a safe probe. The explicit import path accepts one selected local stdio or credential-free HTTPS remote entry and never edits a client configuration file. |
| `miftah init [name]` | none | `--name <name>`, `--preset <name>`, `--output <file>`, `--interactive`, `--client <claude-desktop\|claude-code\|cursor\|vscode\|all>`, `--credential-env <name>`, `--npm-package <package>`, `--docker-image <image>`, `--url <url>`, `--header-name <name>`, `--header-prefix <prefix>`, `--oauth-client-secrets-file <file>`, `--local-command <executable>`, repeated `--arg <value>`, `--cwd <directory>`, `--accept-local-command` | Writes a strict catalog configuration with exclusive creation and can print client JSON snippets. The positional `name` and `--name` are alternatives; the default name is `miftah-wrapper`. |
| `miftah migrate-config --config <file>` | `--config` | `--config <file>`, `--write` | Plans a supported configuration-format migration and writes a safe JSON report. It is dry-run by default. `--write` validates the candidate, makes an exact exclusive `<file>.bak`, then uses a same-directory non-overwriting publication for a changed regular non-symlink source; it never resolves secrets or starts an upstream. |
| `miftah profile set-default --config <file> --profile <name>` | `--config`, `--profile` | `--config <file>`, `--profile <name>` | Makes one existing profile the durable default for future Miftah sessions. It performs a guarded replacement with a recovery backup and finalizes a configured fail-closed audit record. Its result omits configuration bytes, profile data, provider paths, and secret references; it never starts an upstream, opens OAuth, or changes profile data, provider caches, or an active client session. |
Expand Down Expand Up @@ -71,7 +71,9 @@ miftah validate --config "$HOME/Miftah configs/work wrapper.json"

`--interactive` uses a wizard only when both input and output are TTYs. EOF or Ctrl-C while it is collecting initial configuration data cancels without writing a config. In `miftah setup`, the first answer can be `remote` for the strict `streamable-http` path, `local` for `local-stdio`, or any catalog connector name. It asks for variable names and safe metadata, never secret values. The `remote` answer does not discover OAuth or call the upstream; use `miftah setup --native-oauth` only when the remote server advertises standards-based OAuth. For `local-stdio`, it asks for one argv element at a time and prints only a bounded count-based review summary before the acknowledgement; it does not echo arguments or credential values. For Google Search Console it asks for each account's profile name, optional description, and client-secrets path, then an explicit default profile. `miftah setup --verify` is an explicit opt-in to run each selected adapter's declared safe read-only check after the configuration write. It never accepts a tool name or arguments from the operator, never guesses a health command, does not auto-approve a policy confirmation, and returns only bounded status rather than provider output. The check runs only while the selected profile still matches the adapter's reviewed launch envelope; otherwise it reports a bounded unsupported status without launching the provider. If the post-write readiness prompt is cancelled, Miftah keeps the configuration, reports incomplete verification, and exits 1. A non-ready `setup --verify` result also keeps the configuration and exits 1. `init` is network-free and does not accept `--verify` or client-entry import flags. In noninteractive use, `init` creates only the config unless `--client` is supplied. `--client` prints JSON with absolute Node and compiled Miftah paths; it does not write a host config. For `claude-code` or `all`, it also prints a separate, exact management-tool `permissions.ask` fragment for manual merge into Claude Code settings; it never writes or overwrites those settings. Regenerate the snippets after moving or upgrading Miftah or changing the config path.

`miftah setup --add-profile --config <file>` is the returning-user path for a reviewed provider-owned adapter. In a noninteractive invocation it requires `--profile` and `--oauth-client-secrets-file`; `--description`, `--make-default`, and `--verify` are optional. It first proves that the entire selected configuration matches one adapter and that every existing account has a literal absolute credential-file reference plus a distinct, canonical provider-state directory. It then atomically adds one new profile and another isolated state directory through that adapter contract. Miftah never reads the credential file or the upstream token cache. Unsupported, modified, mixed, or shared-state configurations fail closed with `PROVIDER_ACCOUNT_ADDITION_UNSUPPORTED`; an invalid credential-file path fails with `PROVIDER_ACCOUNT_INPUT_INVALID`. `--verify` checks the new account only. The durable default changes only when `--make-default` is present, so existing MCP clients still need a restart or new connection.
`miftah setup --add-profile --config <file>` has two typed returning-user paths. For a reviewed provider-owned adapter, noninteractive use requires `--profile` and `--oauth-client-secrets-file`; `--description`, `--make-default`, and `--verify` are optional. Miftah proves that the entire selected configuration matches one adapter and that every existing account has a literal absolute credential-file reference plus a distinct canonical provider-state directory. It then atomically adds one new profile and isolated state directory through that adapter contract. Miftah never reads the credential file or the upstream token cache. Unsupported, modified, mixed, or shared-state configurations fail closed with `PROVIDER_ACCOUNT_ADDITION_UNSUPPORTED`; an invalid credential-file path fails with `PROVIDER_ACCOUNT_INPUT_INVALID`. `--verify` checks the new account only.

For a static local account, noninteractive use requires `--profile` and `--credential-env`; the latter is an environment-variable name, never a secret value. This path accepts only a configuration with exactly one unnamed `stdio` upstream, one direct `${ENV_NAME}` credential binding in every profile, one shared destination/policy, no provider adapter, no native OAuth, and no named upstreams or other profile overrides. It atomically adds one profile that points at a different environment variable, enforces profile-switch confirmation and explicit destructive selection, and never starts the upstream or reads the credential. Remote HTTP credentials use headers rather than profile environments, so remote configurations fail closed with `ENVIRONMENT_PROFILE_ADDITION_UNSUPPORTED`. Generic `--verify` is deliberately rejected because Miftah has no declared safe probe. The durable default changes only when `--make-default` is present, so existing MCP clients still need a restart or new connection.

`miftah setup <name> --import-file <absolute-json-file> --import-entry <name>` is a separate no-secret flow, not a generic client migration. The source file must be an absolute regular non-symlink file. Miftah reads it through one bounded verified handle, requires an explicitly selected entry, and never changes the source. It accepts either a local `stdio` entry under `mcpServers` (Claude Desktop, Claude Code, or Cursor) or `servers` (VS Code) that fits its finite static launch grammar—literal executable, optional absolute working directory, and either an exact-version package-runner launch with only that runner's fixed safe prefix flags and no arguments after the package, a script path plus non-sensitive flags, or a direct executable plus non-sensitive flags—or one credential-free HTTPS remote entry. A remote import uses `url` under `mcpServers` or `servers` and must explicitly declare `type: "http"` or `"streamable-http"`. It requires HTTPS without userinfo, query, fragment, or opaque credential-shaped path segments, and does not discover OAuth or call the remote endpoint. On Windows, a local import accepts only a direct absolute `.exe` or `.com` executable; bare runners such as `npx` or `node`, and `.cmd`/`.bat` shims, are rejected rather than being dispatched through a command processor. It rejects `env`, headers, shell settings, unknown fields, environment wrappers, inline code, opaque values or assignments, unsupported remote transports, URL userinfo, opaque credential-shaped URL path segments, unpinned package references, and credential-shaped arguments. It creates a read-only default profile with unknown tool risk set to destructive and does not launch the imported program. `--verify` is rejected before publication because no reviewed provider adapter is inferred. Use advanced manual setup when the existing entry does not fit this grammar; configure upstream credentials or OAuth separately through the upstream's documented path and Miftah secret references.

Expand Down
Loading