oec.sh

sh.oecv0.1.0更新於 Oct 6, 2026

Operate your oec.sh Odoo servers, projects and environments with your own API key.

已驗證Streamable HTTP可網頁執行Cloud & InfrastructureDeveloper ToolsSecurity & Monitoring

概覽

AI 產生的概覽

讓助理查看並操作你的 oec.sh Odoo 主機服務:伺服器、專案、環境、日誌、指標、部署、重啟與備份。

功能
包裝 oec.sh 公開 API,讓助理列出並讀取伺服器、專案、環境、部署紀錄、備份、Webhook 與任務,並取得即時的 Odoo 或 PostgreSQL 日誌以及 CPU、記憶體、磁碟指標。使用完整存取金鑰時,還能部署、重啟、啟動、停止、快速更新、建立備份,以及建立或修改專案與環境。寫入操作會回傳任務 ID,助理可輪詢直到任務完成。可選擇開啟的工具還包括刪除、還原、Webhook 管理、撤銷 API 金鑰與備份下載連結。
適用情境
當你在 oec.sh 上執行 Odoo,並希望助理不必打開控制台就能檢查環境健康、讀取日誌、追蹤部署,或觸發例行部署、重啟與備份時,適合使用。建議先用唯讀金鑰做診斷,只有在助理確實需要變更時才使用完整存取金鑰。
執行需求
需要 Starter 或以上方案的 oec.sh 組織,以及來自「設定 > API 金鑰」的 API 金鑰;本機模式透過 OECSH_API_KEY 提供,託管模式透過 Authorization Bearer 標頭提供。本機模式需要 Node.js 22 或更新版本與 npm 套件 @oecsh/mcp-server;託管端點為 api.oec.sh。
安裝前請注意
金鑰以明文存放在 MCP 用戶端設定檔中,請勿納入版本控制或出現在螢幕分享中,也不要把金鑰貼到對話裡。完整存取金鑰允許部署、重啟、停止與更新,會替換執行中的程式碼或使網站離線;除非用 OECSH_ALLOW 開啟,破壞性工具預設為關閉。可選的 Webhook 與儲存庫工具可能把資料傳送到外部 URL,或在新儲存庫上執行程式碼。備份下載連結會讓持有者下載整個資料庫,Webhook 密鑰與連結也會留在對話紀錄中。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 oec.sh,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "mcp-server": {
      "type": "http",
      "url": "https://mcp.oec.sh/mcp"
    }
  }
}

README

oec.sh MCP server

Let an AI assistant (Claude Code, Claude Desktop, Cursor and other MCP clients) work with your oec.sh organization: look at servers, projects and environments, read an environment's Odoo logs and live metrics, deploy, restart, update modules, take backups and follow a task to its end.

The server adds no powers of its own. Every tool is one or two calls to the oec.sh Public API made with your API key, so the key's type (read only or full access), its scope (organization or one project), your plan, your quotas and the audit log all apply exactly as they do for any other API client.

Requirements: an oec.sh organization on the Starter plan or higher, and an API key from Settings > API Keys in the dashboard. Local mode needs Node.js 22 or newer.

Choose a key

KeyPrefixWhat the assistant can do
Read only (recommended to start)oec_live_ro_Read tools only
Full accessoec_live_rw_Read tools and write tools (deploy, restart, create...)

A project-scoped key limits the assistant to one project. Use one whenever the assistant only needs to work on one project.

The server reads the key's type from its prefix and only offers the tools that key can use.

Install: local mode (stdio)

The MCP client starts the server on your computer. Your key stays on your computer and is sent only to api.oec.sh.

Claude Code

bash
claude mcp add oecsh -e OECSH_API_KEY=oec_live_ro_your_key -- npx -y @oecsh/mcp-server

Claude Desktop

Add to claude_desktop_config.json (Settings > Developer > Edit Config), then restart Claude Desktop:

json
{  "mcpServers": {    "oecsh": {      "command": "npx",      "args": ["-y", "@oecsh/mcp-server"],      "env": { "OECSH_API_KEY": "oec_live_ro_your_key" }    }  }}

Cursor

Add to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

json
{  "mcpServers": {    "oecsh": {      "command": "npx",      "args": ["-y", "@oecsh/mcp-server"],      "env": { "OECSH_API_KEY": "oec_live_ro_your_key" }    }  }}

Do not commit a file that contains your key.

Settings (local mode)

VariableMeaning
OECSH_API_KEYYour API key. Required.
OECSH_ALLOWOpt-in tools, comma separated: destructive, backup-download. Empty by default.
OECSH_API_URLAPI address. Default https://api.oec.sh/api/public/v1; change only if oec.sh support asks you to.

Hosted mode (streamable HTTP)

https://mcp.oec.sh/mcp. Nothing to install: your client sends your API key with every request in the Authorization header, the server forwards it to the API for that request only, and keeps nothing.

Claude Code:

bash
claude mcp add --transport http oecsh https://mcp.oec.sh/mcp \  --header "Authorization: Bearer oec_live_ro_your_key"

Cursor (mcp.json):

json
{  "mcpServers": {    "oecsh": {      "url": "https://mcp.oec.sh/mcp",      "headers": { "Authorization": "Bearer oec_live_ro_your_key" }    }  }}

To turn on opt-in tools in hosted mode, add the header X-OECSH-Allow: destructive (or backup-download, or both, comma separated).

Clients that only connect through OAuth, such as claude.ai web connectors, cannot use the hosted server yet.

The hosted server at mcp.oec.sh passes your address to the API (it is configured with OECSH_MCP_PROXY_SECRET, see below), so the API's block on repeated refused keys counts your address, not the server's shared one. Rate limits are per API key either way.

Tools

Every tool name starts with oecsh_. List tools take limit (1 to 100, default 20) and cursor (the next_cursor of the previous page) and answer with items, count, total, has_more and next_cursor.

Read tools (any key)

ToolWhat it does
oecsh_get_organizationPlan, limits and current usage
oecsh_list_servers, oecsh_get_serverServers, size, readiness
oecsh_get_server_metricsLive CPU, memory, disk and network of one of your own servers (not shared servers)
oecsh_list_projects, oecsh_get_projectProjects
oecsh_list_environmentsA project's environments, optionally by status
oecsh_get_environmentOne environment with its health and last deploy
oecsh_get_runtime_logsThe newest lines (up to 1000) of an environment's Odoo or PostgreSQL log, read live from its server
oecsh_get_environment_metricsLive CPU and memory of an environment's containers, and its disk sizes
oecsh_list_deploymentsAn environment's deploy history
oecsh_get_taskAny task's status and progress
oecsh_wait_for_taskWaits until a task finishes
oecsh_get_task_logA task's step log and error
oecsh_list_backups, oecsh_get_backupAn environment's backups; one backup
oecsh_list_webhooks, oecsh_get_webhook, oecsh_list_webhook_deliveriesOutgoing webhooks and their recent deliveries

Write tools (full-access key; none of them deletes data)

ToolWhat it does
oecsh_deploy_environmentPulls the branch and redeploys; can update modules
oecsh_restart_environment, oecsh_start_environment, oecsh_stop_environmentRestart, start, stop
oecsh_quick_update_environmentPull and restart, update all modules, or update some
oecsh_create_backupStarts a manual backup
oecsh_create_project, oecsh_update_projectProjects (creating needs an organization-scoped key). Changing a project's repository or git provider is an opt-in tool
oecsh_create_environment, oecsh_update_environmentEnvironments

oecsh_create_webhook and oecsh_rotate_webhook_secret return the webhook's signing secret, because the API shows it only once. The secret is then in your conversation transcript, and the tool result says so: if the transcript is shared or stored where others can read it, rotate the secret in the dashboard (Settings > Webhooks) and give the new one to the receiver yourself. Rotating it through the assistant would put the new secret in the transcript too.

Write tools that start work return a task_id; the assistant follows it with oecsh_wait_for_task. Deploy, restart, stop, quick update and the two update tools are marked destructive (they replace running code, take a site offline or overwrite settings), so clients that honour the hint ask before running them; the create tools and start are not.

Opt-in tools

Off unless you turn them on. Each is marked destructive, which is only a hint: most clients then ask for your approval, unless you have auto-approved the tool. Keep these tools out of your client's auto-approve or allow list.

They also take a confirm argument (confirm_environment_name for a restore) that must repeat the resource's name exactly, and the server checks it against the real resource before doing anything. For deleting a webhook or rotating its secret, the name is the webhook's URL. For creating a webhook, testing one, or changing its URL, it is the host the data goes to (for https://hooks.example.com/oec, type hooks.example.com), as the server reads it from the URL: in https://[email protected]/ that is other.example. Changing a webhook's other settings needs no confirm. The assistant is told to ask you for that name, but it can also read names through the list tools, so the argument alone cannot prove that you typed it. So when your client supports MCP elicitation (it can show you a form from the server), the server also asks you to type the name in your client's own prompt, which names the action and the resource, and goes ahead only if you accept and the name matches. Declining, or typing something else, changes nothing. Clients without elicitation, and the hosted server (which keeps no session, so it cannot ask), rely on the confirm argument alone.

Opt-inToolsKey
destructiveoecsh_delete_environment, oecsh_delete_project, oecsh_delete_webhook, oecsh_rotate_webhook_secret, oecsh_revoke_api_key, oecsh_reinitialize_modules, oecsh_restore_backup, oecsh_update_project_repository, oecsh_create_webhook, oecsh_update_webhook, oecsh_test_webhookFull access (revoking keys and deleting projects: organization-scoped)
backup-downloadoecsh_get_backup_download_links (links to a full database dump, valid 5 minutes by default, at most 60)Any

Creating, changing and testing webhooks are opt-in because a webhook sends oec.sh data to whatever HTTPS URL it names, and the test sends it at once: text that someone else wrote into a result (an Odoo log line, say) could ask the assistant to point one at their own address. Changing a project's repository or git provider (oecsh_update_project_repository) is opt-in for the same reason: every later deploy runs code from the new repository on your server, and the git provider decides which host your organization's git token is sent to. oecsh_update_project changes everything else about a project. Branch names (branch, default_branch) must be real branch names: ref paths such as refs/..., pull/... or merge-requests/..., bare commit ids and names starting with - are refused, so a deploy cannot pick up code from a fork's pull request.

oecsh_get_backup_download_links answers with a warning: anyone holding a link can download the whole database until it expires, and the links are now in the conversation transcript.

With a read-only key the server offers 19 tools (20 with backup-download). With a full-access key it offers 29, 40 with destructive, and 41 with both opt-ins.

oecsh_restore_backup overwrites an environment's database and files with a completed backup of that same environment (a safety backup of the current data is taken first) and returns a task to follow. The name to type, for a restore or for download links, is the environment's current name; for a stopped or broken environment, which the API does not list, it is the name recorded with the backup (see oecsh_get_backup). Restoring into another environment stays in the dashboard.

Server registration tokens are not available through this server.

Limits

  • Every API request counts against your key's rate limit: 120 reads and 20 writes a minute, counted separately.
  • Most tools make one or two API requests. oecsh_get_backup_download_links and oecsh_restore_backup make three, and each other confirmed destructive tool two (it reads the resource first to check the name), except creating a webhook or changing its URL, which check the host in the URL given and make one.
  • oecsh_get_runtime_logs, oecsh_get_environment_metrics and oecsh_get_server_metrics reach your server on every call, so the API allows 6 of each a minute per environment or server.
  • oecsh_wait_for_task polls the task every 5 seconds for the first 30 seconds, then every 10 seconds, and never spends more than a fifth of the read limit the API reports for your key (with a limit of 20 a minute, one poll every 15 seconds). Each call waits up to 50 seconds, since many clients give up on a tool call after 60 seconds, and up to 45 seconds in hosted mode; the assistant calls it again while the task runs. In local mode it waits up to 10 minutes when the client asks for progress notes (it then sends one after every poll) or the assistant passes a longer timeout_seconds.
  • When a limit is reached the tool says how long to wait, from the API's Retry-After (or, without it, until the next full minute). A wait of 10 seconds or less is retried once by itself, and oecsh_wait_for_task sits out a wait that fits in its time limit.
  • If the answer to an action (deploy, restart, restore...) is lost on the network, the server asks once more with the same idempotency key, so the API returns the first answer instead of starting the action twice.
  • oecsh_get_task_log returns up to 1000 lines of a task's own log; oecsh_get_runtime_logs returns the Odoo or PostgreSQL log. Either is cut to its newest 60,000 characters (with truncated set), so one answer stays within what clients accept.
  • Running, stopped, paused and errored environments are all visible. A deleted environment answers "not found"; its backups and tasks stay readable.
  • Each API request times out after 30 seconds. The hosted server accepts request bodies up to 1 MB.

Security notes

  • The key is checked for the right format before any call, sent only in the Authorization header to the configured API, and removed from every output, error and log line. The server never prints it.
  • The API address must use https (plain http only to localhost), and the server never follows a redirect, so the key cannot be sent in clear text or replayed to another address.
  • In hosted mode the API address is fixed by the server; a client cannot point your key at another host. Requests without a well-formed key are refused before the body is read, and a key the API has just refused is refused locally for 5 minutes. The API blocks an address for 15 minutes after 10 refused keys, so tool calls with keys the server has not yet seen working stop at 6 possible refusals until the API's count has run out; keys that worked recently are not held back. That count is kept per caller address when the server passes caller addresses to the API (OECSH_MCP_PROXY_SECRET), and once for the whole server when it does not, since the API then sees every hosted user at the server's one address. Only hashes of keys are kept in memory. Each request carries one JSON-RPC message (batches are refused).
  • Every id an assistant passes is checked to be a UUID before it goes into a request.
  • Backups the assistant starts go only to your organization's own storage; the API refuses a storage location that belongs to another organization.
  • Names, notes, branch names and log text in results are your data. They are returned as data, and the server tells the assistant not to follow instructions found in them. Results that carry text others wrote (runtime and task logs, task error messages, deploy history, backup notes and snapshots) have a notice field before that text saying so, and those tools are marked open-world. Webhook delivery lists leave out the body your receiving URL answered with, since whoever runs that URL writes it.
  • In hosted mode at most 3 tool calls per key, and 10 per caller address, run at the same time; more get a "too many tool calls" error. Error messages there name "the oec.sh API" rather than the address the server uses, and leave out answers that are not the API's own JSON.
  • Never paste your API key into the chat. The assistant does not need it: the server reads it from its configuration, and anything typed into the chat stays in the transcript.
  • MCP client configuration files (claude_desktop_config.json, ~/.claude.json, mcp.json and the like) store the key in plain text. Keep them out of version control, backups you share and screen shares.
  • With Claude Code, do not add the server with --scope project: that writes the key into .mcp.json in the project, which is meant to be committed. Use the default (local) or --scope user.
  • Destructive and sensitive tools are off by default. Prefer a read-only, project-scoped key, and give the assistant a full-access key only when it needs to change things.
  • Revoke a key at once if it leaks: Settings > API Keys.

Running the HTTP server yourself

bash
docker build -t oecsh-mcp ./mcp-serverdocker run -p 127.0.0.1:8080:8080 -e OECSH_MCP_ALLOWED_HOSTS=localhost oecsh-mcp

The origin must be reachable only through your proxies (for mcp.oec.sh: Cloudflare, then Traefik). Publish the port on loopback, or only on the proxy's Docker network, and never on a public interface: the caller address the server passes to the API, and its per-address limits, rely on the proxy in front.

In production set OECSH_MCP_ALLOWED_HOSTS to the public host name (for example mcp.oec.sh). On a bind other than loopback the server refuses to start without it, unless OECSH_MCP_ALLOW_ANY_HOST=1 is set.

VariableDefaultMeaning
OECSH_MCP_HOST127.0.0.1 (0.0.0.0 in the image)Bind address
OECSH_MCP_PORT8080Port
OECSH_API_URLhttps://api.oec.sh/api/public/v1API the keys are sent to. Must use https, except to localhost
OECSH_API_ALLOW_HTTP(off)1 allows plain http to a non-loopback OECSH_API_URL, for an API on the same internal network only
OECSH_MCP_MAX_BODY_BYTES1048576Largest request body
OECSH_MCP_ALLOWED_HOSTS(none)Host names to accept, comma separated. On a loopback bind, localhost, 127.0.0.1 and [::1] are always accepted and every other Host is refused. Required on any other bind.
OECSH_MCP_ALLOW_ANY_HOST(off)1 accepts any Host header on a non-loopback bind (DNS rebinding protection then rests on the Origin check alone)
OECSH_MCP_ALLOWED_ORIGINS(none)Browser origins to accept. Requests without an Origin header are not affected.
OECSH_MCP_PROXY_SECRET(none)A secret of at least 32 printable ASCII characters, no spaces (for example openssl rand -hex 32), shared with the API. When set, every API request carries X-OECSH-MCP-Proxy: <secret> and X-OECSH-Client-IP: <caller's address>, and the API counts refused keys against the caller instead of this server. Sent only to OECSH_API_URL, never logged and never returned. Unset: neither header is sent. Set PLATFORM_MCP_PROXY_SECRET on the API to the identical value first: the API ignores the headers when its value is empty or different, and this server cannot tell, so all hosted users would again share one count. This works only against an API you configure; a self-hosted server pointed at api.oec.sh should leave it unset.
OECSH_MCP_CLIENT_IP_HEADERcf-connecting-ipRequest header that holds the caller's address, set by the proxy in front of this server. It is believed only when the hop in front of the local proxy (the last X-Forwarded-For entry, which Traefik appends; read only when the connection comes from a private address or a trusted proxy) is in Cloudflare's published ranges or in OECSH_MCP_TRUSTED_PROXIES. Otherwise, or when the value is not one IPv4 or IPv6 address, that hop is the caller's address. Addresses are passed on in one form (IPv6 compressed, IPv4-mapped IPv6 as IPv4).
OECSH_MCP_TRUSTED_PROXIES(none)Extra proxies, comma separated addresses or CIDR ranges, whose client address header is believed and which may connect to the server directly.

Endpoints: POST /mcp (MCP, stateless, JSON responses) and GET /healthz. Put it behind a proxy that terminates TLS and limits connections per address.

Development

bash
cd mcp-servernpm installnpm run buildnpm testnpx @modelcontextprotocol/inspector -e OECSH_API_KEY=oec_live_ro_... node dist/stdio.js

The package does not depend on the rest of the oec.sh repository.

Licence

MIT, see LICENSE. Copyright (c) 2026 OpenEduCat Inc. To report a security problem, see SECURITY.md.

Odoo is a trademark of Odoo S.A. oec.sh is not affiliated with Odoo S.A.

來源:README.md,提交 544d3ed

工具

0
工具後設資料尚未被收錄。

版本歷史

1
  1. v0.1.0最新Oct 6, 2026