Skip to main content
Glama
causercode

azure-devops-server-mcp

by causercode

azure-devops-server-mcp

Connect MCP-compatible AI coding agents to self-hosted Azure DevOps Server Git repositories and pull requests.

The v0.1 milestone is From MCP to Pull Request:

“Create a pull request from my current feature branch into develop.”

The agent reads its local Git context, finds the Azure DevOps project and repository, and calls this server. The server resolves the repository, verifies both remote branches, creates the PR, and returns its number and browser URL.

Status: v0.1 implementation with automated unit, HTTP integration, and stdio protocol tests. The live stdio acceptance check passed against Azure DevOps Server Express 2022.2 Patch 12 using REST 7.0, including PR creation/updates and repository access restrictions. The maintainer also reported successful Codex workflow testing on this lab; Claude Code and other client workflows remain unverified. This package has not been published to npm. Independently implemented; not affiliated with Microsoft.

Requirements and compatibility

  • Node.js 22.12+ (CI is configured for Node 22 and 24 on Windows and Linux).

  • Network access to the Azure DevOps Server collection.

  • A PAT and an identity with access to the projects/repositories you want to use.

Azure DevOps Server

REST version

Project status

Express 2022.2 Patch 12

7.0

Live stdio acceptance passed; build 19.235.37529.3

2022 / 2022.1 and other updates

7.0, optionally 7.1 on 2022.1+

Primary target; these exact installations and REST 7.1 remain unverified

2020

6.0

Experimental; untested against a live server

2019

5.0

Configurable; not yet tested or supported

Version mappings follow Microsoft’s REST API compatibility table. Selecting a version does not prove compatibility. There is no automatic negotiation or fallback. Azure DevOps Services (cloud), TFVC, and Windows/NTLM/Kerberos authentication are outside the v0.1 target.

Related MCP server: github-pr-mcp

Build and configure

For an existing workplace installation, the read-only configuration inspection guide explains how to identify its collection/project layout, authentication, and version.

For a first workplace trial, follow the workplace quickstart: build, configure one approved repository, run a read-only MCP connection check, and register the server with your coding client before trying a draft PR.

From a source checkout:

npm ci
npm run build

Configure the environment of the MCP process:

ADO_SERVER_URL=https://devops.example.com/tfs
ADO_COLLECTION=DefaultCollection
ADO_PROJECT=MyProject
ADO_ALLOWED_REPOSITORIES='[{"project":"MyProject","repository":"MyRepo"}]'
ADO_AUTH_TYPE=pat
ADO_TOKEN=your-personal-access-token

ADO_SERVER_URL is the server root, including any virtual directory such as /tfs, without the collection or project. The collection is appended separately and may contain spaces. Installations hosted directly at a hostname can use https://devops.example.com. Trailing slashes are accepted. URLs containing credentials, query parameters, or fragments are rejected.

Variable

Required

Default / meaning

ADO_SERVER_URL

Yes

Server root and optional virtual directory

ADO_COLLECTION

Yes

Collection name

ADO_TOKEN

Yes

PAT owned by the MCP process

ADO_AUTH_TYPE

No

pat; the only v0.1 implementation

ADO_PROJECT

No

Default project; tool calls may override it

ADO_ALLOWED_REPOSITORIES

Required for writes

JSON array of {project, repository} entries; restricts all repository access

ADO_API_VERSION

No

7.0; accepts 7.1, 6.0, or 5.0

ADO_TIMEOUT_MS

No

30000 per HTTP request; range 100–120000

Use the Code (Read & write) PAT scope to create or edit PRs, plus Project and Team (Read) for project discovery and connectivity diagnostics. For a read-only installation, use Code (Read) instead. Server administrators may restrict PAT availability; PAT scopes do not grant repository permissions that the identity lacks. See PAT documentation and PR API scopes.

The CLI reads process environment variables. It does not automatically load .env. For development, copy .env.example to .env, edit locally, and run npm run dev. To run a built server with an env file:

node --env-file=/absolute/path/to/.env /absolute/path/to/azure-devops-server-mcp/dist/index.js

Do not commit credentials or provide them in an agent prompt.

Repository access

PR writes are disabled by default. Each user must explicitly configure ADO_ALLOWED_REPOSITORIES before the MCP can create or edit a PR. A default project, broad PAT permissions, repository discovery, or an agent's choice of repository does not grant write access.

The allowlist is generic: entries select a project and repository by name or ID, within the configured collection. Multiple repositories and projects are supported (up to 100 entries). For example:

ADO_ALLOWED_REPOSITORIES='[{"project":"SharedProject","repository":"MyApplication"},{"project":"SharedProject","repository":"MyLibrary"}]'

When configured, it restricts reads and writes across repository, branch, and PR tools. Discovery queries only the configured repositories and shows only their projects. Supplying another project, repository ID, or PR ID cannot override the restriction. The server checks a PR's repository before editing it. Scope is configured by the person launching the process; tools cannot change it.

Use project and repository GUIDs to pin identities across renames. Name entries authorize whatever repository currently has that name; deleting/recreating it can change its identity. Tool callers can use the current names or IDs of a repository resolved from an allowed entry. Matching is case-insensitive; wildcards and unknown configuration fields are rejected. A malformed allowlist stops startup. [] denies all repository access. Omission permits reads according to ADO permissions but still disables all PR writes.

The MCP does not infer who "owns" a repository. Effective access is the configured allowlist intersected with the PAT identity's ADO permissions. This restriction applies to this MCP process; an agent's separate Git, shell, or other integrations have their own access.

Connect an MCP client

Build one local copy of this program, then register it separately in each coding provider's configuration. Codex and Claude Code can both point to the same dist/index.js and local env file; each connecting client starts its own stdio process. Authentication to the coding provider is separate from the ADO PAT used by this server.

Switching coding clients does not transfer MCP registration. Accounts sharing one client configuration can share its registration; separate configuration directories need their own registration.

Prepare the shared program and configuration

The following commands use PowerShell. Run them from this MCP's source directory, after npm ci and npm run build. Create .env.local from .env.example if it does not already exist, then edit it locally with your connection, PAT, and explicit repository allowlist. Use .env.work.local instead if following the workplace quickstart.

$mcpDirectory = (Get-Location).Path
$nodeExecutable = (Get-Command node -CommandType Application).Source
$mcpEnvFile = Join-Path $mcpDirectory '.env.local'
$mcpEntryPoint = Join-Path $mcpDirectory 'dist/index.js'
if (-not (Test-Path -LiteralPath $mcpEnvFile)) {
  Copy-Item -LiteralPath .env.example -Destination $mcpEnvFile
}
notepad $mcpEnvFile

For .env.work.local, change the $mcpEnvFile assignment above. Keep the env file private; neither registration below stores the PAT in the agent configuration or command history. Existing parent-process ADO_* variables take precedence over Node's env file, so clear stale values when switching servers. For the first workplace trial, use a Code (Read) PAT, then upgrade to Code (Read & write) when you are ready to create a draft PR.

Run the read-only check before registering:

& $nodeExecutable "--env-file=$mcpEnvFile" (Join-Path $mcpDirectory 'scripts/check-connection.mjs')

Paths must refer to the machine running the coding provider. For macOS/Linux, use the same Node command and absolute arguments with your platform's paths and shell syntax.

Codex

If you use a custom Codex configuration directory, set $env:CODEX_HOME to that path in this terminal before registering; otherwise use Codex's normal default. Use the same profile when verifying the registration.

codex mcp add azure-devops-server -- $nodeExecutable "--env-file=$mcpEnvFile" $mcpEntryPoint
codex mcp list

Alternatively, append this table to that Codex home's config.toml (normally ~/.codex/config.toml), replacing the absolute paths. Use either the CLI command or the table, and preserve existing configuration:

[mcp_servers.azure-devops-server]
command = "C:/Program Files/nodejs/node.exe"
args = [
  "--env-file=C:/path/to/azure-devops-server-mcp/.env.local",
  "C:/path/to/azure-devops-server-mcp/dist/index.js"
]
startup_timeout_sec = 30
tool_timeout_sec = 120

The CLI writes the basic command/args registration; the table also shows optional timeouts. Codex may show Auth: Unsupported for this stdio registration: there is no MCP OAuth login, and the ADO PAT is handled inside our process. For a read-only client configuration, add enabled_tools = ["server_info", "repo_repository", "repo_branch", "repo_pull_request"] to this table. Remove that filter or add repo_pull_request_write before trying PR writes. See OpenAI's MCP configuration documentation.

Claude Code

Register with user scope so the server is available across your local checkouts:

claude mcp add --transport stdio --scope user azure-devops-server -- $nodeExecutable "--env-file=$mcpEnvFile" $mcpEntryPoint
claude mcp get azure-devops-server

If you use a custom Claude Code configuration directory, set $env:CLAUDE_CONFIG_DIR to that path in this terminal before registering and verifying. Leave it unset for the normal configuration. --scope user makes the registration available across projects, while this MCP's repository allowlist still limits ADO access. Default local scope would register only for the current checkout. See Claude Code's MCP documentation.

Verify the tools in the selected client

Start a fresh client session using the configured profile, in the repository you want to work on. In the Codex or Claude Code CLI, /mcp shows MCP status. Then ask:

Use the Azure DevOps Server MCP to check connectivity, inspect my repository, and list its branches. Do not make changes.

Confirm the agent actually calls this server's tools. codex mcp list confirms registration; claude mcp get checks connection status, but neither proves the tools are loaded in your active session. If tools are missing, check the client's configuration directory, absolute Node/env/script paths, and startup errors. A client's native source-control features and PR tracking are separate from this MCP registration. Verify each client's setup with this check and the PR acceptance prompt; see the recorded client results.

Other MCP clients

For clients that use an mcpServers JSON configuration, register the same stdio command and env file:

{
  "mcpServers": {
    "azure-devops-server": {
      "command": "node",
      "args": [
        "--env-file=/absolute/path/to/azure-devops-server-mcp/.env.local",
        "/absolute/path/to/azure-devops-server-mcp/dist/index.js"
      ]
    }
  }
}

On Windows, use a path such as C:/Users/you/code/azure-devops-server-mcp/dist/index.js. Your client may instead offer a server configuration form or another config format; use the same command, arguments, and environment variables. Prefer the client’s protected environment/secret mechanism when available.

Keep stdout dedicated to MCP. Startup errors go to stderr. Running npm start manually waits for a client on stdin; it does not open a web page. node dist/index.js --help and --version work without credentials.

Tools

Tool

Actions

Purpose

repo_repository

get, list

Inspect Git repositories in a project

repo_branch

get, list

Inspect exact remote branches or list branch prefixes

repo_pull_request

get, list

Read PRs and filter by status/source/target branch

repo_pull_request_write

create, update

Create PRs or edit title, description, and draft state

server_info

get, list_projects

Connectivity diagnostics and project discovery

Tool names are inspired by Microsoft’s Azure DevOps MCP; inputs and features are a deliberately smaller, independent contract, not a drop-in replacement.

All repository operations accept project as a name or ID. It can be omitted when ADO_PROJECT is configured. repository accepts a name or ID and is required except for repository listing. Branch names are case-sensitive and accept either feature/foo or refs/heads/feature/foo.

When no default project is configured, start with:

{ "action": "list_projects" }

Call this on server_info, select an accessible project, then use repo_repository with { "action": "list", "project": "Website" }.

Create a PR with repo_pull_request_write:

{
  "action": "create",
  "project": "Website",
  "repository": "intranet",
  "sourceBranch": "feature/search",
  "targetBranch": "develop",
  "title": "Improve search caching",
  "description": "Cache repeated search queries.",
  "isDraft": true
}

The response includes pullRequestId, url, title, status, short branch names, project/repository IDs and names, and draft state. Results are available as both JSON text and MCP structuredContent.

For an update, supply action: "update", repository, pullRequestId, and at least one of title, description, or isDraft. An empty description clears it; isDraft: false publishes a draft for review. Titles are limited to 400 characters and descriptions to 4000. Source and target branches cannot be changed on update.

For repo_pull_request/get, supply pullRequestId. For repo_branch/get, supply branch. Listing PRs defaults to status: "active"; also accepts completed, abandoned, or all, with optional sourceBranch and targetBranch filters. Branch listing accepts prefix, such as feature/.

Pagination

List operations return { "items": [...] } and accept top (default 25, maximum 100).

  • Projects and branches: pass the returned continuationToken to the next call, preserving filters and page size. Stop when no token is returned. With an allowlist, project pagination uses only the projects resolved from allowed repositories.

  • Repositories: use skip/nextSkip. Without an allowlist, the REST endpoint returns the repository inventory; the service pages it locally. With an allowlist, only configured repositories are queried and then paged locally.

  • PRs: use skip/nextSkip. A full page indicates a possible next page; the final call may return an empty array.

Local Git and write outcomes

The MCP server does not inspect the agent’s checkout, run Git, or push commits. The agent identifies its branch and remote using local tools, selects the matching Azure DevOps project/repository, and pushes the source branch through Git before calling this server.

Branch lookups verify exact ref names, even though ADO’s refs API applies a prefix filter. PR creation rejects identical source/target branches and verifies both exist remotely. Branches may change between the checks and creation; the server remains authoritative.

Writes are never automatically retried. A timeout, connection failure, or HTTP 5xx can leave the write outcome unknown. List PRs for the same source/target branches before retrying to avoid duplicates. Errors set isError and provide a safe error.code and message; raw REST error bodies are withheld.

Security boundaries

v0.1 exposes no repository/branch deletion, push, merge, PR completion, autocomplete, policy bypass, permissions, or administrative operations. PR update payloads use an explicit metadata allowlist. Input schemas reject unknown fields; read and write tools have MCP safety annotations. Client approval behavior is controlled by the client.

The PAT remains inside the MCP process. Tools do not return environment variables, auth headers, raw responses, or arbitrary exception messages. Known raw and encoded forms of the configured PAT are redacted from tool output as defence in depth. Remote project/repository names, PR titles, and descriptions remain untrusted data, not instructions.

Prefer HTTPS. HTTP is accepted for installations and local labs that require it, but carries the PAT without transport encryption. Redirects are rejected; configure the final collection URL. No TLS verification bypass is provided. For an internal CA, configure Node’s trust with NODE_EXTRA_CA_CERTS=/absolute/path/to/company-ca.pem before launching the process. See Node TLS configuration.

See SECURITY.md for reporting guidance.

Development and release validation

For a real server away from the workplace, see the free Express test lab guide.

npm ci
npm run check
npm pack --dry-run

npm run check runs formatting verification, strict typechecking, the production build, and all tests. Unit tests cover config/auth, URL construction, safe errors, bounded responses, and exact branch lookup. Integration tests use a local HTTP fixture and real MCP transports, including a compiled stdio child process and a legacy MCP 2025 client. They require no corporate server, PAT, or network access beyond loopback.

The offline suite validates implementation against fixtures; the separate live stdio run provides evidence for the tested Express 2022.2 Patch 12 / REST 7.0 configuration. The maintainer also reported successful Codex workflow testing on this lab. These results do not establish every server version or coding-client workflow. Use the live acceptance checklist when testing another client or expanding compatibility claims. CONTRIBUTING.md explains the architecture and contribution checks.

License

MIT.

Available Tools

5 tools
repo_branchA
Read-onlyIdempotent

Get an exact remote Git branch or list remote branches. Branch names are case-sensitive. Only heads are exposed; local Git state is supplied by the agent.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum results per page (1–100).
actionYes
branchNoBranch name; required for get.
prefixNoOptional starts-with branch filter for list, such as feature/.
projectNoProject name or ID. Defaults to ADO_PROJECT; discover with server_info/list_projects.
repositoryYesRepository name or ID in the selected project.
continuationTokenNoOpaque continuationToken from the previous response. Keep the same filters.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive, so safety is covered. The description adds genuinely useful behavioral context beyond that: only heads are exposed and local Git state must be supplied by the agent, which prevents an agent from assuming it can resolve local refs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core capability, then two constraints. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 7 parameters, the description covers the important gotchas (case-sensitive names, heads-only scope, no local state). Pagination is handled by the schema's top/continuationToken descriptions, so nothing critical is left for the description to carry.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 86%, so the schema already documents top, branch, prefix, project, repository, and continuationToken. The description's case-sensitivity note is relevant to the branch parameter, but otherwise adds little beyond the structured fields, which is the expected baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb pair (get/list) and resource (remote Git branch), so an agent immediately knows this reads branch data. The resource is clearly distinct from the PR/repository siblings, but it never explicitly differentiates itself from them, keeping it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrasing 'get an exact branch or list branches' implies the two modes and the schema's action enum plus branch/prefix descriptions fill in the conditions. There is no explicit when-to-use/when-not guidance against alternatives such as repo_repository, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_pull_requestA
Read-onlyIdempotent

Get a pull request by ID or list pull requests in a repository, optionally filtering status and source/target branch. Returns human-facing PR URLs.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum results per page (1–100).
skipNoPage offset. Pass nextSkip from the previous response.
actionYes
statusNoactive
projectNoProject name or ID. Defaults to ADO_PROJECT; discover with server_info/list_projects.
repositoryYesRepository name or ID in the selected project.
sourceBranchNoShort branch name, such as feature/foo, or refs/heads/feature/foo.
targetBranchNoShort branch name, such as feature/foo, or refs/heads/feature/foo.
pullRequestIdNoRequired for get.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds one useful behavioral detail — that results include human-facing PR URLs — but says nothing about pagination behavior or auth/permission requirements, which is the kind of context that would raise this above baseline.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the primary read operations front-loaded and the filter/return details trailing. No filler and nothing that could be cut without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter read tool with no output schema, the description covers both operation modes, the filters, and the nature of the return value (PR URLs). It is close to complete, missing only pagination/return-shape detail and explicit sibling routing, which are minor given the annotation coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 78% with 9 parameters, and the schema already documents top, skip (including nextSkip), project, repository, branches and pullRequestId. The description only echoes the status and branch filters, adding no syntax or format meaning beyond the structured fields, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states specific verbs and resource: 'Get a pull request by ID or list pull requests in a repository,' plus the optional filters. It clearly separates the two modes, but it never names or contrasts with the sibling repo_pull_request_write, leaving the read-vs-write routing to inference from the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies usage by pairing 'get' with an ID and 'list' with a repository, and notes the available filters, but gives no explicit when-to-use/when-not guidance, no mention of the write sibling as the alternative for mutations, and no prerequisites such as the ADO_PROJECT default.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_pull_request_writeA
Destructive

Create a PR after verifying both remote branches, or update its title, description, or draft state. Writes require a process-configured ADO_ALLOWED_REPOSITORIES entry; otherwise they are disabled. The agent supplies project/repository and local Git context. No merge, completion, autocomplete, policy bypass, retargeting, or branch deletion is supported. After an uncertain write outcome, list PRs before retrying.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoRequired for create; optional for update.
actionYes
isDraftNoCreate as draft, or change draft state on update.
projectNoProject name or ID. Defaults to ADO_PROJECT; discover with server_info/list_projects.
repositoryYesRepository name or ID in the selected project.
descriptionNoPR description. Empty string clears it on update.
sourceBranchNoRequired for create. Push the branch through Git first.
targetBranchNoRequired for create, such as develop.
pullRequestIdNoRequired for update; omit for create.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing that writes are disabled unless a process-configured ADO_ALLOWED_REPOSITORIES entry exists, enumerating the unsupported operations, stating the input the agent must supply, and prescribing behavior after an ambiguous write outcome. This is exactly the kind of mutation-side context the hints (destructive=false read profile) cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four front-loaded sentences: primary action first, then permission gate, then scope limits, then recovery. Each sentence carries distinct operational information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write tool with no output schema, the description covers authorization, scope limits, prerequisites, and failure handling, leaving only the returned value (e.g., the new PR identifier needed for follow-up calls) unmentioned.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 89%, so parameter meaning is largely carried by the schema itself; the description's mention of project/repository and local Git context adds little. The 'verify both remote branches' remark loosely reinforces sourceBranch/targetBranch semantics but no format or constraint detail is added.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States specific verbs and resource ('Create a PR ... or update its title, description, or draft state'), covering both action modes the enum supports. The explicit exclusion list (no merge, completion, autocomplete, policy bypass, retargeting, or branch deletion) draws a clean boundary against other PR-related operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear preconditions ('after verifying both remote branches'), an authorization gate (ADO_ALLOWED_REPOSITORIES), and a recovery path ('After an uncertain write outcome, list PRs before retrying'). It does not name the sibling tool (repo_pull_request) that performs that listing, so routing is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_repositoryA
Read-onlyIdempotent

Get or list Git repositories in an Azure DevOps Server project. Names and IDs are accepted. A configured ADO_ALLOWED_REPOSITORIES list restricts results and access. Use server_info/list_projects first if the project is unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum results per page (1–100).
skipNoPage offset. Pass nextSkip from the previous response.
actionYes
projectNoProject name or ID. Defaults to ADO_PROJECT; discover with server_info/list_projects.
repositoryNoRepository name or ID; required for get.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description still adds real behavioral context beyond them: an ADO_ALLOWED_REPOSITORIES allow-list silently restricts both results and access, which an agent must know before interpreting an empty list as 'no repositories exist.'

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose, then the allow-list caveat, then the prerequisite. Every sentence carries distinct information and none of it is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only lookup/list with no output schema, the description is nearly complete: it covers scope, accepted identifier forms, and the access restriction. It could mention returns (id/name/URL) or that paging uses skip, but the schema's nextSkip note largely covers pagination, leaving only a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 80%, so the schema already documents top, skip, project, and repository. The description repeats that 'names and IDs are accepted,' which is largely redundant with the schema's 'Project name or ID' phrasing, and adds nothing about the action enum. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get or list Git repositories') and the scope ('in an Azure DevOps Server project'), with the get-vs-list duality matching the action enum. The resource is unambiguous against siblings like repo_branch and repo_pull_request, which operate on entirely different entities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides an explicit prerequisite: 'Use server_info/list_projects first if the project is unknown.' This is clear context for when the caller lacks a project identifier, but it offers no exclusions or alternatives among the sibling repo tools for cases like resolving a branch or PR.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

server_infoA
Read-onlyIdempotent

Check Azure DevOps Server connectivity and safe configuration, or discover accessible projects without a configured default project. With a repository allowlist, diagnostics query only allowed repositories and discovery returns only their projects. Credentials are never returned. The API version is configured; product build is reported only if the server supplies it.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum results per page (1–100).
actionNoget
continuationTokenNoOpaque continuationToken from the previous response. Keep the same filters.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the safety profile is covered. The description adds genuine value beyond them: the repository allowlist narrows both diagnostics and discovery scope, credentials are never returned, the API version is fixed by configuration, and product build is reported only when the server supplies it. Auth requirements and error behavior are still unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the two primary modes before the scoping and security caveats. Every sentence carries information; the allowlist sentence is slightly dense but not redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must carry return-value expectations — and it does, by stating credentials are never returned and build is conditional. With three optional params and full annotation coverage, only auth/permission prerequisites are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%: top and continuationToken carry their own descriptions, while action has only an enum with no explanation. The description's two modes implicitly explain what action=get vs list_projects do, but it adds no format or pagination detail, so this sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names two concrete operations — connectivity/safe-configuration diagnostics and discovery of accessible projects — which maps cleanly onto the get/list_projects enum. It is clearly a server-level tool, distinct in domain from the repo_* siblings, though it never names or contrasts an alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a real trigger condition: use discovery 'without a configured default project', and use diagnostics to check connectivity/safe configuration. No exclusions or named alternatives are offered, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedrepo_branch
    • First observedrepo_pull_request
    • First observedrepo_pull_request_write
    • First observedrepo_repository
    • First observedserver_info

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct resource (server, repository, branch, PR read vs. PR write), and the `_write` suffix plus description clearly separates read from write for pull requests. The only mild overlap is repo_pull_request vs. repo_pull_request_write, which is mitigated by explicit read-only vs. create/update language.

Naming Consistency4/5

The set follows a predictable domain-prefix + resource pattern (repo_repository, repo_branch, repo_pull_request, repo_pull_request_write). server_info is the lone outlier that drops the prefix, and some tools are dual-purpose rather than verb_noun, but overall it reads consistently.

Tool Count4/5

Five tools is a tight, well-scoped surface for a read-mostly Azure DevOps Git/PR server. It is slightly lean, but each tool earns its place with no redundant entries.

Completeness3/5

Coverage is deliberately narrow: repositories and branches are read-only, PRs support create/update but no merge, comments, or completion, and there is no work item or pipeline support. The descriptions reference a list_projects capability that is not present as a tool, a notable gap for the stated discovery workflow.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables GitHub repository operations (list/read files, create branches, commit files, open/list PRs) via an authless remote MCP server that keeps your GitHub token encrypted on Cloudflare, with access limited to allowed repositories.
    -
  • A
    license
    C
    quality
    B
    maintenance
    A policy-aware MCP server for GitHub and GitHub Actions that enables safe AI-assisted infrastructure workflows—inspecting repositories, preparing branches and pull requests, and constrained remote mutations behind explicit preview-bound approval tokens.
    18
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server that enables AI assistants to interact with GitHub via a fine-grained personal access token — pushing commits, managing branches, opening and merging PRs, creating issues, and reading repositories. It runs locally with no telemetry and supports a read-only mode.
    15
    1
    MIT