Query Azure DevOps work items
Query Azure DevOps work items with WIQL and read the matching ids back, without your AI ever holding the PAT.
Run a WIQL query against an Azure DevOps project and read the matching work item ids back off the replay execution. The org and project are fixed at install; the PAT is the secret, entered in the browser as an HTTP Basic credential. The response is a reference list of {id, url} with no fields on it, so this pipe pairs with azure-devops-read. Choose your scope. The azure-devops family is a ladder. File only: azure-devops-workitem on its own, which runs on the free Deckhand tier and fits a developer logging bugs without leaving the code. Read: azure-devops-query plus azure-devops-read, which needs two pipe slots and a plan that stores full response bodies (Bosun), runs on a PAT scoped Work Items (Read) when nothing else in the family is installed, and fits a developer checking their own assignments or a manager checking team progress. Manage: those two plus azure-devops-manage, which needs three pipe slots (First Mate) and a PAT scoped Work Items (Read & write), for a PM or QA grooming the whole backlog. Climbing the ladder swaps pipes rather than stacking them: a higher rung supersedes the lower one (azure-devops-manage supersedes azure-devops-workitem), so delete the superseded pipe when you move up; keeping every rung installed side by side needs more replay-target slots than the named tier provides.
The credential never enters the model context: it lives in the FlurryPORT secret store, deliveries are signed server-side, and every send returns a receipt your agent can quote.
Install with your agent
npx flurryport mcp
Point your agent at the FlurryPORT MCP server (npx flurryport mcp) and ask it for the flurryport:azure-devops-query recipe. Works from AI clients that can run a local process: desktop apps and terminal agents. Web-only chat clients cannot reach a local MCP server; open a desktop client instead.
Tools your agent gains
flry_azure_devops_query- Run a WIQL query against the configured Azure DevOps org and project. Input: wiql (required). Returns nothing inline; the matching work item ids arrive on the replay execution, read them with get_replay_execution and pass them to flry_azure_devops_read for fields.
Setup walkthrough
AZURE_DEVOPS_PAT: In Azure DevOps: User settings, Personal access tokens, New Token. This recipe on its own needs only scope Work Items (Read); the same token needs Work Items (Read & write) if it also serves azure-devops-workitem or azure-devops-manage. The value to paste in the FlurryPORT secret page is the HTTP Basic credential, NOT the raw token: run `printf ':YOUR_PAT' | base64` and paste the result. The recipe sends it as `Authorization: Basic <value>`. A raw PAT answers 401, or 203 with a sign-in page.
Intent schema
{
"type": "object",
"required": [
"wiql"
],
"properties": {
"wiql": {
"type": "string",
"description": "A WIQL query string. Scope by person in the query, not at install: SELECT [System.Id] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] <> 'Done' returns the open items assigned to whoever owns the PAT."
}
}
}Install-time parameters
org- install-time: Azure DevOps organization.
project- install-time: Project within the organization.
Transformation
{ "body": { "query": $body.wiql } }Delivery target
POST https://dev.azure.com/$install.org/$install.project/_apis/wit/wiql?api-version=7.1
Placeholders like $secrets.NAME resolve server-side at delivery, never in the agent.
Gotchas
- The transformation wraps the payload in an explicit body envelope. A bare { "query": ... } output has root keys that are all envelope words, so FlurryPORT reads it as routing metadata and delivers a null body.
- The response is a reference list: workItems is an array of {id, url}, with no titles, states, or priorities on it. Pair this pipe with azure-devops-read to get fields.
- Results arrive on the replay execution the fire created, not on the capture. Read them with get_replay_execution.
- Assignee scoping is a query fact, not an install setting. @Me in the WIQL resolves to the identity that owns the PAT.
- Success is 200 with queryType and workItems. A malformed WIQL string answers 400 with the parse error in the body.
- On plans without full response bodies the stored response is a 4096-byte preview, so a long id list is cut off. Check ResponseBodyTruncated on the execution before parsing.
- This call cannot ride the Azure DevOps $batch endpoint. $batch answers a wiql sub-request with 404 Unsupported Batch operation, which is why query is its own pipe.
- The Accept-Encoding identity header in the target template is load-bearing: without it Azure DevOps gzips responses and the stored response preview is unreadable binary. With it, stored responses are plain JSON (proven live on prod 2026-08-03).
- Bind this pipe's transformation with the predicate $exists($body.wiql). When two or more azure-devops pipes share one capture endpoint, every binding must carry its routing predicate at bind time, and the family's predicates are mutually exclusive by design: azure-devops-workitem routes on $exists($body.title), azure-devops-read on $exists($body.ids), azure-devops-query on $exists($body.wiql), azure-devops-manage on $exists($body.items). An unpredicated binding fires on every intent that reaches the endpoint (live repro 2026-08-03: a workitem binding bound without its predicate fired on every read intent).
- Safest test fire: a narrow count-style WIQL such as SELECT [System.Id] FROM WorkItems WHERE [System.Id] = 1. It returns at most one reference and changes nothing.
Where this fits
- Destination: Azure DevOps
- Part of the Azure DevOps work items suite
- Project tracking recipes
- What agent tokens can and cannot do
- All recipes
Related recipes
Create and update Azure DevOps work items in one batched pipe: priority, state, tags, and sprint included.
Read fields for a batch of Azure DevOps work items by id: title, state, tags, priority, iteration.
Let your AI file Azure DevOps work items (bugs, tasks) the model never holds credentials for.
Let your AI file GitHub issues with a fine-grained PAT it never touches.
Search GitHub issues and read whole threads back, without your AI ever holding the PAT.
Update, close and reopen GitHub issues in batches, with the PAT held server-side.