Skip to content

Repository files navigation

TypeWhisper Claude OAuth Plugin

CI License: GPL-3.0

Use your Claude Pro/Max subscription — not an API key — for on-device text post-processing in TypeWhisper on macOS.

TypeWhisper cleans up and rewrites your dictated text with an LLM. Out of the box that means a pay-per-token API key. This plugin lets the LLM step run on the Claude Pro/Max subscription you already pay for: it signs in through Anthropic's OAuth flow and calls the Claude Messages API with those tokens, so dictation post-processing costs nothing beyond your existing plan.

End-to-end verified: 53/53 tests pass, and the plugin loads, logs in via OAuth, and calls the Anthropic Messages API from inside TypeWhisper 1.4.0.

What it is

A native macOS plugin (Swift, built against the TypeWhisper Plugin SDK) that registers as an LLM provider inside TypeWhisper. Once connected it appears in the app's model picker like any other backend. Concretely it:

  • Authenticates with Anthropic via OAuth + PKCE (S256) using the Pro/Max subscription, instead of an API key.
  • Sends post-processing requests to the Claude Messages API, choosing Haiku, Sonnet, or Opus.
  • Stores tokens in the macOS Keychain and keeps them refreshed automatically in the background.
  • Makes no telemetry or analytics calls — the only hosts it ever contacts are Anthropic's (claude.ai, platform.claude.com, api.anthropic.com).

It is a single, self-contained .bundle. There is no server, no account beyond your Claude subscription, and no third-party dependency outside the TypeWhisper SDK.

⚠️ Disclaimer

This is not an official Anthropic or TypeWhisper plugin. It uses the same OAuth client ID that Claude Code uses internally to authenticate against the Anthropic API, and identifies its API calls as Claude Code requests so the Pro/Max subscription accepts the inference. This sits in a gray area of Anthropic's Terms of Service. Use at your own risk — excessive use may result in account action.

Installation

Prerequisites: macOS 14+ (Apple Silicon), the Swift toolchain (Xcode or Command Line Tools), TypeWhisper 1.4.0+ installed at /Applications/TypeWhisper.app, and an active Claude Pro/Max subscription.

Build and install in one step:

./scripts/build-plugin.sh --install

Then quit and restart TypeWhisper. The plugin appears under Settings → Plugins → Claude (OAuth Pro/Max).

Build without installing

./scripts/build-plugin.sh
# Bundle is at .build/release/ClaudeOAuthPlugin.bundle

What the build script does

  1. swift build -c release — produces libClaudeOAuthPlugin.dylib.
  2. Assembles ClaudeOAuthPlugin.bundle (Contents/MacOS/ClaudeOAuthPlugin, Contents/Resources/manifest.json, Contents/Info.plist).
  3. Patches the binary with install_name_tool:
    • Changes the SDK reference from @rpath/libTypeWhisperPluginSDK.dylib (the SPM build output) to @rpath/TypeWhisperPluginSDK.framework/Versions/A/TypeWhisperPluginSDK (what TypeWhisper.app ships).
    • Adds /Applications/TypeWhisper.app/Contents/Frameworks as an LC_RPATH so the framework resolves at runtime.
  4. Ad-hoc code-signs the bundle (Gatekeeper accepts ad-hoc signatures on user-installed plugins).
  5. With --install: copies the bundle to ~/Library/Application Support/TypeWhisper/Plugins/.

Plugin directory

~/Library/Application Support/TypeWhisper/Plugins/

Verified at TypeWhisper 1.4.0 (build 803). The directory sits alongside PluginData/ (where plugins store their own state).

First-time setup

  1. Open Settings → Plugins → Claude (OAuth Pro/Max) inside TypeWhisper and activate it.
  2. Click "Mit Claude verbinden". Your default browser opens at claude.ai/oauth/authorize.
  3. Log in with your Claude Pro/Max account and confirm the permission grant.
  4. platform.claude.com shows an authorization code in the form <code>#<state>. Copy the whole thing.
  5. Paste it into the plugin's code field and click "Bestätigen".
  6. The plugin splits the input at #, verifies the state matches the login it started (a CSRF guard), exchanges the code for access + refresh tokens, and stores them in the macOS Keychain under com.guttmann.typewhisper-claude.oauth.

How it stays logged in

Anthropic's refresh tokens are single-use: every refresh returns a new refresh token, and the old one dies immediately. The plugin keeps the chain rotated and warm by:

  • Ticking every 60 seconds while TypeWhisper runs, refreshing whenever less than 15 minutes of validity remain.
  • Refreshing on plugin activation, and before each process() call if less than 5 minutes remain.
  • Persisting the new tokens before returning from the refresh, so a rotated token is never lost.

This keeps you signed in as long as TypeWhisper opens at least every few days. If a refresh ever fails (e.g. the token was revoked), the settings panel shows an "expired" state and prompts you to reconnect.

Models

Model Identifier When
Haiku 4.5 (default) claude-haiku-4-5 Fast post-processing of short voice snippets
Sonnet 4.6 claude-sonnet-4-6 More careful rewriting
Opus 4.7 claude-opus-4-7 Rare — complex transformations

Switch via the model picker in the plugin settings. Your choice is persisted in plugin-scoped UserDefaults through the SDK's HostServices.

Each request sends max_tokens: 2048. Temperature is set to 0.3 for Haiku and Sonnet but omitted for Opus 4.7, which rejects the temperature parameter (see Known Issues).

OAuth endpoints (Anthropic)

  • Authorize: https://claude.ai/oauth/authorize — PKCE S256, scopes org:create_api_key user:profile user:inference.
  • Token exchange / refresh: https://platform.claude.com/v1/oauth/token.
  • Redirect URI: https://platform.claude.com/oauth/code/callback — Anthropic renders the code on this page; the user copies it back into the plugin.
  • Client ID: 9d1c250a-e61b-44d9-88ed-5944d1962f5e (identical to Claude Code's client ID).
  • Inference: https://api.anthropic.com/v1/messages.

The plugin manifest (manifest.json)

manifest.json is the TypeWhisper plugin manifest — the metadata TypeWhisper reads to discover and load the plugin. The build script copies it into the bundle at Contents/Resources/manifest.json. Its fields:

Field Value Meaning
id com.guttmann.typewhisper-claude-oauth Unique plugin identifier
name Claude (OAuth Pro/Max) Display name shown in TypeWhisper
version 0.1.0 Plugin version
minHostVersion 1.4.0 Oldest TypeWhisper version that can load it
sdkCompatibilityVersion v1 Plugin SDK ABI this build targets
minOSVersion 14.0 Minimum macOS version
supportedArchitectures ["arm64"] Apple Silicon only
category llm Registers the plugin as an LLM provider
principalClass ClaudeOAuthLLMPlugin The Swift class TypeWhisper instantiates as the entry point

The principalClass matches the @objc(ClaudeOAuthLLMPlugin) class in the source and the NSPrincipalClass written into the bundle's Info.plist, so the host can find and instantiate the plugin at load time.

Known issues

  • TypeWhisper 1.4.0 drops the Fine-tuning field on Custom Workflow templates. When a workflow uses Eigener Workflow / Custom Workflow, the Feinabstimmung input is silently ignored — the plugin only receives the Anweisung as systemPrompt. This is a TypeWhisper bug, not a plugin bug. Tracked upstream: typewhisper-mac#608. Workaround: paste the fine-tuning text at the end of the instruction field, or switch the workflow's template to Cleaned Text / Summary / Email Reply etc. (all of which correctly include fineTuning in the generated prompt).

  • Opus 4.7 rejects the temperature parameter. Anthropic deprecated temperature for the Opus 4.7 reasoning model. The plugin omits temperature when the selected model starts with claude-opus-4-7; for Haiku 4.5 and Sonnet 4.6 it still sends temperature: 0.3.

Development

swift build          # compile
swift test           # run the test suite (53 tests across 5 suites)

Tests use the Swift Testing framework (@Test macros) and run fully offline — network calls are stubbed via a URLProtocol mock and an in-memory HostServices, so no real Anthropic credentials or requests are involved.

Catalog submission

Submitted to the official TypeWhisper plugin catalog via a fork-and-pull-request against the upstream catalog repository.

Security

To report a vulnerability, see SECURITY.md.

License

GPL-3.0-only — see LICENSE.

Acknowledgements

  • Token-refresh and retry logic is modeled on an internal reference implementation of single-use refresh-token rotation.
  • OAuth + PKCE flow patterns are adapted from an internal reference implementation of Anthropic OAuth authentication.

About

Use your Claude Pro/Max subscription instead of an API key for on-device LLM text post-processing in TypeWhisper (macOS). Unofficial; tokens stay in the Keychain.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages