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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. The format
- [#83](https://github.com/mohanagy/miftah/issues/83) Added durable bounded profile/account identity bindings, visible per-profile binding states and evidence, exact OAuth connection identity-state updates, and opt-in explicit or confirmed current-session selection for protected multi-profile operations. Persisted evidence never replaces live verification, and external state changes never silently override an active client's in-memory profile.
- [#84](https://github.com/mohanagy/miftah/issues/84) Added dry-run-first OAuth connection setup, redacted connection list/status/test reports, safe connect and reauthentication, exact local disconnect, client snippets, and headless diagnostics through shared typed application services.
- [#85](https://github.com/mohanagy/miftah/issues/85) Added the explicitly launched, literal-loopback Console control API with a separate `/api/v1` listener, one-use terminal bootstrap, bounded HttpOnly browser sessions, strict Host/Origin and CSRF enforcement, metadata-only configuration/profile/connection health, atomic audited connection changes, redacted Console audit queries, credential rotation, and clean shutdown. The browser UI remains a separate roadmap layer.
- [#87](https://github.com/mohanagy/miftah/issues/87) Added a typed built-in provider-adapter contract and a bounded Google Search Console pilot with exact `mcp-search-console@0.3.2` launch pinning, explicit upstream-owned OAuth/browser/cache lifecycle, safe health metadata, read-only defaults, manual service-account guidance, and no token-cache access or native-OAuth claims.

## [0.3.3] - 2026-07-22

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ When you need the other product, select its profile deliberately. When a tool ca
- **Other compatible MCP servers:** configure a generic STDIO, Streamable HTTP, or legacy SSE upstream, then add profiles around it.
- **Multiple upstreams in one wrapper:** use an account bundle when related upstreams belong behind one controlled connection.

Miftah can authorize a standards-compatible remote HTTPS Streamable HTTP MCP server through discovery, PKCE, a bounded loopback browser callback, OS-vault storage, and refresh. `miftah connection …` and `miftah auth …` provide reviewed setup, status, noninteractive testing, connect, safe reauth, and local disconnect. Provider-specific or local STDIO OAuth remains owned by that upstream, and local disconnect does not claim provider-side token revocation. Read [OAuth support](docs/oauth-support.md) for the exact compatibility and configuration boundary.
Miftah can authorize a standards-compatible remote HTTPS Streamable HTTP MCP server through discovery, PKCE, a bounded loopback browser callback, OS-vault storage, and refresh. `miftah connection …` and `miftah auth …` provide reviewed setup, status, noninteractive testing, connect, safe reauth, and local disconnect. Provider-specific or local STDIO OAuth remains owned by that upstream, and local disconnect does not claim provider-side token revocation. A bounded [Google Search Console provider-adapter pilot](docs/provider-adapters.md#google-search-console-pilot) now generates an exact-pinned upstream-owned setup without reading its token cache or pretending it is native Miftah OAuth. Read [OAuth support](docs/oauth-support.md) for the exact compatibility and configuration boundary.

## Trust and control boundaries

Expand All @@ -117,6 +117,7 @@ If you use one account with one direct MCP server and do not need profile, routi
- [Configuration reference](docs/config.md)
- [Security boundary](docs/security.md), [Threat model](docs/threat-model.md), and [OAuth and Console security design](docs/oauth-console-threat-model.md)
- [OAuth support](docs/oauth-support.md)
- [Provider adapters and Google Search Console pilot](docs/provider-adapters.md)
- [Local Console control API](docs/console-api.md)
- [CLI reference](docs/cli.md)
- [Architecture](docs/architecture.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Architecture

The [threat model](threat-model.md) maps these components and their boundaries to public security controls and residual risks. The [OAuth and Console security design delta](oauth-console-threat-model.md) describes the control-plane and credential-lifecycle gates. Version 3 adds a standards-compatible remote OAuth runtime, in-process operator lifecycle services, and a separately launched local Console control API for exact HTTPS Streamable HTTP connections; provider adapters, provider-side revocation, and the browser UI remain separate milestones.
The [threat model](threat-model.md) maps these components and their boundaries to public security controls and residual risks. The [OAuth and Console security design delta](oauth-console-threat-model.md) describes the control-plane and credential-lifecycle gates. Version 3 adds a standards-compatible remote OAuth runtime, in-process operator lifecycle services, and a separately launched local Console control API for exact HTTPS Streamable HTTP connections. A separate typed built-in [provider-adapter catalog](provider-adapters.md) can launch and describe upstream-owned local authentication without entering the native OAuth engine; provider-side revocation and the browser UI remain separate milestones.

Miftah is an MCP-aware proxy, not a byte-level reverse proxy:

Expand Down
6 changes: 3 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,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 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>` | 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 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>` | 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 connection add --config <file>` | `--config`, `--profile`, `--issuer`, `--client-registration` | `--connection <ref>`, `--upstream <name>`, repeated `--scope <scope>`, `--write` | Plans a v3 OAuth binding by default. `--write` applies the reviewed candidate with a unique recovery backup and configured audit event. It never resolves credentials or starts an upstream. |
| `miftah connection list --config <file>` | `--config` | `--client <claude-desktop\|claude-code\|cursor\|vscode\|all>` | Lists redacted connection state. Optional snippets are copyable JSON only; Miftah never edits client settings. |
Expand Down Expand Up @@ -55,14 +55,14 @@ The Console API is versioned under `/api/v1` and uses exact Host/Origin checks,

### `init` presets and paths

`--preset` defaults to `generic`. The strict catalog accepts `generic`, `github`, `sentry`, `generic-npx`, `generic-docker`, and `streamable-http`; an unrecognized preset is a usage error. `--output` defaults to `<name>.miftah.json`. Miftah resolves the output path from the current working directory, creates missing parent directories, and refuses to overwrite an existing file. Quote shell paths and names containing spaces:
`--preset` defaults to `generic`. The strict catalog accepts `generic`, `github`, `sentry`, `google-search-console`, `generic-npx`, `generic-docker`, and `streamable-http`; an unrecognized preset is a usage error. `--output` defaults to `<name>.miftah.json`. Miftah resolves the output path from the current working directory, creates missing parent directories, and refuses to overwrite an existing file. Quote shell paths and names containing spaces:

```sh
miftah init "work wrapper" --preset github --output "$HOME/Miftah configs/work wrapper.json"
miftah validate --config "$HOME/Miftah configs/work wrapper.json"
```

`generic-npx` requires `--npm-package` with exact package SemVer; `generic-docker` requires a canonical digest in `--docker-image`; and `streamable-http` requires `--url` plus optional credential environment/header metadata. `--credential-env` is optional where supported. See [preset and client compatibility](presets-and-clients.md) for exact inputs, pins, provenance, and client snippets.
`generic-npx` requires `--npm-package` with exact package SemVer; `generic-docker` requires a canonical digest in `--docker-image`; `streamable-http` requires `--url` plus optional credential environment/header metadata; and `google-search-console` requires `--oauth-client-secrets-file` with an absolute path. `--credential-env` is optional where supported. The GSC adapter prints credential/browser/identity ownership without printing that path. See [preset and client compatibility](presets-and-clients.md) for exact inputs, pins, provenance, and client snippets, and [provider adapters](provider-adapters.md) for the upstream-owned OAuth boundary.

`--interactive` uses a wizard only when both input and output are TTYs. EOF or Ctrl-C cancels without writing a config. It asks for variable names and safe metadata, never secret values. 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.

Expand Down
4 changes: 2 additions & 2 deletions docs/oauth-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The [OAuth and local Console design delta](oauth-console-threat-model.md) record
| Support class | Transport and current ownership | Operator fallback |
| --- | --- | --- |
| Standards-compatible remote HTTP MCP OAuth | Enabled for an exact HTTPS `streamable-http` connection whose protected-resource and authorization-server metadata satisfy Miftah's discovery checks. Miftah owns browser authorization, the bounded loopback callback, exchange, vault storage, refresh, and bearer injection. | If the server does not advertise the required standards, use its documented API-key, static-header, or provider-owned flow. |
| Provider-adapter-backed local or non-standard OAuth | No provider-adapter API exists today. Miftah does not automate a provider-specific browser flow, private callback convention, or token-store format. | Complete the upstream's documented login and configuration; Miftah can launch, redact, and diagnose that configured upstream. |
| Provider-adapter-backed local or non-standard OAuth | The built-in [Google Search Console pilot](provider-adapters.md#google-search-console-pilot) launches an exact-pinned local upstream and publishes its ownership contract. OAuth, browser handoff, token cache, reauthentication, and revocation remain upstream/manual-owned; this is not native Miftah OAuth. | Complete the upstream's documented login and configuration. The typed adapter supplies bounded launch and safe health metadata without cache access. |
| Upstream-owned or manual credentials | `stdio`, legacy `sse`, and remote Streamable HTTP headers remain supported. The upstream/provider owns login, callback, token cache, refresh, reauth, and revoke. | Complete the provider-owned login, supply its documented credential path, environment value, or static secret reference, then run `miftah validate` and `miftah doctor`. |
| Unsupported authentication patterns | Provider passwords, browser cookies, and arbitrary third-party token caches are not a supported Miftah-managed OAuth mechanism. Miftah does not own, parse, scrape, import, replay, or lifecycle-manage provider passwords, browser cookies, or arbitrary third-party token caches as OAuth artifacts. | Use a provider-supported mechanism, or leave that upstream unconfigured when its only path depends on opaque private state. |

Expand Down Expand Up @@ -103,7 +103,7 @@ The exact OAuth-bound Streamable HTTP transport receives the profile-bound OAuth

## Local and provider-owned OAuth

For a **Google Search Console-style local OAuth** upstream, such as a local `uvx mcp-search-console` process configured with a provider client-secrets file, complete the provider's login first. Configure only the documented client-secret file path, environment value, or other upstream input; then let that upstream create and maintain its own local credential cache. **Miftah must not scrape, copy, or manage that upstream token cache.**
For Google Search Console-style local OAuth, the [Google Search Console pilot](provider-adapters.md#google-search-console-pilot) generates an exact-pinned local `uvx mcp-search-console@0.3.2` process configured with a provider client-secrets file. Complete the upstream's browser login on first use and let that upstream create and maintain its own local credential cache. **Miftah must not scrape, copy, or manage that upstream token cache.**

The same rule applies when Sentry or another upstream MCP server owns consent, redirects, or cached tokens. Miftah may pass an explicit configured path or secret reference to the child and redact resolved values. It does not reinterpret an opaque provider cache as a native Miftah OAuth connection.

Expand Down
Loading