Make AI clients speak to models correctly.
APIdapter is an open-source, local-first Model Compatibility Runtime. It repairs semantic differences that remain when an AI client and a model provider both claim to support an OpenAI-compatible API.
Use APIdapter when DeepSeek V4 Flash can answer in Raycast but streaming reasoning or multi-turn tool calls do not work correctly.
Project status: v0.1.0 is the first public Raycast vertical-slice release. It remains pre-release software and is not production-ready.
v0.1.0 intentionally supports one path:
Raycast Custom Provider
│ OpenAI Chat Completions
▼
APIdapter on 127.0.0.1
│ DeepSeek Chat Completions
▼
https://api.deepseek.com/chat/completions
│
▼
deepseek-v4-flash
The runtime currently provides:
POST /chat/completionsandGET /healthz;- immediate SSE forwarding with Raycast reasoning updates;
- non-streaming reasoning translation;
- cancellation propagation to the upstream request;
developertosystemmessage normalization;- non-null assistant content for tool-call messages;
- removal of thinking-mode
tool_choicebefore calling DeepSeek; - bounded in-memory
reasoning_contentreplay across Raycast tool turns; - stable OpenAI-style local and upstream error objects;
- bearer-token pass-through without API-key persistence;
- content-free operational logs.
DeepSeek requires reasoning_content to be replayed after thinking-mode tool calls, while Raycast does not currently replay that field. APIdapter retains only this required protocol state, bounded by TTL, tool-call count, and bytes. See the DeepSeek thinking-mode contract.
Requirements: macOS. Download the matching binary and its checksum from the v0.1.0 release. For Apple silicon:
curl -LO https://github.com/p1ac4/APIdapter/releases/download/v0.1.0/apidapter_v0.1.0_darwin_arm64
curl -LO https://github.com/p1ac4/APIdapter/releases/download/v0.1.0/apidapter_v0.1.0_checksums.txt
grep ' apidapter_v0.1.0_darwin_arm64$' apidapter_v0.1.0_checksums.txt | shasum -a 256 -c -
chmod +x apidapter_v0.1.0_darwin_arm64
./apidapter_v0.1.0_darwin_arm64 --versionIntel Mac users should download apidapter_v0.1.0_darwin_amd64 and substitute that filename in the verification and launch commands. GitHub release downloads do not retain the executable bit, so chmod +x is required.
To build from source, install Go 1.24 or newer:
git clone https://github.com/p1ac4/APIdapter.git
cd APIdapter
go test ./...
go build -o apidapter ./cmd/apidapter
./apidapter serve --config examples/config.jsonVerify the daemon:
curl http://127.0.0.1:48765/healthzThen copy examples/raycast-providers.yaml to Raycast's custom-provider configuration and replace REPLACE_WITH_YOUR_DEEPSEEK_API_KEY with your own key. See Raycast setup for the complete procedure and security boundary.
The adapter can also run with safe defaults and no configuration file:
./apidapterOverride the loopback address or port without editing JSON:
./apidapter serve --listen 127.0.0.1:49000Validate a configuration without starting the server:
./apidapter validate-config --config examples/config.jsonDiscover every command and option from the binary:
./apidapter --help
./apidapter help serve
./apidapter validate-config --help
./apidapter --version{
"listen": "127.0.0.1:48765",
"upstream_url": "https://api.deepseek.com/chat/completions",
"state": {
"ttl": "30m",
"max_entries": 256,
"max_bytes": 33554432
}
}v0.1.0 fails closed unless the listener is loopback-only and the upstream is the official DeepSeek Chat Completions endpoint. Unknown JSON fields are rejected.
Request policy remains user-controlled: valid thinking, reasoning_effort, and max_tokens values pass through. DeepSeek V4 Flash supports a 1M context window and up to 384K output, but the public example does not silently request the maximum because output is billed. Review the current DeepSeek model details and pricing before increasing max_tokens.
Raycast sends its configured bearer token to APIdapter, which forwards it to api.deepseek.com. APIdapter does not save the token.
The Raycast Custom Provider file contains the key as a literal value. Protect that file with normal user-only filesystem permissions. Never commit it.
By default APIdapter does not log or persist prompts, responses, tool arguments, or credentials. It keeps only provider-required reasoning state in memory and removes it after the configured TTL or earlier capacity eviction. Restarting APIdapter clears all state.
- Only Raycast,
deepseek-v4-flash, and the official DeepSeek endpoint are supported. - Vision, VS Code, Warp, Anthropic API, Responses API, multi-provider routing, UI, and automatic background installation are not included.
- Raycast only sends tools exposed by its selected AI Extensions. APIdapter makes those tools compatible; it does not add search, filesystem, or other tools.
- Restarting the daemon during an active tool loop loses required reasoning state. Start a new Raycast chat if
reasoning_state_missingis returned. - v0.1.0 is pre-release software and is not yet production-ready.
gofmt -w .
go test ./...
go test -race ./...
go vet ./...
./scripts/build-release.sh v0.1.0The default suite is deterministic and does not call a live model provider. It covers a two-step Raycast-style tool loop, response translation, state bounds, cancellation, upstream errors, and interrupted SSE streams.
GitHub Actions runs formatting, repeated tests, the race detector, vet, and release-artifact verification on every push and pull request. Pushing a v* tag reruns those checks, builds both macOS binaries, verifies checksums, and creates or updates the corresponding GitHub Release. A maintainer must complete the live Raycast tool-loop check before pushing the release tag.
Read CONTRIBUTING.md before proposing changes. Security-sensitive findings should follow SECURITY.md.
APIdapter is licensed under the Apache License 2.0.