OpenCode MCP Bridge
by ManuOtel
README.md
# opencode-mcp-bridge
A coordinator-facing MCP server for a self-hosted
[`OpenCode`](https://opencode.ai) instance.
A host harness (Codex, Claude Code, Cursor, or any MCP-capable client)
delegates repository or system work to an OpenCode worker on another
machine. The host model scopes the task, coordinates the worker, and
verifies the result. The bridge speaks MCP over Streamable HTTP with
Bearer authentication (remote HTTP only; there is no local stdio
transport). It coordinates OpenCode workers; it does not replace
OpenCode.
This is not a hosted OpenCode service for production. Each user should
self-host for production: provide an OpenCode server, or use one they
control, plus their own bridge deployment and token. The project includes
an optional community demo endpoint operated by ManuOtel at
`https://opencode-mcp.manuotel.com/worker-mcp` (`/worker-mcp` only); it
requires its own token and is not for production. Placeholder URLs such as
`https://YOUR-BRIDGE-HOST/worker-mcp` are not usable servers.
## Section map
1. [Quick start (60 seconds)](#quick-start-60-seconds)
2. [Endpoints](#endpoints)
3. [Harness setup](#harness-setup)
4. [Worker workflow](#worker-workflow)
5. [Tools](#tools)
6. [Security](#security)
7. [Local deployment](#local-deployment)
8. [Contributor workflow](#contributor-workflow)
9. [Publish and discover](#publish-and-discover)
10. [Community and license](#community-and-license)
## Quick start (60 seconds)
You need your own bridge deployment ([Local deployment](#local-deployment))
and its Bearer token. Keep the token in environment variables. Never
paste a real token into a file, a chat log, or a commit.
```bash
export OPENCODE_MCP_URL="https://<your-domain>/worker-mcp"
export OPENCODE_MCP_BEARER_TOKEN="<paste-token-here>"
```
Replace `<your-domain>` with your bridge host and `<paste-token-here>`
with the value of `MCP_BEARER_TOKEN` on that host. Then register the
transport in your harness (see [Harness setup](#harness-setup)).
Quick connect (your own bridge): `./scripts/install-client.sh both`
registers Codex and Claude Code transports from `OPENCODE_MCP_URL` and
`OPENCODE_MCP_BEARER_TOKEN`. Full steps live in
[docs/client-setup.md](docs/client-setup.md). The maintainer demo is
opt-in only and may require its own token; generic installs never point
at another person's server.
Rules for every example in this file:
- `https://<your-domain>/worker-mcp` is the safe default. It exposes
exactly five worker tools and never includes `exec_run`.
- `https://<your-domain>/mcp` exposes the full legacy catalog, including
`exec_run` when the operator enables it. Use it only for legacy clients.
- `https://YOUR-BRIDGE-HOST/worker-mcp` (as shipped in `.mcp.json`) is a
placeholder. It fails loudly by design. Always register your own URL
per machine for production. The optional community demo endpoint
`https://opencode-mcp.manuotel.com/worker-mcp` (`/worker-mcp` only) is
operated by ManuOtel, requires its own token, and is not for production.
- Generate a fresh token with
`python3 -c "import secrets; print(secrets.token_urlsafe(48))"`.
The helper `./scripts/install-client.sh --help` registers Codex or Claude
Code transports from these variables. It requires both variables and
fails clearly when either is missing or the URL is malformed (it must be
`http(s)://...` ending in `/mcp` or `/worker-mcp`); it never falls back
to anyone else's server. Full Codex and Claude Code steps live in
[docs/client-setup.md](docs/client-setup.md). Copilot-family products
have their own guide at [docs/copilot-setup.md](docs/copilot-setup.md).
For the public registry metadata and publication checklist, see
[docs/registry.md](docs/registry.md). The registry entry describes the
software and advertises the optional community demo endpoint operated by
ManuOtel; it never supplies a token. Self-host for production with your
own token.
## Endpoints
Two Streamable HTTP endpoints share one Bearer token.
`GET /health` is the only unauthenticated endpoint. Remote HTTP only;
there is no local stdio command.
| Endpoint | Tools | Use |
| --- | --- | --- |
| `/worker-mcp` | Exactly five: `worker_catalog`, `worker_run`, `worker_status`, `worker_verify`, `worker_cleanup` | Default for all new clients. Least privilege; no shell. |
| `/mcp` | Full 16-tool catalog: the five worker tools plus `list_*`, session tools, `get_diff`, `exec_run` | Legacy clients only. `exec_run` stays listed but fails closed unless `ENABLE_EXEC_RUN=true`. |
| `/health` | None (open) | Reverse-proxy checks. |
There is no global tool-profile switch. Both endpoints are always served
from the same process.
## Harness setup
Compatibility is protocol-level (MCP over Streamable HTTP with a Bearer
header) unless an end-to-end test is documented in this repo. Client
config keys differ per product; confirm key names in the linked official
docs before pasting.
| Harness | How to connect | Status |
| --- | --- | --- |
| OpenAI Codex CLI | `codex mcp add` with `--bearer-token-env-var` | Protocol-level, syntax from official docs |
| Claude Code | `claude mcp add --transport http` or `opencode-worker` plugin | Protocol-level, syntax from official docs |
| ChatGPT Developer Mode | Remote MCP connector, URL mode + Bearer token | Protocol-level; needs an eligible plan and workspace, plus admin approval where required |
| Cursor | Project `.cursor/mcp.json`, `url` + `headers` | Protocol-level |
| Gemini CLI | `~/.gemini/settings.json`, `httpUrl` + `headers` | Protocol-level |
| Windsurf | `~/.codeium/windsurf/mcp_config.json`, `serverUrl` + `headers` | Protocol-level, key names from official docs |
| Cline | `cline_mcp_settings.json`, `type: streamableHttp` + `url` + `headers` | Protocol-level, key names from official docs |
| Roo Code | `mcpServers` entry, `url` + `Authorization` header | Protocol-level, client-specific shape |
| Pi | `pi-mcp-adapter`, shared `~/.config/mcp/mcp.json` | Protocol-level, syntax from official docs |
| Hermes Agent | YAML `mcp_servers` entry + `tools.include` | Protocol-level, syntax from official docs |
| GitHub Copilot / Copilot Studio / M365 Copilot | See [docs/copilot-setup.md](docs/copilot-setup.md) | Separate guide, three distinct cases |
| MCP Inspector | Streamable HTTP transport + `Authorization` header | Debugging only |
The safe pattern in every client-specific block below: URL
`https://<your-domain>/worker-mcp`, header
`Authorization: Bearer ${OPENCODE_MCP_BEARER_TOKEN}`, tools
`worker_catalog`, `worker_run`, `worker_status`, `worker_verify`,
`worker_cleanup`.
### OpenAI Codex CLI
```bash
codex mcp add opencode --url "$OPENCODE_MCP_URL" --bearer-token-env-var OPENCODE_MCP_BEARER_TOKEN
```
Codex reads the token from the environment at request time. Codex plugin
bundles do not interpolate environment variables in the server URL, so
register the transport per machine with your concrete URL. There is also
an `opencode-worker` plugin with worker skills, installed from a Git
marketplace pinned at `v0.2.0`:
```bash
codex plugin marketplace add ManuOtel/opencode-mcp-bridge --ref v0.2.0
```
Then install `opencode-worker` from that marketplace and register your
own transport as above (required: the bundled placeholder URL is not
usable). Details: [docs/client-setup.md](docs/client-setup.md) sections
2 and 6. Official docs:
https://developers.openai.com/codex/cli/reference
### Claude Code
Preferred transport (no skills): a project `.mcp.json` entry. Claude
Code expands `${VAR}` references in `url` and `headers` at load time,
so the token stays in the environment and out of the file:
```json
{
"mcpServers": {
"opencode": {
"type": "http",
"url": "${OPENCODE_MCP_URL}",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
CLI alternative (transport only, no skills). Double quotes let the shell
expand the token before Claude Code sees it:
```bash
claude mcp add --transport http opencode "$OPENCODE_MCP_URL" --header "Authorization: Bearer $OPENCODE_MCP_BEARER_TOKEN"
```
Warning: `claude mcp add` writes the resolved header into its local MCP
config, which can persist the token on disk. Prefer the `.mcp.json`
form above on shared hosts, and rotate the token if a config file
leaks.
Prefer the env-var reference form so the token value never lands in
config (see [docs/client-setup.md](docs/client-setup.md) section 3):
```bash
claude mcp add --transport http --header 'Authorization: Bearer ${OPENCODE_MCP_BEARER_TOKEN}' opencode "$OPENCODE_MCP_URL"
claude mcp add --transport http --header 'Authorization: Bearer ${OPENCODE_MCP_BEARER_TOKEN}' opencode-bridge "$OPENCODE_MCP_URL"
```
Recommended path: the `opencode-worker` plugin from this repo's Claude
marketplace (`.claude-plugin/marketplace.json`). It bundles the MCP transport
(URL `${OPENCODE_MCP_URL}`, token `${OPENCODE_MCP_BEARER_TOKEN}`) plus
the `coordinate-opencode-worker` skill. Export both variables before
installing:
```bash
claude plugin marketplace add ManuOtel/opencode-mcp-bridge
claude plugin install opencode-worker@opencode-mcp-bridge
```
There is no npm or Brew package; both marketplaces install from this Git
repo. Details: [docs/client-setup.md](docs/client-setup.md) sections 3
and 7. Official docs: https://docs.anthropic.com/en/docs/claude-code/mcp
### ChatGPT Developer Mode
Developer Mode ON, then Connectors, Create connector, URL mode with
`https://<your-domain>/worker-mcp` plus your Bearer token, then Scan
Tools. Select `https://<your-domain>/mcp` only when you explicitly need
the full legacy catalog or `exec_run`.
Remote MCP connectors need an eligible plan and workspace, and may need
admin approval. Availability depends on your account, not on this repo.
### Cursor
Add to `.cursor/mcp.json` in your project (key names per
https://cursor.com/docs/context/mcp):
```json
{
"mcpServers": {
"opencode-bridge": {
"url": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
### Gemini CLI
Add to `~/.gemini/settings.json` (key names per
https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html):
```json
{
"mcpServers": {
"opencode-bridge": {
"httpUrl": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
### Windsurf
Edit `~/.codeium/windsurf/mcp_config.json`. Windsurf uses `serverUrl`
(not `url`) for remote servers and supports `${env:VAR}` interpolation
in `headers`. Official docs: https://docs.windsurf.com/windsurf/cascade/mcp
```json
{
"mcpServers": {
"opencode-bridge": {
"serverUrl": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${env:OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
Refresh the server list in Cascade after saving.
### Cline
Open MCP Servers, Configure tab, Configure MCP Servers
(`cline_mcp_settings.json`), or use the Remote Servers tab with
Transport Type Streamable HTTP. Official docs:
https://docs.cline.bot/mcp/mcp-overview
```json
{
"mcpServers": {
"opencode-bridge": {
"type": "streamableHttp",
"url": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
Set `"type": "streamableHttp"` explicitly. Omitting it falls back to
legacy SSE transport.
### Roo Code
Client-specific shape; confirm key names in the Roo Code docs for your
version. Minimal standard form:
```json
{
"mcpServers": {
"opencode-bridge": {
"url": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}
```
### Pi
Install the adapter, then add the bridge to the shared
`~/.config/mcp/mcp.json` (key names per
https://pi.dev/packages/pi-mcp-adapter):
```bash
pi install npm:pi-mcp-adapter
```
```json
{
"mcpServers": {
"opencode-bridge": {
"url": "https://<your-domain>/worker-mcp",
"auth": "bearer",
"bearerTokenEnv": "OPENCODE_MCP_BEARER_TOKEN",
"includeTools": ["worker_catalog", "worker_run", "worker_status", "worker_verify", "worker_cleanup"],
"lifecycle": "lazy"
}
}
}
```
The token stays in `OPENCODE_MCP_BEARER_TOKEN`; only the variable name
is stored in the file. Servers are lazy by default and connect on first
tool call. There is no one-click plugin for this bridge; do not claim
one. Adapter version and current syntax:
https://pi.dev/packages/pi-mcp-adapter
### Hermes Agent
Hermes uses YAML `mcp_servers` entries (key names per
https://hermes-agent.nousresearch.com/docs/reference/mcp-config-reference
and https://github.com/hermes-agent-org/hermes/blob/main/website/docs/guides/use-mcp-with-hermes.md):
```yaml
mcp_servers:
opencode-bridge:
url: "https://<your-domain>/worker-mcp"
headers:
Authorization: "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
tools:
include: [worker_catalog, worker_run, worker_status, worker_verify, worker_cleanup]
resources: false
prompts: false
```
Hermes resolves `${VAR}` (or `${env:VAR}`) references from its active
profile secret scope, falling back to the process environment. Put the
token in `~/.hermes/.env`; an unset variable keeps its literal
placeholder. Reload servers with `/reload-mcp` after changing config.
### MCP Inspector (debugging)
```bash
npx @modelcontextprotocol/inspector
```
Select Streamable HTTP transport, enter
`https://<your-domain>/worker-mcp`, and add the `Authorization: Bearer`
header in the Inspector UI. Never use a real token on a machine you do
not control. Docs: https://github.com/modelcontextprotocol/inspector
You can also smoke-test the deployment without a client:
`./scripts/smoke.sh` (see the script header).
## Worker workflow
Lifecycle, in order. There is no `worker_wait` tool; poll instead.
```text
worker_catalog()
worker_run(message="Implement X in /path/to/repo", directory="/path/to/repo", title="feat-x")
worker_status(taskID="<taskID>", directory="/path/to/repo") # repeat until idle
worker_verify(taskID="<taskID>", directory="/path/to/repo")
worker_cleanup(taskID="<taskID>", directory="/path/to/repo")
```
1. Pick a model: `worker_catalog` (free and connected only by default).
Default model is `opencode/muse-spark-1.3-contributor-free`. No paid
models unless explicitly requested for that task. Ordered fallback:
free first, then paid `opencode-go/muse-spark-1.3-contributor`
("Muse Spark 1.3 Contributor") from `worker_catalog.recommendations[1]`.
Paid use must be intentional: pass `providerID`/`modelID` explicitly
only when the boss asked for paid for that task. The bridge never
auto-selects paid.
2. Launch: `worker_run` with `message`, `directory`, `title`, and
optional `requestID` for safe retries. Save `taskID` and `directory`.
3. Poll: `worker_status` with the same `taskID` and `directory` until
`idle`. States: `running` (wait), `idle` (verify), `error`/`unknown`
(recover, see `skills/recover-opencode-task/SKILL.md`).
4. Verify: call `worker_verify`, then inspect the exact diff and run
tests and lint with the host's own tools. Never trust a worker
summary alone.
5. Clean up: `worker_cleanup` (`action=abort` stops, `action=delete`
removes) when done.
Status and messages are directory-scoped: always pass the `directory`
returned by `worker_run` when it differs from the server default, or
status reads `unknown`. When omitted, `worker_status` and
`worker_verify` recover the saved directory from the durable task
registry (`TASK_STATE_PATH`). Tasks are idempotent by `requestID`: same
ID plus same inputs returns the existing task with `deduplicated=true`;
conflicting reuse fails before side effects.
The plugin skills enforce this workflow: Codex
(`delegate-to-opencode`, then `verify-opencode-work`, on failure
`recover-opencode-task`) and Claude Code
(`coordinate-opencode-worker`). Code changes follow
`opencode-git-workflow`.
## Tools
Full signatures: [docs/tool-api.md](docs/tool-api.md).
Worker tools (also the full `/worker-mcp` catalog):
| Tool | What it does |
| --- | --- |
| `worker_run` | Start a background worker. Returns `taskID` (= session ID), state, model, directory, title, `requestID`, `deduplicated`. Prompts before running. |
| `worker_status` | Poll state (`running`/`idle`/`error`/`unknown`) plus latest assistant text only, with truncation counts. Read-only. |
| `worker_catalog` | List models, free and connected only by default, with bridge defaults and ordered `recommendations` (free first, paid fallback second). Read-only. |
| `worker_verify` | Re-check a finished worker (state plus read-only git evidence). Read-only. |
| `worker_cleanup` | Abort (`action=abort`) or delete (`action=delete`) a worker session. Prompts before running. |
Legacy tools (`/mcp` only, advanced compatibility):
`list_providers`, `list_agents`, `create_session`, `send_message`,
`list_sessions`, `get_session`, `list_messages`, `abort_session`,
`delete_session`, `get_diff`, `exec_run` (raw shell, opt-in via
`ENABLE_EXEC_RUN=true`, disabled by default).
Compatibility notes: `send_message` accepts `message`; `prompt` remains
an alias (supply exactly one). `providerID`/`modelID` must be given
together or omitted; when omitted the bridge uses its configured
default. `worker_catalog` filters (`free_only`, `connected_only` default
true, `limit` default 20, cap 100) apply to `models`/`total` only;
`recommendations` is always two entries (free default rank 1, paid
`opencode-go/muse-spark-1.3-contributor` rank 2) so clients can discover
the fallback when the free model is unavailable. `abort_session`, `delete_session`, and `get_diff` are the
full-profile equivalents of `worker_cleanup` and `worker_verify`;
prefer the worker tools.
Per-tool approval ships in `.mcp.json`: `worker_run` and
`worker_cleanup` prompt; `worker_status`, `worker_catalog`, and
`worker_verify` auto-approve. If your client ignores that file, enforce
the same policy in the client config.
## Security
- Treat `MCP_BEARER_TOKEN` like a root password: long random value,
rotate on leak, never commit `.env` or tokens. Generic install steps
never point at another person's server.
- Use `/worker-mcp` for least privilege. It never exposes `exec_run`,
so a leaked token cannot become a direct shell.
- Do not expose `/mcp` or set `ENABLE_EXEC_RUN=true` on an untrusted
deployment. When enabled, plus open directories, anyone with the
Bearer token has a shell where the bridge runs. Prefer session tools
for code edits; reserve `exec_run` for system ops.
- Token rotation (zero downtime): `MCP_BEARER_TOKEN_SECONDARY` accepts
one extra token during overlap. Steps: 1) generate a new token,
2) set it as `MCP_BEARER_TOKEN_SECONDARY` and restart or reload the
bridge, 3) move clients to the new token, 4) promote it to
`MCP_BEARER_TOKEN`, unset the secondary, restart. Blank or duplicate
secondary values fail startup closed. Comparison is constant-time and
token values are never logged.
- `/health` is the only unauthenticated endpoint, plus read-only
RFC 9728 discovery at `GET /.well-known/oauth-protected-resource`
(and its `/mcp` and `/worker-mcp` children, no secrets, no
authorization server). Everything under `/mcp` and `/worker-mcp`
requires the Bearer token.
- Request-body limit: `MCP_MAX_BODY_BYTES` (default 1048576, 1 MiB) caps
the declared `Content-Length` and the actual streamed body on `/mcp`
and `/worker-mcp`. Oversized requests get a generic 413 before any
tool runs. Auth still runs first, so missing tokens stay 401.
- Browser-origin allowlist (optional): `MCP_ALLOWED_ORIGINS` is a
comma-separated exact-origin list (`scheme://host[:port]`, http/https,
no path/query/fragment) for `/mcp` and `/worker-mcp`. Unset or blank
means no origin policy. Absent `Origin` and `Referer` stays allowed
for CLI/SDK clients. Auth runs first (missing tokens stay 401),
`/health` never checks origins, and rejections are a generic 403 with
no secret or header echo.
## Local deployment
Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/), plus a
running `opencode serve` or `opencode web` (see
[OpenCode server docs](https://opencode.ai/docs/server/)).
```bash
git clone https://github.com/ManuOtel/opencode-mcp-bridge.git
cd opencode-mcp-bridge
uv sync
cp .env.example .env
# edit .env: OpenCode credentials + a fresh MCP_BEARER_TOKEN
uv run python -m opencode_mcp_bridge.server
```
Check it: `curl http://127.0.0.1:8087/health` should report OpenCode
healthy. `POST /mcp` and `POST /worker-mcp` without a Bearer token must
return 401.
| Variable | Default | Purpose |
| --- | --- | --- |
| `OPENCODE_BASE_URL` | `http://127.0.0.1:4096` | OpenCode server URL. |
| `OPENCODE_SERVER_USERNAME` | `opencode` | Basic auth user for OpenCode. |
| `OPENCODE_SERVER_PASSWORD` | (required) | Basic auth password of your OpenCode server. |
| `MCP_BEARER_TOKEN` | (required) | Static token clients send as `Authorization: Bearer <token>`. |
| `MCP_BEARER_TOKEN_SECONDARY` | (unset) | Overlap token for rotation; unset means single-token mode. |
| `MCP_HOST` | `127.0.0.1` | Bridge listen address. Use a host IP reachable from your reverse proxy when proxying from Docker. |
| `MCP_PORT` | `8087` | Bridge listen port. |
| `DEFAULT_DIRECTORY` | `$HOME` | Working directory for sessions when clients omit it. |
| `DEFAULT_PROVIDER_ID` | `opencode` | Default provider. |
| `DEFAULT_MODEL_ID` | `muse-spark-1.3-contributor-free` | Default model. |
| `EXEC_TIMEOUT_S` | `120` | Cap for `exec_run` timeouts. |
| `EXEC_MAX_OUTPUT_CHARS` | `20000` | Output truncation cap for `exec_run`. |
| `ENABLE_EXEC_RUN` | `false` | Opt-in for `exec_run` on `/mcp`. Set `true` only where a shell is intended. |
| `TASK_STATE_PATH` | `/var/lib/opencode-mcp-bridge/tasks.json` | JSON registry for durable tasks (atomic writes, bounded records, no prompts or secrets). |
| `MCP_MAX_BODY_BYTES` | `1048576` | Max request body (bytes) for `/mcp` and `/worker-mcp`, declared and streamed; oversized returns generic 413. |
| `MCP_ALLOWED_ORIGINS` | (unset) | Optional exact-origin allowlist for `/mcp` and `/worker-mcp`; unset/blank disables. Single trailing slash stripped. |
Put a reverse proxy with TLS in front. Traefik example:
`deploy/traefik-opencode-mcp.yaml`. Host systemd keeps full terminal
access for `exec_run` (see `deploy/opencode-mcp-bridge.service`, env
file `0640`); Docker scopes `exec_run` to the container
(`docker compose up -d` after filling `.env`). For clean release,
pre/post-deploy checks, rotation, rollback, and log steps, follow
[docs/operations.md](docs/operations.md).
## Contributor workflow
Read [AGENTS.md](AGENTS.md) first: ownership boundaries, edit
discipline, free-model policy, test commands, secrets, worktree and
commit rules, and reporting. The worker playbook lives in `skills/`
(`delegate-to-opencode`, `verify-opencode-work`,
`recover-opencode-task`, `opencode-git-workflow`). Planned work lives in
[docs/roadmap.md](docs/roadmap.md); read phases in order and do not skip
a gate.
```bash
uv sync
uv run pytest
uv run ruff check src tests
uv run ruff format --check src tests
git diff --check
```
CI (`.github/workflows/ci.yml`) runs pull requests on Python 3.14 only,
and pushes to master across Python 3.11, 3.12, 3.13, and 3.14, plus JSON
validation of the Codex and Claude plugin manifests and a no-push
Docker build on master pushes only. `ruff format` in write mode touches Python files: use
`--check` only and report failures instead of fixing them here.
## Publish and discover
Ready in this repo (no secrets committed):
- `server.json`: schema-valid remote Streamable HTTP entry for
`io.github.ManuOtel/opencode-mcp-bridge`, safe `/worker-mcp`
only, auth as a required secret `Authorization` header. The URL
`https://opencode-mcp.manuotel.com/worker-mcp` is the optional community
demo endpoint operated by ManuOtel; it supplies no token. Self-host for
production with your own token.
- `glama.json`: maintainer claim for `ManuOtel`, nothing else.
- Smithery: no checked-in file needed; URL publishing is a
dashboard/CLI flow. Full checklist:
[docs/registry.md](docs/registry.md).
Still requires a human owner login (not done by this change):
- MCP Registry: `mcp-publisher login github` as `ManuOtel`, then
`validate` and `publish` the checked-in `server.json`, which advertises
`https://opencode-mcp.manuotel.com/worker-mcp` (`/worker-mcp` only).
Start here:
[publishing quickstart](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx),
[server.json spec](https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/server-json/generic-server-json.md),
[live API docs](https://registry.modelcontextprotocol.io/docs).
- Glama: add this repo at
[glama.ai/mcp/servers](https://glama.ai/mcp/servers), then Claim
ownership as `ManuOtel` to pick up `glama.json`. Background:
[what is glama.json](https://glama.ai/blog/2025-07-08-what-is-glamajson).
- Smithery: publish at [smithery.ai/new](https://smithery.ai/new)
from your own public HTTPS `/worker-mcp` URL
([docs](https://smithery.ai/docs/build/publish)). This bridge uses
a static Bearer token, not OAuth, so an auth-required endpoint
needs manual review during the Smithery scan: supply the token out
of band. The bridge serves truthful RFC 9728 metadata at
`GET /.well-known/oauth-protected-resource` (plus `/mcp` and
`/worker-mcp` children, no secrets, no authorization server) and
points 401s at it via `WWW-Authenticate`, which fixes the
"not a valid OAuth Protected Resource Metadata response" scan
error without weakening auth. It does not add an OAuth login flow;
that needs a real authorization server and is out of scope.
Listing versus hosting: a registry entry lists the open-source
bridge (repo, docs, install). It never grants access or supplies a token.
The project includes an optional community demo endpoint operated by
ManuOtel at `https://opencode-mcp.manuotel.com/worker-mcp` (`/worker-mcp`
only); production users should self-host with their own HTTPS URL and
token.
Endpoint reminder: `/worker-mcp` (five worker tools, no shell) is
the default for all new clients; `/mcp` (full legacy catalog,
`exec_run` opt-in) is legacy only. Never publish an endpoint you do
not operate, and never commit tokens.
## Community and license
- Read [CONTRIBUTING.md](CONTRIBUTING.md) before you change code or docs.
- Obey the [Code of Conduct](CODE_OF_CONDUCT.md) in all project spaces.
- Report security faults in private per [SECURITY.md](SECURITY.md).
- Open a [bug report or feature
request](https://github.com/ManuOtel/opencode-mcp-bridge/issues/new/choose)
or read [open
issues](https://github.com/ManuOtel/opencode-mcp-bridge/issues).
- Open [pull
requests](https://github.com/ManuOtel/opencode-mcp-bridge/pulls) from
a feature branch, never directly from `master`.
License: PolyForm Noncommercial 1.0.0 - free for noncommercial use and
modification, commercial use needs permission. See [LICENSE.md](LICENSE.md).
For a commercial license, reach out: manuotel@gmail.com
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues