CLI for working with TFS/Azure DevOps Server work items (create, update, delete, search, WIQL, and more).
- Run WIQL and list matching work items.
- Create, update, and delete work items (including comments).
- Search by title/description.
- Show details, complete comment history, and child items.
- List work item types and resolve your identity.
- Create Git pull requests in TFS/Azure DevOps Server.
- Show Git pull request details by URL or ID (repo, branches, work items, comments).
- Post comment threads on pull requests (inline, stdin, or file input).
- Read wiki page metadata and raw Markdown content from a TFS/Azure DevOps browser URL.
- JSON output by default, with optional text tables.
- Go 1.21+ (for building from source).
- A TFS/Azure DevOps Server instance and a PAT token.
Build a local binary:
go build -o tfs .Run it from the repo root:
./tfs --helpConfigure the CLI, then create a backlog item and a child task. The examples below use common English work item names:
- Product Backlog Item
- Task
./tfs config set --base-url "https://dev.azure.com/your-org" --project "YourProject" --pat "YOUR_PAT"
./tfs create --type "Product Backlog Item" --title "Add report generation" \
--set "System.Description=Allow users to generate and download reports"
./tfs create --type "Task" --title "Implement report endpoint" --parent 123 \
--set $'System.Description=Implement the API endpoint\n\nResult: Report file is returned in the response' \
--set "Microsoft.VSTS.Common.Activity=Development" \
--set "Microsoft.VSTS.Scheduling.RemainingWork=4" \
--set "Microsoft.VSTS.Scheduling.OriginalEstimate=4"You can configure the CLI via a config file, environment variables, or flags.
Save config values:
./tfs config set --base-url "https://dev.azure.com/your-org" --project "YourProject" --pat "YOUR_PAT"View config (PAT redacted):
./tfs config viewThe config file is stored in the OS user config directory (for example, ~/.config/tfs/config.json on Linux, %AppData%\\tfs\\config.json on Windows).
TFS_BASE_URLTFS_PROJECTTFS_PAT
Flags override environment variables, which override the config file.
Set --base-url (or TFS_BASE_URL) to the organization/collection root:
- Azure DevOps Services:
https://dev.azure.com/{org} - TFS on-prem:
http://server:8080/tfs/{collection}
If the URL ends with the project name, the CLI will normalize it automatically.
Run ./tfs --help for the full command list. Main commands:
wiql- run a WIQL query and list itemsview- show a work item by IDupdate- update fields or add a commentcreate- create a work itemdelete- delete a work item; add--destroyto attempt permanent removal when the PAT has destroy permissionsearch- search by title/descriptionmy- list your assigned itemsshow- show details plus child itemspr create- create a Git pull requestpr show- show pull request details (repo, branches, title, work items, comments)pr comment- post a comment thread on a pull requestwiki show- show a wiki page by browser URLtypes- list work item typeswhoami- show the resolved identity from the PATconfig- view/set stored config
The examples below assume these English type names and field references:
- Work item types:
Product Backlog Item,Task - Activity field:
Microsoft.VSTS.Common.Activity(value:Development) - Remaining work:
Microsoft.VSTS.Scheduling.RemainingWork - Original estimate:
Microsoft.VSTS.Scheduling.OriginalEstimate
List work item types (text output):
./tfs types --json=falseCreate a work item:
./tfs create --type "Product Backlog Item" --title "Add report generation" \
--set "System.Description=Allow users to generate reports"Create a child task:
./tfs create --type "Task" --title "Implement report endpoint" --parent 123 \
--set $'System.Description=Implement the API endpoint\n\nResult: Report file is returned in the response' \
--set "Microsoft.VSTS.Common.Activity=Development" \
--set "Microsoft.VSTS.Scheduling.RemainingWork=4" \
--set "Microsoft.VSTS.Scheduling.OriginalEstimate=4"Update fields and add a comment:
./tfs update 123 \
--set "System.Title=Report generation supports filters" \
--add-comment $'### Updated scope\n\n- Add CSV export\n- Preserve current filters'System.Description, Microsoft.VSTS.Common.AcceptanceCriteria,
Microsoft.VSTS.TCM.ReproSteps, and comments written through --add-comment
are TFS rich-text fields. The CLI renders Markdown supplied for these fields to
HTML before sending it to TFS, so headings, paragraphs, lists, emphasis, links,
and inline code retain their structure in the web interface. Existing HTML is
passed through unchanged. Use real newline characters; in Bash, ANSI-C quoting
such as $'line one\n\nline two' is convenient.
Delete a work item:
./tfs delete 123 --yesPermanently delete a work item when the PAT has destroy permission:
./tfs delete 123 --destroy --yesCreate a pull request:
./tfs pr create --repository "sample-service" \
--source "feat/update-report-workflow" \
--target "develop" \
--title "Update report workflow example" \
--description "Documentation examples were refreshed with neutral placeholder values" \
--work-item 12345 \
--work-item 12346 \
--auto-completeIf you pass --work-item, the CLI links those work items to the PR. --auto-complete is optional and disabled by default.
Show a pull request by URL:
./tfs pr show "https://dev.azure.com/your-org/YourProject/_git/your-repo/pullrequest/42"Show a pull request by ID with explicit repository:
./tfs pr show 42 --repository "your-repo"The pr show command prints the repository name, source and target branches, PR title, description, linked work items (with type/state/title), and comment threads. Use --json=false for human-readable text output. --max-threads N limits the number of comment threads shown. Add --git-diff to fetch and display unified diffs of changed files in the pull request.
Post a comment on a pull request:
./tfs pr comment "https://dev.azure.com/your-org/YourProject/_git/your-repo/pullrequest/42" \
--content "Looks good — approved" --json=falsePost a long comment from a file:
./tfs pr comment 42 --repository "your-repo" --content-file review-report.mdPost a comment from stdin:
echo "Please fix the null check in service.java" | ./tfs pr comment 42 --repository "your-repo" --content -The pr comment command creates a new comment thread on the pull request. Content can be provided via --content "text", --content - (stdin), or --content-file <path>. Optional --status sets the thread status (active, byDesign, resolved, closed, wontFix, unknown; default: active).
Show a wiki page by its browser URL:
./tfs wiki show "https://dev.azure.com/your-org/YourProject/_wiki/wikis/YourProject.wiki/1578/Page-title" --json=falseThe command accepts both page-ID URLs (.../<wiki>/1578/Page-title) and pagePath URLs (.../<wiki>?pagePath=%2FGuides%2FPage). It prints page metadata followed by the raw Markdown content. JSON output includes the wiki/page identifiers, paths, URLs, page flags, and content without duplicating the document body. To prevent sending the configured PAT to another server, the URL must belong to the configured TFS organization or collection; use the matching --base-url override when intentionally targeting another configured collection.
Show details, all comments, and children:
./tfs show 123Use --max-comments N to limit the number of comments returned; 0 (the default) returns all comments. JSON output contains the comments in the top-level comments array.
Search:
./tfs search --query "report generation" --top 20Run a WIQL query:
./tfs wiql "SELECT [System.Id] FROM WorkItems WHERE [System.State] = 'New'" --top 50- Most commands output JSON by default.
- Use
--json=falseto get text tables where supported. myandshowdefault to text unless--jsonis explicitly provided.
Run tests:
go test ./...Integration tests require a live instance and environment variables:
TFS_BASE_URL=... \
TFS_PROJECT=... \
TFS_PAT=... \
TFS_WIT_TYPE=... \
go test -tags=integration ./internal/integrationOptional integration variables:
TFS_TASK_TYPE(default in code:Задача)TFS_TASK_ACTIVITY_NAME(default in code:Активность)TFS_TASK_ACTIVITY_VALUE(default in code:Разработка)TFS_TASK_REMAINING_WORK_NAME(default in code:Оставшаяся работа)TFS_ASSIGNED_TOTFS_INSECURE(set to non-empty to skip TLS verification)
- The CLI uses Azure DevOps REST API version 6.0; wiki page reads use
6.0-preview.1, as required by supported on-premises TFS servers. - For API background and examples (in Russian), see
tfs_api.md.