Otask Server
FreeNot checkedMCP server and HTTP proxy for O!task API that enables managing tasks (get, update) through natural language.
About
MCP server and HTTP proxy for O!task API that enables managing tasks (get, update) through natural language.
README
MCP-сервер для O!task API. Отдаёт операции O!task (воркспейс/задачи) как MCP-инструменты для агентов (Claude, Cursor, OpenCode, n8n MCP Client Tool).
🚀 Возможности
- stdio — локальный MCP для Claude Desktop / Cursor / OpenCode
- HTTP gateway / passthrough — Streamable HTTP для n8n и self-host
- Remote MCP (Cloudflare Worker) — OAuth-логин O!task, без пароля в конфиге клиента
- Allow-list workspace/project, defaults, inbox-сценарии (
otask_list_tasks) - Open source: grigoreo-dev/otask-mcp
npm i -g @grigoreo-dev/otask-mcp
# или: npx @grigoreo-dev/otask-mcp
# HTTP: npx otask-mcp-http # bin name stays unscoped
Публикация на npm: push tag vX.Y.Z (версия в tag = package.json). CI: .github/workflows/publish.yml (OIDC Trusted Publisher, без NPM_TOKEN).
🔒 Приватность и доверие
Касается Cloudflare Worker (remote MCP) и библиотеки @cloudflare/workers-oauth-provider:
| Что | Где | Кто видит |
|---|---|---|
| Пароль O!task | только memory на POST /authorize |
нигде не пишется (ни KV, ни env, ни git) |
Токен O!task + scope (props) |
grant в Cloudflare KV (OAUTH_KV) |
end-to-end encrypted: ключ шифрования — секрет access-токена MCP; из сырого KV нельзя прочитать props без валидного Bearer |
| userId | KV, не зашифрован | HMAC-SHA256(email, secret pepper) — не email; без секрета USER_ID_PEPPER перебором по словарю email не сматчить |
| metadata | KV, не зашифрован | пусто ({}) — email в хранилище не пишется |
| Access token MCP | у клиента (Claude и т.д.) | клиент + тот, кто перехватит Bearer |
- Пароль не хранится после логина: email+password →
POST api.otask.ru/.../login→ API-токен → вprops, пароль drop. - O!task Bearer нужен для запросов к API → лежит в encrypted
props, не в открытом виде. userId = HMAC-SHA256(email, USER_ID_PEPPER): стабильный id (повторный логин заменяет старый grant), но email в KV нет и хэш не перебрать без секрета.- Публичный Worker без
OTASK_*/MCP_AUTH_TOKENв env: multi-user, каждый — своя OAuth-сессия. - После expiry/401 — повторный Connect (re-login).
- Код open source: self-deploy и аудит. Паттерн: Remote MCP on Cloudflare.
- Официальный URL:
https://otask-mcp.grigoreo.dev/mcp.
Доверие к оператору Worker: в хранилище нет ни пароля, ни email plaintext, а O!task-токен — только encrypted props. Но владелец Cloudflare-аккаунта может сменить код Worker (залогировать ctx.props / токен на своём деплое). Гарантия — открытый код: не доверяете чужому demo → self-deploy.
Не кладите OTASK_PASSWORD, OTASK_AUTH_KEY и токены в git, скриншоты и issue.
☁️ Remote MCP (Cloudflare)
Официальный публичный endpoint:
https://otask-mcp.grigoreo.dev/mcp
Multi-user OAuth, OTASK_* в env Worker нет. Self-host: см. 🔧 Self-deploy Worker.
Подключение (OAuth)
- В MCP-клиенте добавьте remote server с URL
…/mcp. - Запустите Connect / OAuth flow клиента.
- На странице логина Worker введите email + password O!task.
- После успешного authorize клиент получает access token сессии MCP; вызовы
/mcpидут с этим токеном. - Default workspace/project — на форме логина (или явные
ws_slug/ project args в tools). Self-host stdio/HTTP: envOTASK_DEFAULT_*.
На публичном Worker нет OTASK_* в env: multi-user, credentials только в сессии пользователя.
💻 stdio (локально)
Локальный процесс; credentials только из env сервера.
OTASK_AUTH_KEY=...
# или OTASK_EMAIL + OTASK_PASSWORD
OTASK_DEFAULT_WS=...
OTASK_DEFAULT_PROJECT=my-project
OTASK_ALLOWED_WS=...
OTASK_ALLOWED_PROJECTS=my-project
bun start
# или: npx @grigoreo-dev/otask-mcp
stdio требует OTASK_* (без них падает при старте).
🐳 Docker / HTTP
bun run start:http
# Docker: образ из Dockerfile, PORT=3847
| MCP | POST/GET /mcp (Streamable HTTP) |
| Health | GET /health → { ok, mode, authMode, projectGuard, wsGuard, defaults } ("env" | "header" | "off") |
Пример self-host: https://otask-mcp.example/mcp (порт 3847 в Docker).
Gateway (credentials O!task на сервере)
OTASK_AUTH_KEY=...
MCP_AUTH_TOKEN=...
OTASK_DEFAULT_WS=...
OTASK_DEFAULT_PROJECT=...
OTASK_ALLOWED_WS=...
OTASK_ALLOWED_PROJECTS=...
Клиент: Authorization: Bearer <MCP_AUTH_TOKEN> (не токен O!task). Не шлите X-Otask-* allow/default (берутся из env).
Passthrough (токен O!task у клиента)
Env сервера: без OTASK_AUTH_KEY / OTASK_EMAIL / OTASK_PASSWORD.
Клиент: Authorization: Bearer <токен api.otask.ru>. Опционально: X-Otask-Allowed-Projects, X-Otask-Allowed-Ws, X-Otask-Default-Ws, X-Otask-Default-Project.
Проверка: GET /health → authMode: "gateway" | "passthrough".
🔀 Режимы auth
| Режим | Где | Команда / URL | Авторизация клиента |
|---|---|---|---|
| stdio | локально | bun start / otask-mcp |
Нет HTTP; OTASK_* в env процесса |
| HTTP gateway | Node/Docker | bun run start:http |
Authorization: Bearer <MCP_AUTH_TOKEN>; на сервере есть OTASK_* |
| HTTP passthrough | Node/Docker | bun run start:http |
Authorization: Bearer <токен O!task>; нет OTASK_* в env |
| remote Worker | Cloudflare | https://…/mcp + OAuth |
OAuth Connect → логин email+password на Worker; API-токен в сессии, не в env Worker |
Определение HTTP (Node): hasServerOtaskCredentials() — gateway, если задан статический ключ или email+password; иначе passthrough. HTTP gateway требует MCP_AUTH_TOKEN, если заданы OTASK_* (иначе падает при старте).
🤖 Промпты для агентов
Скопируйте блок в чат агента.
Claude web → официальный URL (https://otask-mcp.grigoreo.dev/mcp)
Подключи remote MCP сервер O!task:
- URL: https://otask-mcp.grigoreo.dev/mcp
- Используй OAuth / Connect flow клиента
- Default workspace/project задаются на форме логина Worker (или явными args tools)
Не сохраняй мой пароль в файлы репозитория.
Cursor → официальный URL
Добавь в MCP config Cursor remote server O!task:
url: https://otask-mcp.grigoreo.dev/mcp
auth: oauth
После connect проверь otask_me.
Self-deploy Worker
Задеплой otask-mcp Worker из репозитория grigoreo-dev/otask-mcp:
1) bun install; bun run build (из корня)
2) wrangler login (один раз)
3) bun run deploy:worker # KV OAUTH_KV создаётся автоматически
4) Дай мне URL /mcp и пропиши в MCP клиент с OAuth
Docker passthrough
Подними otask-mcp HTTP passthrough в Docker без OTASK_* в env.
Клиент шлёт Authorization: Bearer <O!task token>.
PORT 3847. Проверь GET /health.
stdio local
Установи @grigoreo-dev/otask-mcp, настрой stdio MCP с OTASK_EMAIL+OTASK_PASSWORD
или OTASK_AUTH_KEY. Добавь в Claude Desktop / Cursor mcp servers.
Gateway self-host
HTTP gateway: задай OTASK_* + MCP_AUTH_TOKEN.
Клиент шлёт Bearer MCP_AUTH_TOKEN, не токен O!task.
🔧 Self-deploy Worker
Пакет: packages/worker (не публикуется на npm). Подробнее: packages/worker/README.md.
# из корня репозитория
bun install
bunx wrangler login # один раз (браузер, без API-токена)
# секрет для HMAC userId (email не хранится в KV в переборно-открытом виде)
bunx wrangler secret put USER_ID_PEPPER --config packages/worker/wrangler.toml
bun run deploy:worker # build + deploy; KV OAUTH_KV создаётся автоматически
Подробнее (GH Actions, Workers Builds из git, secrets): packages/worker/README.md.
- Endpoint MCP:
https://otask-mcp.<ваш-subdomain>.workers.dev/mcp(или свой custom domain, как официальныйhttps://otask-mcp.grigoreo.dev/mcp) - OAuth:
/authorize,/oauth/token,/oauth/register - Не задавайте
OTASK_*в[vars]для multi-user публичного деплоя - GitHub Actions (кнопка Deploy): нужны secrets
CLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_ID - Cloudflare Workers Builds (git в dashboard): токен в GitHub не нужен — CF GitHub App; build из monorepo
Rate limiting — в dashboard Cloudflare (см. worker README), не в коде v1.
Переменные окружения
| Переменная | Где используется | Когда обязательна | Назначение |
|---|---|---|---|
OTASK_AUTH_KEY |
stdio, HTTP gateway | stdio или gateway (альтернатива: email/password) | Статический O!task Bearer, которым пользуется сервер |
OTASK_EMAIL |
stdio, HTTP gateway | вместе с OTASK_PASSWORD как альтернатива ключу |
Логин для получения токена |
OTASK_PASSWORD |
stdio, HTTP gateway | вместе с OTASK_EMAIL |
Пароль для логина |
MCP_AUTH_TOKEN |
HTTP gateway | режим gateway | Общий секрет, который должен отправлять клиент; не токен O!task |
OTASK_DEFAULT_WS |
stdio, HTTP | опционально | Workspace slug по умолчанию (если tool не передал ws_slug) |
OTASK_DEFAULT_PROJECT |
stdio, HTTP | опционально | Project slug или numeric id по умолчанию |
OTASK_ALLOWED_WS |
stdio, HTTP gateway | опционально | Allow-list workspace slug через запятую |
OTASK_ALLOWED_PROJECTS |
stdio, HTTP gateway | опционально | Allow-list project slug и/или numeric id через запятую |
PORT |
HTTP | опционально (по умолчанию 3847) |
Порт прослушивания |
HOST |
HTTP | опционально (по умолчанию 0.0.0.0) |
Адрес привязки |
Default должен входить в allow-list, если list непустой (иначе сервер падает при старте).
Remote Worker: user credentials не через эти env (OAuth-сессия).
HTTP-заголовки
| Заголовок | Режим | Назначение |
|---|---|---|
Authorization: Bearer … |
gateway | Должен совпадать с MCP_AUTH_TOKEN |
Authorization: Bearer … |
passthrough | Токен O!task API; проксируется на каждый запрос к API |
Authorization: Bearer … |
remote Worker | Access token OAuth-сессии MCP (после Connect) |
X-Otask-Allowed-Projects |
только passthrough | Allow-list projects; в gateway — env |
X-Otask-Allowed-Ws |
только passthrough | Allow-list workspaces |
X-Otask-Default-Ws |
passthrough (override env) | Default workspace slug |
X-Otask-Default-Project |
passthrough (override env) | Default project slug/id |
Примеры для n8n
Gateway
- URL:
https://otask-mcp.example/mcp - Transport: HTTP Streamable
- Credential / header:
Authorization: Bearer <MCP_AUTH_TOKEN> - Не отправляйте
X-Otask-*allow/default headers
Passthrough
- URL:
https://otask-mcp.example/mcp - Transport: HTTP Streamable
- Credential / header:
Authorization: Bearer <токен api.otask.ru> - Опционально:
X-Otask-Allowed-*,X-Otask-Default-*
Инструменты
Регистрируются в packages/core/src/tools/registry.ts:
| Инструмент | Назначение |
|---|---|
otask_me |
Текущий пользователь (id, имя, email, timezone) |
otask_list_tasks |
Задачи воркспейса; по умолчанию mine=true; фильтры performer_ids, project_ids, priority_ids, due, page |
otask_get_task |
Получить одну задачу по workspace + slug задачи |
otask_update_task |
Обновить существующую задачу |
otask_list_projects |
Список проектов воркспейса (с фильтром по allow-list) |
otask_list_project_tasks |
Задачи проекта: по умолчанию активные задачи из UI board snapshot; active_only=false для полного legacy-списка |
otask_list_board |
Доски/колонки (статусы) с type, is_system, tasks_count; type=completed помечает завершённую колонку |
otask_list_members |
Участники воркспейса |
otask_list_tags |
Теги воркспейса |
otask_list_comments |
Комментарии к задаче |
otask_add_comment |
Добавить комментарий (parent_id для ответов) |
otask_create_task |
Создать задачу (name, board_id, board_column_id, end_at, …) |
otask_move_task |
Переместить задачу в другую колонку |
otask_archive_task |
Архивировать задачу |
Inbox (после OTASK_DEFAULT_WS):
otask_me
otask_list_tasks # mine=true
otask_list_tasks due=today
otask_list_tasks due=overdue
Defaults и allow-list (ws + projects)
| Что | Env (gateway/stdio) | Header (passthrough) |
|---|---|---|
| Default workspace | OTASK_DEFAULT_WS |
X-Otask-Default-Ws (override) |
| Default project | OTASK_DEFAULT_PROJECT (slug или id) |
X-Otask-Default-Project |
| Limit workspaces | OTASK_ALLOWED_WS |
X-Otask-Allowed-Ws |
| Limit projects | OTASK_ALLOWED_PROJECTS |
X-Otask-Allowed-Projects |
Формат allow-list: значения через запятую. Projects: slug и/или numeric id. WS: только slug. Пусто = off.
otask_list_board по умолчанию шлёт type=status (так требует O!task API).
Снимок API-документации
bun run docs:parse
Пишет в docs/catalog/ (или bun run docs:parse --file path для офлайн HTML).
Разработка
Монорепо: packages/core, packages/stdio, packages/http-node, packages/worker.
bun install
bun run build # core → stdio → http-node
bun test
bun start # stdio MCP
bun run start:http # Streamable HTTP MCP
bun run dev # stdio hot reload
bun run dev:http # HTTP hot reload
Добавление инструмента
packages/core/src/services/api.ts/client.ts— метод API при необходимостиpackages/core/src/schemas/— Zod input schemapackages/core/src/tools/my-tool.ts— factory →ToolDefinitionpackages/core/src/tools/registry.ts— добавить вtoolFactories
Contributing
See CONTRIBUTING.md for setup, PR checks, and the release tag flow.
Install Otask Server in Claude Desktop, Claude Code & Cursor
unyly install otask-mcp-serverInstalls into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.
First time? Get the CLI: curl -fsSL https://unyly.org/install | sh
Or configure manually
Run in your terminal:
claude mcp add otask-mcp-server -- npx -y @grigoreo-dev/otask-mcpFAQ
Is Otask Server MCP free?
Yes, Otask Server MCP is free — one-click install via Unyly at no cost.
Does Otask Server need an API key?
No, Otask Server runs without API keys or environment variables.
Is Otask Server hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Otask Server in Claude Desktop, Claude Code or Cursor?
Open Otask Server on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Notion
Read and write pages in your workspace
by NotionLinear
Issues, cycles, triage — from Claude
by LinearGoogle Drive
Search and read your Drive files
by Googlemindsdb/mindsdb
Connect and unify data across various platforms and databases with [MindsDB as a single MCP server](https://docs.mindsdb.com/mcp/overview).
by mindsdbCompare Otask Server with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All productivity MCPs
