NODEDC_TASKMANAGER_CODEXAPI/README.md

5.4 KiB
Raw Blame History

NODE.DC Tasker Codex API

Отдельный модуль NODE.DC для безопасного подключения локальных Codex/AI-агентов к Tasker / Operational Core.

Модуль не является частью Plane fork и не должен становиться backend-расширением Tasker. Его роль — agent gateway: выдача ограниченных agent credentials, проверка прав, MCP/REST-контракт для внешних агентов, аудит и маршрутизация разрешённых операций в Tasker через узкий internal adapter.

Documents

Core rule

External Codex instances never receive Plane session cookies, raw Tasker API tokens, database access, or a generic HTTP proxy into Tasker.

All writes go through NODE.DC Agent Gateway, are scoped by agent grants, and are recorded as actions of a dedicated agent identity owned by a human platform user.

Current implementation

  • Fastify service with /healthz, /readyz, and capability metadata.
  • Postgres migrations for agents, grants, token hashes, pairing codes, audit events, and idempotency keys.
  • Internal REST endpoints for agent profile, grant, and token lifecycle.
  • Opaque agent tokens are generated once and stored only as SHA-256 hashes.
  • Authenticated agent-session endpoint returns effective grants/scopes for future MCP calls.
  • Product tool endpoints validate agent token, scopes, and project grants before calling Tasker internal adapter.
  • MCP JSON-RPC endpoint /mcp exposes the same tool runtime as REST product endpoints.
  • Tool execution calls the real Tasker internal adapter; no fake Tasker storage exists in Gateway.
  • Local real e2e smoke verifies Gateway -> MCP -> Tasker runtime writes.

Local development

cp .env.example .env
docker compose --env-file .env -f docker-compose.local.yml up -d postgres
npm install
npm run migrate
npm run dev

Useful checks:

npm run check
npm run build
npm run smoke:mcp
npm run smoke:gateway
curl http://127.0.0.1:4100/readyz
curl http://127.0.0.1:4100/api/v1/meta/capabilities

Create a local test agent:

curl -X POST http://127.0.0.1:4100/api/v1/agents \
  -H 'Content-Type: application/json' \
  -d '{"owner_user_id":"local-user","owner_email":"local@example.test","display_name":"Local Codex"}'

Create a token and inspect effective agent session:

TOKEN=$(curl -sS -X POST http://127.0.0.1:4100/api/v1/agents/<agent-id>/tokens \
  -H 'Content-Type: application/json' \
  -d '{"name":"Local Codex token"}' | jq -r .token)

curl http://127.0.0.1:4100/api/v1/agent-session \
  -H "Authorization: Bearer $TOKEN"

Do not expose these lifecycle endpoints publicly before the Launcher/internal auth layer is added.

Call MCP tools through the JSON-RPC endpoint:

curl -sS http://127.0.0.1:4100/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-06-18' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"jsonrpc":"2.0","id":"tools","method":"tools/list","params":{}}' | jq

Local testing strategy

No fake Tasker storage is embedded into Agent Gateway.

Local verification is split into product layers:

  1. npm run smoke:mcp verifies MCP initialize, tool listing, bearer token auth, scope checks, grant checks, and the Tasker boundary.
  2. npm run smoke:gateway verifies the REST compatibility boundary over the same tool execution path.
  3. npm run smoke:e2e verifies REST tool endpoints against the real local Tasker runtime.
  4. npm run smoke:mcp:e2e verifies MCP tool calls against the real local Tasker runtime.
  5. External-machine testing uses the same token and endpoint shape against staging HTTPS; no extra protocol or fake environment should be introduced.

Example real localhost MCP e2e:

TOKEN=$(python3 - <<'PY'
from pathlib import Path
for line in Path('/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER/plane-app/plane.env').read_text().splitlines():
    if line.startswith('NODEDC_INTERNAL_ACCESS_TOKEN=') or line.startswith('PLANE_NODEDC_ACCESS_TOKEN='):
        value = line.split('=', 1)[1].strip().strip('"').strip("'")
        if value:
            print(value)
            break
PY
)

DATABASE_URL='postgres://nodedc_agent_gateway:replace-with-local-postgres-password@localhost:54100/nodedc_agent_gateway' \
NODE_ENV=development \
LOG_LEVEL=silent \
NODEDC_TASKER_INTERNAL_URL='http://localhost:8090' \
NODEDC_INTERNAL_ACCESS_TOKEN="$TOKEN" \
SMOKE_WORKSPACE_SLUG='nodedc' \
SMOKE_PROJECT_ID='<project-id>' \
npm run smoke:mcp:e2e

Current Tasker internal adapter contract expected by Gateway:

  • POST /api/internal/nodedc/agent/projects/resolve
  • GET /api/internal/nodedc/agent/projects/:projectId/context
  • GET /api/internal/nodedc/agent/issues?project_id=...
  • POST /api/internal/nodedc/agent/issues
  • PATCH /api/internal/nodedc/agent/issues/:issueId
  • POST /api/internal/nodedc/agent/issues/:issueId/move
  • POST /api/internal/nodedc/agent/issues/:issueId/comments
  • PUT /api/internal/nodedc/agent/issues/:issueId/labels
  • PUT /api/internal/nodedc/agent/issues/:issueId/assignees