Skip to main content
Glama
ajithnow

azdo-onprem-mcp

by ajithnow

azdo-onprem-mcp

Minimal Model Context Protocol server for self-hosted Azure DevOps Server (on-premises). It uses the REST APIs with a PAT and Basic auth (curl -u ":$PAT"), same as Azure DevOps Services patterns but with your own base URL.

Not for dev.azure.com only—any DevOps Server reachable over HTTPS works if the APIs respond.

Requirements

  • Node.js 18+

  • A Personal Access Token with at least Work Items (Read) (and any other scopes you rely on)

  • VPN/network access to your server if required

Related MCP server: Azure DevOps MCP Server

Install

npm install -g azdo-onprem-mcp

Or run without a global install:

npx azdo-onprem-mcp

The package exposes the CLI binary azdo-onprem-mcp (see package.jsonbin).

Environment variables

Variable

Required

Description

AZURE_BASE_URL

Yes

Team project root URL, same as in the browser for that project, e.g. https://devops.example.com/Collection/MyProject (no trailing slash required).

AZURE_PAT

Yes

Personal Access Token. Sent as Basic auth with an empty username (Authorization: Basic base64(":PAT")).

AZURE_COLLECTION_URL

No

Overrides collection root for listProjects only. If unset, the collection URL is derived by dropping the last path segment of AZURE_BASE_URL (e.g. .../Collection/Project.../Collection).

AZURE_HTTP_TIMEOUT_MS

No

HTTP timeout in ms (default 120000).

AZURE_DEVOPS_API_VERSION

No

REST api-version query parameter (default 7.1). Try 7.0 or 6.0 if your server is older.

MCP_DEBUG

No

Set to 1 to log request URLs and timing on stderr (no secrets).

Do not commit secrets. Prefer Cursor/IDE env injection or your OS secret store.

Cursor (or any MCP client)

Example mcp.json entry using the published package (-y lets npx install or run without an interactive prompt, which MCP clients need):

{
  "mcpServers": {
    "azdo-onprem": {
      "command": "npx",
      "args": ["-y", "azdo-onprem-mcp"],
      "env": {
        "AZURE_BASE_URL": "https://devops.example.com/Collection/MyProject",
        "AZURE_PAT": "<your-pat>"
      }
    }
  }
}

Alternatives

  • Global install: "command": "azdo-onprem-mcp" with no args (or an empty args array), if npm install -g azdo-onprem-mcp put the binary on your PATH.

  • Local clone: after npm install and npm run build, use "command": "node" and "args": ["/absolute/path/to/azdo-onprem-mcp/dist/server.js"] (adjust the path to your machine).

Reload MCP / restart the editor after changing env.

Windows / npx: From v1.0.1, HTTP calls use Node’s built-in fetch only (the axios dependency was removed). That avoids a known failure where npx pulled a broken tree and mime-db could not load db.json. If you still see strange missing-module errors, run npm cache clean --force and try again.

Tools

Tool

Description

getWorkItem

GET/_apis/wit/workitems/{id}? $expand=all — returns the full REST body as MCP structuredContent and as JSON text. Empty field values are often omitted by Azure DevOps; unset fields are not listed. If the chat UI shows a short snippet, use the structured payload (or your client’s tool-result JSON view).

searchWorkItems

WIQL search on System.Title (contains), then batch-fetch details — returns { id, title, state }[].

listProjects

GET/_apis/projects at the collection URL (see AZURE_COLLECTION_URL / derivation above).

Verify with curl (optional)

Mac/Linux: use single quotes around the URL so $expand is not interpreted by the shell.

export AZURE_PAT='your-pat'
curl -sS -u ":$AZURE_PAT" \
  'https://your-host/Collection/MyProject/_apis/wit/workitems/12345?$expand=all&api-version=7.1'

Development

From a clone of this repository:

npm install
npm run build
npm start

Source lives in src/ (TypeScript); npm run build emits to dist/. With AZURE_BASE_URL and AZURE_PAT set, npm start runs the MCP server on stdio (stop with Ctrl+C). Point your MCP client at this command or use npx azdo-onprem-mcp after publishing.

Publish to npm

From the repo root (with npm login if needed):

npm run build
npm publish

prepack runs npm run build automatically, so dist/ is always fresh in the tarball. For a scoped package name (e.g. @your-scope/azdo-onprem-mcp), use npm publish --access public the first time.

License

MIT (see package.json"license").

Available Tools

3 tools
getWorkItemA

Returns the complete Azure DevOps work item JSON from GET /_apis/wit/workitems/{id}?$expand=all. Includes the full fields map (System.Title, System.Description, System.Tags, custom fields, etc. — only fields with values are present), relations, _links, rev. This is NOT limited to id/title/state/assignedTo; read the fields object for description, tags, and links.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries full burden and excels: it details the exact response structure ('full fields map', 'relations', '_links', 'rev'), notes that only populated fields appear, and explicitly warns against expecting only basic fields. This adds significant behavioral context beyond the mere fact it 'gets' a work item.

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?

The description is three sentences, each earning its place: the first states the core purpose, the second details the response contents, and the third clarifies scope. It is front-loaded and compact with no fluff.

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

Completeness5/5

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

For a one-parameter GET with no output schema and no annotations, the description is thorough: it names the endpoint, explains the included fields, and clarifies the absence of certain fields. It also differentiates from siblings, making it complete for its complexity.

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

Parameters4/5

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

Schema has zero descriptions, so the description must compensate. It does by embedding 'id' in the API path, indicating it's the work item identifier. However, it doesn't elaborate on the type or constraints beyond the schema's integer and exclusiveMinimum, so it slightly over-delivers but leaves a little room for more.

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?

The description starts with a specific verb+resource: 'Returns the complete Azure DevOps work item JSON from GET /_apis/wit/workitems/{id}?$expand=all.' It clearly states the exact API endpoing and the scope of data returned, distinguishing it from sibling tools like searchWorkItems by emphasizing it's not limited to a subset of fields.

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?

The description implies usage: use this when you need the full work item JSON for a known ID. The phrase 'This is NOT limited to id/title/state/assignedTo' suggests that if you only need those basic fields, other tools may suffice, but it doesn't explicitly name alternatives or state when-not-to-use. So it provides clear context without exclusions, fitting score 4.

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

listProjectsA

List team projects in the Azure DevOps collection. Uses AZURE_COLLECTION_URL if set, otherwise derives collection URL from AZURE_BASE_URL.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does add useful context about environment variable fallback (AZURE_COLLECTION_URL vs AZURE_BASE_URL), which is a behavioral trait. However, it does not disclose the return format, pagination, or any authentication requirements, leaving gaps in transparency for a tool with no annotations.

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?

The description is two short sentences, front-loaded with the action and resource, and contains no superfluous words. It efficiently conveys the core purpose and a configuration detail without waste.

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?

Given the tool's simplicity (0 params, no output schema), the description covers the main purpose and adds a useful configuration note. However, it does not explicitly describe what the response includes (e.g., project IDs, names), which would be expected when no output schema exists. It is nearly complete but lacks that minor detail, so a 4 is appropriate.

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

Parameters4/5

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

The tool has zero parameters, so the description has nothing to explain. The baseline for 0 parameters is 4, and the description correctly avoids adding any unnecessary parameter details.

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?

The description clearly states the verb 'List' and the resource 'team projects in the Azure DevOps collection,' which is specific and unambiguous. It naturally distinguishes from sibling tools (getWorkItem, searchWorkItems) that deal with work items, not projects.

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?

The description provides clear context for when to use the tool: when you need to list team projects in the collection. It does not explicitly mention alternatives or exclusions, but the sibling tools are sufficiently different that the intended usage is obvious. No misleading guidance is present.

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

searchWorkItemsA

Search work items whose title contains the given text (WIQL CONTAINS on System.Title). Returns { id, title, state }[].

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the burden of disclosure. It specifies the underlying WIQL CONTAINS operation and the return shape, but does not explicitly state that the operation is read-only or describe any error/empty-result behavior. It adds some useful detail beyond a bare purpose statement.

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?

The description is a single, focused sentence that front-loads the action and resource, followed by a compact return type note. Every word contributes value with no fluff.

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

Completeness5/5

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

For a simple tool with one parameter and no annotations, the description provides the essential information: what it searches, how it searches (WIQL CONTAINS), and what it returns. The output schema is absent but the return shape is explicitly given, making the description self-sufficient.

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

Parameters4/5

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

The schema has one parameter ('query') with 0% description coverage, so the description must compensate. It clarifies that the query is 'the given text' to search for in the title, which adds meaning beyond the raw parameter name. However, it doesn't add details like case sensitivity or wildcard support.

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?

The description clearly states the tool searches work items by title text, using a specific verb ('Search') and resource ('work items'). It distinguishes from siblings by focusing on title-based search rather than listing projects or fetching a single work item.

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

Usage Guidelines2/5

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

The description implies a search use case, but provides no explicit guidance on when to use this tool versus alternatives like getWorkItem or listProjects. There are no prerequisites, exclusions, or context about when search is preferred.

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. Dates show when Glama detected each change.

  1. 3 tool updatesv1.0.2
    • First observedgetWorkItem
    • First observedlistProjects
    • First observedsearchWorkItems

TDQS

A4.2/5.0
Disambiguation5/5

Each tool targets a distinct resource/action: listProjects for projects, getWorkItem for a specific work item by ID, and searchWorkItems for finding work items by title. No overlap in functionality.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in camelCase: listProjects, getWorkItem, searchWorkItems. The naming is predictable and uniform.

Tool Count5/5

With only three tools, each serves a clear and non-redundant purpose. The count is well-scoped for a focused Azure DevOps read-only server.

Completeness2/5

The tool surface is severely limited, providing only read operations. There is no ability to create, update, or delete work items, nor any support for queries beyond title-based search. Significant gaps exist for a typical Azure DevOps integration.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ajithnow/azdo-onprem-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server