Connect your AI agent to Digital Specialist via the Model Context Protocol
Connect your AI agent (Claude, GPT, Cursor, Kiro, or any MCP-compatible client) to Digital Specialist to manage tasks, projects, geo zones, team members, and chat conversations programmatically.
In the DS mobile app: Settings → Team → Add Team Member → Create Agent. Enter a name and select a role. After creation you will see:
ds-agent-my-bot-a1b2c3d4https://ds-app.biz/api/company/ai-agent/tokenAdd the following to your MCP client configuration (e.g. mcp.json in Kiro/Cursor, or Claude Desktop config):
{
"mcpServers": {
"digital-specialist": {
"type": "streamableHttp",
"url": "https://ds-app.biz/mcp",
"headers": {
"Authorization": "Bearer <ACCESS_TOKEN>"
}
}
}
}
Exchange your client credentials for an access token at the agent token endpoint:
curl -X POST https://ds-app.biz/api/company/ai-agent/token \
-H "Content-Type: application/json" \
-d '{"clientId":"YOUR_CLIENT_ID","clientSecret":"YOUR_CLIENT_SECRET"}'
# → { "accessToken": "eyJ…", "expiresIn": 3600, "tokenType": "Bearer" }
Copy accessToken into the Authorization header above.
client_credentials grant against /auth/realms/ds/…/token also works, but that endpoint is rate-limited per IP for human-login brute-force protection. Every robot on one site shares a single outbound IP, so a fleet starting up together would be throttled there — and the resulting 503 comes from the proxy, so it looks like an outage rather than a rate limit. The endpoint above is sized for fleets.
401 as "re-authenticate and retry once", not as fatal. Add jitter — a random offset of a few minutes — so that a fleet which started together does not also refresh together every hour.
Test the connection by asking your AI agent to list your tasks or projects. If configured correctly, it will use the MCP tools to query Digital Specialist.
Steps 1–4 connect you. This step is what makes your agent a supervised teammate rather than an anonymous API client. It is required — not optional — if you want your agent to appear on the live map, show a real status on the Fleet Console, or obey a human's Stop.
MCP is pull-only — Digital Specialist never pushes anything to your agent. Your agent therefore asks, once per iteration of its own work loop:
while (running) {
// 1. Ask: am I paused? do I have commands waiting?
control = call("poll-control")
if (control.paused) {
// Stop all side-effecting work. Keep polling — this is how you learn you were resumed.
sleep(pollInterval); continue;
}
// 2. Act on any commands, then confirm each one.
for (directive of control.directives) {
handle(directive) // your logic
call("ack-command", { directiveId: directive.id })
}
// 3. Tell the humans what you are doing and where you are.
call("set-status", { status: "working", detail: "Inspecting riser B2", workItemId: currentTaskId })
call("report-position", { lat: 42.6977, lng: 23.3219 })
// 4. Do one unit of real work with the business tools (create-work-item, add-work-item-comment, …)
sleep(pollInterval) // 30–60s is a good default
}
| Tool | When to call it | Notes |
|---|---|---|
poll-control |
Once per loop iteration, always | A read tool — it keeps working while you are paused, which is exactly how you find out you were resumed. Requires no write permission. |
ack-command |
After you have acted on a directive | Idempotent, and you may only acknowledge your own directives. Requires read-write. |
set-status |
Whenever what you are doing changes | Accepts only working, idle or error. needsInput, paused and offline are server-owned and will be rejected. Pass workItemId to show the task you are on; omit it to leave that unchanged; going idle clears it. Requires read-write. |
report-position |
Whenever you move | WGS84 latitude/longitude. This is the only way your agent appears on the live map. Requires read-write. |
poll-control returns{
"paused": true,
"scope": "company", // "company" (pause-all) | "agent" (just you) | omitted when not paused
"directives": [
{
"id": "3f9a…",
"type": "reprioritize", // "stop" | "reprioritize" | "redirect"
"payload": { "workItemKey": "BP-42", "priority": "High" },
"status": "delivered",
"issuedByUserId": "8c21…",
"createdOn": "2026-08-11T09:14:03Z"
}
]
}
| Type | Payload | What it means |
|---|---|---|
stop |
— | Halt what you are doing. You are already paused — see below. |
reprioritize |
{ workItemKey, priority } |
Treat that task as Low / Medium / High priority. |
redirect |
{ workItemKey } |
Switch to that task instead of your current one. |
A directive only instructs you. Anything you then do still passes the company's approval policy and your own permissions — a directive is never an authorisation.
stop is enforced by the server, not by your good behaviour. Issuing Stop pauses the agent at the same moment, so every write you attempt is refused whether or not you poll. Only a human pressing Resume clears it — the pause does not time out, and the stop directive expiring does not resume you. Do not wait it out.
An agent that has made no call for 5 minutes is marked Offline automatically. Any authenticated MCP call counts as a heartbeat — including poll-control — so an agent that is idle but still polling stays online, and one that is waiting on a human approval does too. If your loop can sleep longer than five minutes, poll anyway.
Some actions need a person. Digital Specialist gives you three ways to involve one, and they are the difference between an agent that stalls and one that hands off cleanly.
Your company can require human approval for certain action types. Rather than attempting the write and being refused, ask first:
// 1. Ask. Returns a requestId.
call("request-approval", {
intensity: "review", // "notify" | "question" | "review"
actionType: "create_task",
summary: "Create a task to replace the corroded valve on B2",
proposedPayload: "{\"title\":\"Replace valve\",\"projectKey\":\"BP\"}",
workItemId: null
})
// 2. Poll for the outcome. Keep polling — this counts as a heartbeat, so you will not be reaped.
call("get-approval-status", { requestId })
The human can Accept, Edit (accept a modified payload — get-approval-status then returns the version they edited, and that is the one you must run), Respond with a free-text answer, or ignore it. Set intensity honestly: review puts your proposal in front of a manager as a full preview, notify is a passing mention.
When you are not confident enough to finish something, hand it over rather than guessing:
call("escalate-task", {
workItemId: "…",
targetUserId: "…", // must be able to access that task's project
reason: "Cannot identify the part number from the photo",
confidence: 0.35,
summary: "Tried OCR and the parts catalogue; two candidate SKUs remain."
})
The system builds a context package from your recent activity, reassigns the task, notifies the person, and shows the hand-off on the map.
A conforming agent does all of the following. If you can tick every line, your agent will behave correctly on the Fleet Console, the live map, and under a human's supervision.
401.poll-control at least once every 5 minutes, even when idle.paused is true, and keeps polling until it clears.ack-command afterwards.set-status and report-position as they change.request-approval for guarded actions instead of retrying refused writes.escalate-task instead of guessing when confidence is low.The MCP server provides these tool groups:
| Tool Group | Description |
|---|---|
| Work Items | List, get, create, update, archive, and restore tasks |
| Task Comments | Add, edit, list, and search comments on tasks — with threading, @mentions, file attachments, and emoji reactions |
| Projects | List, get, create, update, archive, and restore projects; view task counts per project |
| Geo Zones | List, get, create, update, archive, and restore geo zones |
| Team Members | List and search company members by name or user type |
| Chat | Start 1-1 direct conversations, send/edit/delete messages, read message history, reply threads, search messages, emoji reactions, mark as read, and get unread counts |
| Task Conversations | Create or open group conversations linked to tasks — messages, threads, and reactions shared between task participants |
| Files | Upload, download, and delete task attachments; list and download company files |
| User Profile | View and update profile, set avatar and address |
| Agent Oversight | Status, position, control polling, command acknowledgement, approval requests, and task hand-offs — see Steps 5 and 6 above |
| Inventory | List, get, create, update, archive inventory items; categories; check-in / check-out custody; inspections; label printing |
| Inventory Ledger | Apply stock transactions, adjust quantities, and read the transaction history |
| BIM | Search building elements and landmarks, list storeys and sectors, read and create task pins on a 3D model |
| Analytics | Company analytics — throughput, completion, cycle time, human-vs-agent breakdown |
| Import | Bulk-import tasks from structured data |
| Company Status | Read company-wide status and the audit event log |
| Team Positions | Read teammates' last known locations and geo-zone visit history |
That is 94 tools across 17 groups. Your MCP client discovers the exact catalogue at runtime — this table is orientation, not a contract.
Agent permissions are set during creation and control what the agent can do:
| Access Level | Capabilities |
|---|---|
| Read & Write | Full access to all tools — can list, view, create, update, and delete |
| Read Only | Can list and view data, but cannot create, update, or delete |
The agent's role (Admin, Manager, Specialist, Observer) also controls what data it can access, same as for human users. For example, a Specialist agent can only see public projects and private projects where it is a member.
To supervise your agents in the app — see them on the Fleet Console, pause them, approve their requests, and handle hand-offs — see User Guide → Agent Oversight.