|
|
||
|---|---|---|
| docs | ||
| migrations | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| docker-compose.local.yml | ||
| docker-entrypoint.sh | ||
| package-lock.json | ||
| package.json | ||
| tsconfig.json | ||
README.md
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.
- Lifecycle endpoints are protected by
NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN; public agent traffic uses only issued agent tokens. - 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.
- Agent setup endpoint returns an MCP config template and AGENTS.md instruction pack without echoing the raw token.
- Product tool endpoints validate agent token, scopes, and project grants before calling Tasker internal adapter.
- MCP JSON-RPC endpoint
/mcpexposes the same tool runtime as REST product endpoints. - Write tools require idempotency keys and replay successful duplicate requests without creating duplicate Tasker writes.
- Agent Gateway writes audit events for executed, replayed, and failed write-tool calls.
- 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
Product-like Docker run:
cp .env.example .env
docker compose --env-file .env -f docker-compose.local.yml up -d --build
curl http://127.0.0.1:4100/readyz
The agent-gateway container waits for local Postgres, runs migrations on startup, and exposes the same :4100 endpoint used by Tasker (PLANE_NODEDC_AGENT_GATEWAY_URL=http://host.docker.internal:4100).
Direct Node.js 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 "Authorization: Bearer $NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN" \
-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 "Authorization: Bearer $NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN" \
-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"
Tasker UI should use the owner-scoped internal lifecycle API through its backend proxy:
curl http://127.0.0.1:4100/api/internal/v1/owners/<owner-user-id>/agents \
-H "Authorization: Bearer $NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN"
The internal API verifies the owner path against the stored agent owner before returning agent detail, grants, tokens, setup packets, or revoke responses.
Generate a local Codex setup packet:
curl http://127.0.0.1:4100/api/v1/agent-session/setup \
-H "Authorization: Bearer $TOKEN" | jq -r .setup.agents_md
The setup packet includes:
- MCP endpoint and header template with
<agent-token>placeholder; - available tools for the current grants;
- AGENTS.md rules for Tasker card writing, no-delete boundary, and required
idempotency_key; - no raw token echo.
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:
npm run smoke:mcpverifies MCP initialize, tool listing, bearer token auth, scope checks, grant checks, idempotency requirement, and the Tasker boundary.npm run smoke:gatewayverifies the REST compatibility boundary and idempotency requirement over the same tool execution path.npm run smoke:e2everifies REST tool endpoints and idempotent replay against the real local Tasker runtime.npm run smoke:mcp:e2everifies MCP tool calls and idempotent replay against the real local Tasker runtime.- 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_AGENT_GATEWAY_INTERNAL_TOKEN='replace-with-gateway-internal-token' \
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/resolveGET /api/internal/nodedc/agent/projects/:projectId/contextGET /api/internal/nodedc/agent/issues?project_id=...POST /api/internal/nodedc/agent/issuesPATCH /api/internal/nodedc/agent/issues/:issueIdPOST /api/internal/nodedc/agent/issues/:issueId/movePOST /api/internal/nodedc/agent/issues/:issueId/commentsPUT /api/internal/nodedc/agent/issues/:issueId/labelsPUT /api/internal/nodedc/agent/issues/:issueId/assignees