Essential tooling recipe book
Permissions, az CLI for ADO, gh CLI for GitHub, MCP servers (including our custom DB and Roslyn servers), persistent context basics, and the .context/ folder convention.
The biggest force multiplier when working with Claude Code is letting Claude reach external systems directly instead of acting as the integration layer yourself. Once Claude can pull a work item, read a PR, query a database, or run a build on its own, you stop being the messenger and start being the decision-maker.
This guide is a recipe book for the tools that make that possible. Each section follows the same shape: what you want to accomplish, the command or tool that does it, and a copy-pasteable example. Set this up once and the savings compound across every session.
Prerequisite: Permissions
Claude asks for permission on every command by default, which is the right starting position when you are getting comfortable with the tool. Once you trust your setup, two adjustments make the experience much smoother.
Trusted local work: launch Claude with the skip-permissions flag and it will run any command without prompting.
claude --dangerously-skip-permissionsThis is appropriate in your own dev environment when you have visibility into what Claude is doing. Skip it in shared environments or when running unfamiliar agents from external sources.
If this is your default mode, save yourself the typing with a shell alias:
alias yolo-claude="claude --dangerously-skip-permissions"Add that to your .bashrc, .zshrc, or .bash_aliases and you can launch with yolo-claude instead of remembering the flag every time.
Finer control: edit your project or user settings.json to allowlist specific commands. This is the right model when you want routine commands to flow through but still want a prompt before anything destructive.
{ "permissions": { "allow": [ "Bash(git status:*)", "Bash(git diff:*)", "Bash(gh pr view:*)", "Bash(az boards work-item show:*)" ] }}Project settings live at .claude/settings.json (committed) or .claude/settings.local.json (gitignored, personal). The fewer-permission-prompts skill can scan your transcripts and propose an allowlist based on commands you actually run, which is the fastest way to build a sensible starting set.
Azure DevOps via az CLI
The az boards CLI is the primary tool for ADO interaction and handles roughly 99% of what you need. It is fast, returns structured JSON Claude can parse directly, and uses far less context than the equivalent MCP calls. Default to az CLI; reach for the MCP only for the specific gaps noted at the end of this section.
Fetch a work item with full description, acceptance criteria, and metadata:
az boards work-item show --id 181646 --org https://dev.azure.com/adesacentral --output jsonAdd --expand relations to also pull linked items (parent feature, child tasks, related stories).
Update a work item field (state, assignee, custom fields):
az boards work-item update --id 181646 --state "Work In Progress" --org https://dev.azure.com/adesacentralSet arbitrary fields with --fields "FieldName=Value". Multiple fields can be set in one call by repeating the flag.
Post a plain-text comment to the discussion thread:
az boards work-item update --id 181646 --discussion "Investigated the timeout. Root cause is the Service Bus retry policy." --org https://dev.azure.com/adesacentralNote: this endpoint posts as HTML and does not render markdown. For markdown comments (code blocks, lists, headers), see the MCP gap section below.
Query work items with WIQL:
az boards query --wiql "SELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] = 'Work In Progress'" --org https://dev.azure.com/adesacentralWIQL is verbose, but Claude can write it for you. Describe what you want and ask for the query.
Create a child task or work item:
az boards work-item create --type "Task" --title "Add retry logic for timeout case" --area "ADESA\Physical Auction\ADIS\Sith Happens" --iteration "ADESA\2025\Sprint 2025.04" --org https://dev.azure.com/adesacentralLink it to a parent with az boards work-item relation add immediately after.
When to reach for the ADO MCP
The official Azure DevOps MCP server (Microsoft, github.com/microsoft/azure-devops-mcp) fills two specific gaps:
- Markdown-formatted comments:
mcp__azure-devops-official__wit_add_work_item_commentwithformat: "markdown"is the only path that renders markdown in the discussion thread. - Auth fallback: when
az boardsreturns auth errors that the CLI cannot recover from, the MCP can sometimes succeed via a different auth path.
That is essentially the entire reason to keep the MCP installed. Everything else is faster and lighter through az boards.
GitHub via gh CLI
gh is the equivalent of az boards for GitHub. Same model: fast, structured, and Claude can drive it directly.
View a PR with title, body, status, and reviewers:
gh pr view 1646 --repo CVNA-Wholesale/inspection-workflowAdd --json files,reviews,comments to get structured data Claude can parse.
Get the diff:
gh pr diff 1646 --repo CVNA-Wholesale/inspection-workflowPull all comments on a PR (general comments, reviews, and inline review comments come from different endpoints):
# General comments and reviewsgh pr view 1646 --repo CVNA-Wholesale/inspection-workflow --json reviews,comments
# Inline review comments tied to specific linesgh api repos/CVNA-Wholesale/inspection-workflow/pulls/1646/commentsReply to an inline review comment (the path requires the PR number, which is easy to miss):
gh api repos/CVNA-Wholesale/inspection-workflow/pulls/1646/comments/{COMMENT_ID}/replies -f body="Good catch, fixed in the next commit."Create a PR:
gh pr create --title "181646 - Auto-complete service on cert completion" --body "AB#181646" --label SithHappensThe team convention is {workItemId} - {description} for the title and AB#{workItemId} on its own line at the start of the body, which links the PR to the ADO work item automatically.
Check CI status without opening the browser:
gh pr checks 1646 --repo CVNA-Wholesale/inspection-workflowgh run view {RUN_ID} --log-failedMCP Servers
MCP (Model Context Protocol) servers are how Claude talks to external systems through structured tool calls instead of shell commands. You install them once, register them in your Claude Code settings, and they appear as callable tools in every session.
The four worth installing for our workflow:
Azure DevOps Official (Microsoft)
- Repo: github.com/microsoft/azure-devops-mcp
- Tool prefix:
mcp__azure-devops-official__* - Purpose: Fallback for the specific gaps in
az boards(markdown comments, auth recovery). As covered above, az CLI handles the vast majority of ADO interaction more efficiently.
DB SQL Server (custom, built in this repo)
- Tool:
mcp__db-sql-server__execute_sql - Repo: github.com/CVNA-Wholesale/Wholesale-Sith-Happens/tree/master/.tools/db-mcp-server. See the README for full installation, configuration, and parameter conventions
- Purpose: Read-only SQL access to Nexus and AMS databases without setting up a local SQL client. Lets Claude run schema discovery, validate assumptions against production data, and write queries that match real shapes instead of guessing.
- For your team: this server is built around our database topology (Nexus + AMS, multiple sites, test/UAT environments). You will likely need to adapt the connection model, server selection, and database routing for your team’s data layout. Do not modify it yourself. Point your Claude Code instance at this repo, tell it to bring the DB MCP into your team’s tooling location, and ask it to adapt the configuration for your environment. The source is well documented and Claude can drive the changes independently.
Roslyn MCP (custom, built in this repo)
- Tool prefix:
mcp__roslyn__* - Repo: github.com/CVNA-Wholesale/Wholesale-Sith-Happens/tree/master/.tools/roslyn-mcp-server. See the README for the full tool list, install scripts, and configuration
- Purpose: Compiler-level C# analysis. Find usages, trace calls, get type hierarchies, list namespace types, check signatures. The right tool when grep is too coarse and you need to know what actually compiles.
- For your team: the tool surface, caching behavior, and preload list reflect our usage patterns. You will likely want to adjust at least the configuration and possibly add or modify tools. Do not modify it yourself. Point your Claude Code instance at this repo, ask it to bring the Roslyn MCP into your tooling location, and have it adapt the configuration for your solutions. Same model as the DB MCP: the source is structured well enough for Claude to navigate and adapt without manual intervention.
Fetch (Anthropic)
- Tool:
mcp__fetch__fetch - Purpose: Pull remote URLs into Claude’s context. Useful for reading public docs, RFC pages, or vendor API references without you having to copy them in.
The mental model for MCP servers: they replace “Claude reads docs and tries to write a CLI command” with “Claude calls a typed function and gets a structured response.” They are lower-friction and harder to get wrong, which is why the custom ones we built (DB and Roslyn) target capabilities that have no good CLI equivalent. For things that already have great CLIs (ADO, GitHub), the CLI usually wins on speed and context cost.
Persistent Context
Re-explaining your conventions every session is a tax that adds up. Claude does not remember what you told it last week. Three mechanisms fix that.
Global rules at ~/.claude/CLAUDE.md. Loaded into every session you start, regardless of project. Put things here that are true everywhere: your shell preferences, your writing style, environment quirks (WSL vs native), CLI tools you always have available.
Project rules at {project}/CLAUDE.md or {project}/AGENTS.md. Loaded only in that project. Put things here that are project-specific: the team’s commit message format, which branches deploy where, naming conventions, repos you always touch together.
Memory system at ~/.claude/projects/{project-hash}/memory/. Claude writes to this on its own when it learns something about you, your preferences, or the project. You can ask it to remember things explicitly (“remember that we always use FluentAssertions, never Shouldly”) and it will write a memory file. Future sessions read these automatically.
The compound effect is significant. A new session in your project starts with hundreds of lines of context already loaded: who you are, how you work, what the project conventions are, what to avoid. You spend less time orienting Claude and more time getting work done.
The .context/ Folder
Persistent context covers the things you want Claude to know on every session. The flip side is the things Claude needs right now but does not belong in source control: a copy of a work item description, an error log you are debugging, a temporary plan, a draft response to a PR comment. These pile up fast in any active session and need somewhere to live.
The convention we use is a .context/ folder at the root of every project, gitignored, treated as Claude’s personal scratch space. Anything Claude needs to read, reference, or write that has no business being committed goes here.
Setup is one line in your .gitignore:
.context/Then ask Claude to use it. Examples of what tends to land there:
- Pulled-down work items (
.context/181646-auto-complete-service.md) - Active implementation plans before they earn a permanent home
- PR comment threads exported for batch review
- Draft notes, scratch SQL queries, intermediate analysis output
- Any “go read this file before continuing” handoff between sessions
The benefit is twofold. Claude has somewhere to write that does not pollute the repo, and you have a single predictable location to look when you want to find what Claude has been working on. When the work is done, you delete the file or leave it; nothing ever gets committed by accident.
A related convention worth knowing: if you reference .context in a prompt without a full path, Claude will default to the .context/ folder in the current repo’s root. This convention is documented in global instructions and is the same pattern any team can adopt.
Putting It Together
What this looks like once it is wired up: you open Claude in your repo and type “Pull down work item 181646 and start a feature branch for it.” Without any further input, Claude runs az boards work-item show, parses the description and acceptance criteria, runs git checkout -b feature/181646-{description-from-title}, and reports back with what it found. No copy/paste, no permission prompts, no re-explaining your branch naming convention.
That is the baseline. Everything in the next guide builds on it.
The next guide in this series covers agents: what they are, when to reach for one instead of doing the work in your main session, and how to build your own for tasks you find yourself repeating.