Skip to main content
Glama
otask-mcp-server

otask-mcp-server

by grigoreo-dev

otask-mcp-server

MCP-сервер для O!task API. Отдаёт операции O!task (пространства/задачи) как MCP-инструменты для агентов (Claude, Cursor, OpenCode, n8n MCP Client Tool).

Неофициально. otask-mcp — независимый open-source MCP-коннектор к API O!task. Не аффилирован с O!task, не является его частью и не поддерживается им.

Unofficial. otask-mcp is an independent open-source MCP connector for the O!task API. Not affiliated with, endorsed by, or part of the O!task product/team.

🚀 Возможности

  • stdio — локальный MCP для Claude Desktop / Cursor / OpenCode

  • HTTP gateway / passthrough — Streamable HTTP для n8n и self-host

  • Remote MCP (Cloudflare Worker) — OAuth-логин O!task (2-step wizard), без пароля в конфиге клиента

  • Allow-list пространство/project, defaults, inbox-сценарии (otask_list_tasks)

  • Discovery: otask_list_workspaces (пространства без ручного slug)

  • 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).

Related MCP server: @ticktick-ecosystem/mcp-server

🔒 Приватность и доверие

Неофициально: otask-mcp — независимый open-source коннектор, не продукт O!task и не поддерживается им.

Касается 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)

Лендинг (что это за коннектор, как подключаться):

https://otask-mcp.grigoreo.dev/
  1. Откройте лендинг https://otask-mcp.grigoreo.dev/ — краткое описание Remote MCP и URL /mcp (это не 404).

  2. В MCP-клиенте добавьте remote server с URL https://otask-mcp.grigoreo.dev/mcp (или свой self-deploy …/mcp).

  3. Запустите Connect / OAuth flow клиента.

  4. Шаг 1: ввод email + пароль O!task.

  5. Шаг 2: выбор пространства по умолчанию, проекта и (опционально) разрешённых пространств/проектов из выпадающих списков — вручную вводить UUID-slug больше не нужно.

  6. Пустой список разрешённых = доступ ко всем пространствам/проектам аккаунта (без allow-list ограничения).

  7. После успешного authorize клиент получает access token сессии MCP; вызовы /mcp идут с этим токеном.

Явные ws_slug / project args в tools по-прежнему работают. Self-host stdio/HTTP: env OTASK_DEFAULT_*. Про UUID-slug vs #N на доске: docs/SLUGS.md.

На публичном 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
- Лендинг: https://otask-mcp.grigoreo.dev/
- Используй OAuth / Connect flow клиента (2 шага: логин → выбор пространства/проекта)
- Default пространство/project задаются на шаге 2 wizard (или явными args tools)
- Для discovery: otask_list_workspaces, otask_list_projects
Не сохраняй мой пароль в файлы репозитория.

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

опционально

Slug пространства по умолчанию (UUID; если tool не передал ws_slug)

OTASK_DEFAULT_PROJECT

stdio, HTTP

опционально

Project slug (UUID) или numeric id по умолчанию

OTASK_ALLOWED_WS

stdio, HTTP gateway

опционально

Allow-list 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 пространств

X-Otask-Default-Ws

passthrough (override env)

Default 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_workspaces

Список пространств (teams); без slug; при одном пространстве агент/резолвер может подставить его автоматически

otask_list_tasks

Задачи пространства; по умолчанию mine=true; фильтры performer_ids, project_ids, priority_ids, due, page

otask_get_task

Получить одну задачу по пространству + 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

Архивировать задачу

Про UUID-slug vs номера досок #N: docs/SLUGS.md.

Inbox (после OTASK_DEFAULT_WS):

otask_me
otask_list_tasks  # mine=true
otask_list_tasks due=today
otask_list_tasks due=overdue

Defaults и allow-list (пространства + projects)

Что

Env (gateway/stdio)

Header (passthrough)

Default пространство

OTASK_DEFAULT_WS

X-Otask-Default-Ws (override)

Default project

OTASK_DEFAULT_PROJECT (slug или id)

X-Otask-Default-Project

Limit пространств

OTASK_ALLOWED_WS

X-Otask-Allowed-Ws

Limit projects

OTASK_ALLOWED_PROJECTS

X-Otask-Allowed-Projects

Формат allow-list: значения через запятую. Projects: slug (UUID) и/или numeric id. Пространства: только slug (UUID). Пусто = без ограничения (off). Подробнее: docs/SLUGS.md.

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

Добавление инструмента

  1. packages/core/src/services/api.ts / client.ts — метод API при необходимости

  2. packages/core/src/schemas/ — Zod input schema

  3. packages/core/src/tools/my-tool.ts — factory → ToolDefinition

  4. packages/core/src/tools/registry.ts — добавить в toolFactories

Contributing

See CONTRIBUTING.md for setup, PR checks, and the release tag flow.

Available Tools

2 tools
otask_get_taskGet O!task TaskA
Read-onlyIdempotent

Fetch a task from O!task by workspace and task slug.

Use before otask_update_task to inspect current field values (board_id, performers, tags, etc.).

Args:

  • ws_slug: Workspace UUID from panel.otask.ru URL (/ws/{ws_slug}/...)

  • task_slug: Task UUID from URL (.../tasks/{task_slug})

Returns JSON with key task fields: id, slug, name, description, end_at, board_id, board_column_id, priority_id, project_id, performers, tags.

Docs: https://api.otask.ru/docs#zadaci-GETapi-v1-ws--ws_slug--tasks--task_slug

Inputs: ws_slug (required), task_slug (required).

otask_update_taskUpdate O!task TaskA

Update an existing O!task task. Sends POST /api/v1/ws/{ws_slug}/tasks/{task_slug}/update.

The O!task API requires a full task payload. This tool fetches the current task, merges your changes, then submits the update. Only pass fields you want to change.

Common updates:

  • board_column_id: move task to another column/status

  • name, description, end_at, priority_id

  • performers, tags, subtasks, files

  • comment: optional note recorded with the update

Args:

  • ws_slug, task_slug: UUIDs from panel.otask.ru

  • Any task fields to change (all optional except slugs)

Returns updated task summary on success.

Docs: https://api.otask.ru/docs#zadaci-POSTapi-v1-ws--ws_slug--tasks--task_slug--update

Inputs: ws_slug (required), task_slug (required), name, tags, +10 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 2 tools

    Disambiguation5/5

    The two tools have completely distinct purposes: one retrieves a task's current state, the other updates it. There is no overlap or ambiguity between them.

    Naming Consistency5/5

    Both tools follow the same 'otask_verb_task' pattern with snake_case, using 'get' and 'update' as clear verbs. Perfectly consistent.

    Tool Count2/5

    With only two tools (get and update), the server feels extremely limited for a task management API. Typical CRUD operations (create, delete, list) are missing, making the tool count too low for the apparent domain.

    Completeness1/5

    The tool surface is severely incomplete. Basic operations like creating, deleting, and listing tasks are absent. An agent cannot perform end-to-end task management with only get and update.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers