Skip to main content
When dotbot cannot proceed with a task without human input — for example, a missing requirement or an ambiguous design decision — it marks that task as needs-input and routes the question to the appropriate stakeholder. Rather than blocking the entire queue, dotbot sends the question out-of-band via Microsoft Teams, email, or Jira, waits for a reply, and then resumes the task automatically once an answer arrives. This keeps pipelines moving without requiring the team to monitor the dashboard in real time.

Why human-in-the-loop matters

AI models can resolve most questions by reading the codebase, product documents, and task context. But some decisions require human judgment — a stakeholder who knows the business constraint, the architect who owns the design, or the product owner who decides between competing priorities. Without a structured way to ask those questions, the AI either guesses (introducing risk) or halts the pipeline entirely. The needs-input mechanism gives the AI a safe escape hatch: pause the task, ask the right person, and continue when the answer arrives — without blocking any other tasks that do not depend on this one.

How the flow works

1

Task reaches needs-input

The AI determines it cannot proceed without more information and calls the task_mark_needs_input MCP tool. The task is paused and removed from the active execution queue.
2

Question is sent to the stakeholder

dotbot’s notification client reads the mothership settings block and sends the question to the configured channel (teams, email, or jira) along with the available choices.
3

Stakeholder answers

The stakeholder replies directly in Teams via an Adaptive Card, by email, or via a Jira comment. The answer is stored as a JSON record on the server.
4

dotbot resumes the task

dotbot polls the server on the configured poll_interval_seconds interval. When an answer arrives, it calls the task_answer_question MCP tool and promotes the task back to the active queue.

Configuring Microsoft Teams integration

Add the mothership block to your settings.default.json and set channel to teams:
settings.default.json
{
  "mothership": {
    "enabled": false,
    "server_url": "",
    "api_key": "",
    "channel": "teams",
    "recipients": [],
    "project_name": "",
    "project_description": "",
    "poll_interval_seconds": 30,
    "sync_tasks": true,
    "sync_questions": true
  }
}
FieldTypeDescription
enabledbooleanSet to true to activate the mothership integration
server_urlstringBase URL of the deployed Teams bot App Service
api_keystringAPI key used to authenticate requests to the bot server
channelstringDelivery channel: teams, email, or jira
recipientsarrayList of Teams user object IDs, email addresses, or Jira account IDs
project_namestringDisplayed in the question card so stakeholders know which project is asking
project_descriptionstringAdditional context shown in the notification
poll_interval_secondsintegerHow often dotbot checks for answers (default: 30)
sync_tasksbooleanWhether to sync task state to the mothership server
sync_questionsbooleanWhether to push questions and retrieve answers via the server

Setting up the server_url and api_key

To use Teams (or any other notification channel), you need a deployed mothership server. Once your server is running, set its URL and API key in settings.default.json:
settings.default.json
{
  "mothership": {
    "enabled": true,
    "server_url": "https://your-dotbot-server.example.com",
    "api_key": "your-api-key-here",
    "channel": "teams"
  }
}
Store the api_key in your local .bot/.control/settings.json rather than in the version-controlled settings.default.json to avoid accidentally committing credentials to your repository.

What stakeholders see

When a question is routed to Teams, the recipient receives an Adaptive Card that includes the project name, the question text, and a set of choices to select from. Clicking a choice submits the answer directly — no separate login or dashboard access is required. The architecture is:
[dotbot runtime] ──POST──▶ [App Service /api/notify]

                             Sends Adaptive Card

[Teams user] ◀──Card────────────────┘
    │ clicks choice

[Teams] ──▶ [Bot Service] ──▶ [App Service /api/messages]

                             Stores answer JSON
                             Sends confirmation card

Answer format

When a stakeholder responds, the bot stores an answer record on the server. dotbot reads this record during the next poll cycle:
{
  "questionId": "q-20260216-001",
  "question": "Which database should we use?",
  "choices": ["PostgreSQL", "SQLite", "CosmosDB"],
  "selectedChoice": "PostgreSQL",
  "selectedIndex": 0,
  "userId": "abc-123",
  "userName": "Andre",
  "timestamp": "2026-02-16T19:30:00Z"
}
The task_answer_question MCP tool ingests this record and attaches the answer to the paused task before resuming it.

Other routing options

Set channel to email and populate recipients with email addresses. dotbot sends a formatted message with answer choices and resumes when a reply is received.
Set poll_interval_seconds to 60 or higher in long-running pipelines to reduce noise in the server logs. For time-sensitive interactive workflows, 1530 seconds gives a responsive feel without excessive polling.