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
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ Claude Desktop is a GUI app and does not inherit terminal startup files such as

Continue with the step-by-step [Claude Desktop setup](docs/claude-desktop.md), or start from the [GitHub example](docs/examples/github.md) or [Sentry example](docs/examples/sentry.md).

Prefer a browser for OAuth setup? Run:

```bash
miftah dashboard
```

The optional local Console opens on `127.0.0.1`, creates a validated first native-OAuth profile without hand-written JSON, shows redacted connection/audit state, and generates client JSON for you to review and copy. It stays in the foreground, never edits Claude or another client configuration, and does not accept provider passwords, browser cookies, or raw tokens. Use `--config <file>` to manage another Miftah configuration or `--no-open` when you only want the local URL.

## A real multi-account setup

Imagine you use Sentry for two products. Instead of adding two separate Sentry servers to Claude Desktop, configure one `miftah-sentry` connector with two profiles:
Expand Down Expand Up @@ -101,7 +109,7 @@ For credential-file workflows, see [profile credential isolation](docs/config.md

When an operator enables profile locking, `miftah_lock_profile` and `miftah_unlock_profile` expose that control to the MCP client. For the complete security scope and future work, read the linked designs below.

The optional local Console control API is started explicitly with `miftah console --config <file>`. It binds only to loopback, uses a one-time terminal bootstrap plus browser session/CSRF protection, and exposes redacted metadata and audited connection operations under `/api/v1`. It is not a daemon and cannot change an already-running MCP client's in-memory session. The browser UI is a separate roadmap layer; see the [Console API contract](docs/console-api.md).
The optional local Console is started explicitly with `miftah dashboard`; `miftah console --config <file>` remains the API-only form. It binds only to loopback, uses a one-time terminal bootstrap plus browser session/CSRF protection, and exposes redacted metadata and audited connection operations under `/api/v1`. It is not a daemon and cannot change an already-running MCP client's in-memory session. See the [Console contract](docs/console-api.md).

## Is Miftah right for you?

Expand All @@ -118,7 +126,7 @@ If you use one account with one direct MCP server and do not need profile, routi
- [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)
- [Local Console dashboard and control API](docs/console-api.md)
- [CLI reference](docs/cli.md)
- [Architecture](docs/architecture.md)
- [Changelog and release policy](CHANGELOG.md)
Expand Down
4 changes: 2 additions & 2 deletions 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. 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.
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 UI/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 remains a separate boundary.

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

Expand All @@ -16,7 +16,7 @@ MCP client
-> upstream STDIO server
```

The Console control plane is a sibling process boundary, not another MCP transport. `miftah console` binds literal loopback only and routes `/api/v1` browser requests through one-use bootstrap, a bounded HttpOnly session, exact Host/Origin checks, CSRF validation, typed application services, and a separate fail-closed mutation journal. It has no `/mcp` route and cannot mutate another process's active STDIO session.
The Console control plane is a sibling process boundary, not another MCP transport. `miftah dashboard` (or API-only `miftah console`) binds literal loopback only and routes `/api/v1` browser requests through one-use bootstrap, a bounded HttpOnly session, exact Host checks, exact Origin plus CSRF for mutations, typed application services, and a separate fail-closed mutation journal. It has no `/mcp` route and cannot mutate another process's active STDIO session.

The STDIO public server is built with the official `@modelcontextprotocol/sdk` `Server` and `StdioServerTransport`. Each profile/upstream pair gets an SDK `Client` and its configured transport on first use: local processes use `StdioClientTransport`; remote upstreams use Streamable HTTP by default (the historical `"http"` alias is accepted only by version 1) or the deprecated legacy SSE client. Resolved profile headers override upstream headers case-insensitively before either remote transport is constructed. An exact version-3 OAuth binding gives only that Streamable HTTP session a profile-bound SDK OAuth provider; static Authorization headers on the same target are rejected. The provider validates protected-resource and authorization-server discovery, drives PKCE/browser/callback exchange, and loads or refreshes credentials through the exact OS-vault binding before reconnecting with bearer authorization. Streamable HTTP session shutdown sends DELETE while its session ID is still available, then closes the local client transport and any pending OAuth handoff; legacy SSE has no corresponding server-session teardown request. Request cancellation and requested progress notifications retain their MCP request context across both STDIO and Streamable HTTP upstreams. Startup HTTP failures and operation HTTP/MCP/OAuth failures are normalized before crossing the proxy boundary, retaining only stable category/code metadata rather than server response text. See [OAuth support](oauth-support.md) for the supported native OAuth boundary.

Expand Down
11 changes: 7 additions & 4 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# CLI reference

`miftah` is an MCP wrapper with STDIO as its default transport, an opt-in local Streamable HTTP server, and a separately launched local Console control API. Run `miftah --help` for the generated command list, or `miftah <command> --help` for the options accepted by one command. The help text is the authoritative grammar for the installed version.
`miftah` is an MCP wrapper with STDIO as its default transport, an opt-in local Streamable HTTP server, and a separately launched local Console dashboard/control API. Run `miftah --help` for the generated command list, or `miftah <command> --help` for the options accepted by one command. The help text is the authoritative grammar for the installed version.

## Help

```text
Usage: miftah [command] [options]
```

The root command list includes `serve`, `console`, `validate`, `doctor`, `schema`, `init`, `migrate-config`, `connection add|list|status|test`, `auth connect|reauth|disconnect`, `list-tools`, `test-profile`, `logs`, `audit-export`, `audit-verify`, and `version`. With no command, Miftah runs `serve`.
The root command list includes `serve`, `dashboard`, `console`, `validate`, `doctor`, `schema`, `init`, `migrate-config`, `connection add|list|status|test`, `auth connect|reauth|disconnect`, `list-tools`, `test-profile`, `logs`, `audit-export`, `audit-verify`, and `version`. With no command, Miftah runs `serve`.

Documented command names, options, JSON success forms, and exit categories are compatibility contracts. An incompatible CLI removal, rename, required-option change, or semantic output change requires the pre-1.0 deprecation/removal process in the [public compatibility policy](library-api.md#compatibility-policy).

Expand All @@ -20,6 +20,7 @@ Documented command names, options, JSON success forms, and exit categories are c
| --- | --- | --- | --- |
| `miftah serve --config <file>` | `--config` | `--config <file>`, `--transport <stdio\|http>` | Runs the STDIO MCP wrapper by default, or the configured local Streamable HTTP endpoint with `--transport http`. `miftah --config <file>` is the equivalent default-command STDIO form. |
| `miftah console --config <file>` | `--config` | `--config <file>`, `--port <number>` | Explicitly starts the separate literal-loopback Console control API. It prints the URL and a one-use terminal bootstrap code; no daemon or MCP session is started. |
| `miftah dashboard` | none | `--config <file>`, `--port <number>`, `--no-open` | Starts the optional foreground browser Console on literal loopback. It defaults to `~/.config/miftah/miftah.json`, permits a missing file for first-run setup, opens the system browser unless `--no-open` is set, and never starts a daemon. |
| `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. |
Expand Down Expand Up @@ -47,11 +48,13 @@ Every command also accepts `--help` and `-h`; those generated per-command help s

HTTP bearer authentication is configured only through `server.http.authToken` as a secret reference. The CLI never accepts a bearer token option and never writes one to its listener or error output. See [HTTP server transport](config.md#http-server-transport) for loopback, non-loopback, Host, Origin, session, and request-limit requirements.

### Local Console control API
### Local Console dashboard and control API

`miftah dashboard` opens the optional browser-local Console and prints its exact URL, resolved configuration location, and one-use bootstrap code. Without `--config`, it uses `~/.config/miftah/miftah.json`. A missing file is not created until the operator submits a strict first-run native-OAuth profile; an existing file is loaded and is never silently replaced. `--no-open` leaves browser launch to the operator while keeping the same foreground server.

`miftah console --config <file>` binds only literal `127.0.0.1`, uses an ephemeral port unless `--port` is supplied, and prints an invocation-bound one-use bootstrap code to the launching terminal. The code is not an OAuth token or MCP bearer. Enter it only in the local Console bootstrap screen; never paste it into a URL, client configuration, log, or support ticket. Stopping the process closes the listener and invalidates every browser session. Restarting produces a fresh bootstrap credential.

The Console API is versioned under `/api/v1` and uses exact Host/Origin checks, a short-lived HttpOnly same-site session, CSRF proof for every mutation, bounded JSON, fail-closed mutation audit, and metadata-only responses. It modifies durable configuration and exact local OAuth credentials for future client connections; it cannot take over or silently change another process's active Claude Desktop session. See the [local Console control API](console-api.md) for the full endpoint and bootstrap contract.
The Console API is versioned under `/api/v1` and uses exact Host checks, exact loopback Origin plus CSRF for every mutation, a short-lived HttpOnly same-site session, bounded JSON, fail-closed mutation audit, and metadata-only responses. Authenticated reads may omit Origin because normal same-origin browser GETs do not consistently send it. It modifies durable configuration and exact local OAuth credentials for future client connections; it cannot take over or silently change another process's active Claude Desktop session. See the [local Console dashboard and control API](console-api.md) for the full endpoint and bootstrap contract.

### `init` presets and paths

Expand Down
Loading