Skip to content

feat(integrations): add Azure DevOps MCP catalog entry - #716

Draft
luxleader wants to merge 1 commit into
OpenHands:mainfrom
luxleader:feat/azure-devops-mcp-15769
Draft

luxleader wants to merge 1 commit into
OpenHands:mainfrom
luxleader:feat/azure-devops-mcp-15769

Conversation

@luxleader

Copy link
Copy Markdown

HUMAN:


AGENT:
Adds the missing Azure DevOps catalog entry and verifies the real published MCP command, package exports, and current Canvas adapter. Authenticated Azure resource calls and Entra login remain unverified.

Why

Azure DevOps is absent from the integration catalog, so clients cannot discover its official MCP server. The issue's proposed configuration names a different npm package and unsupported catalog fields. The hosted server also needs MCP OAuth discovery and a registered Entra client, rather than hard-coded Azure DevOps REST API OAuth scopes.

Summary

  • Add one canonical Azure DevOps JSON entry: editable Streamable HTTP endpoint with MCP OAuth discovery, plus the official @azure-devops/mcp PAT stdio connection with required organization and base64-encoded PERSONAL_ACCESS_TOKEN inputs.
  • Ship the existing Canvas Azure DevOps logo and regenerate the JS index.
  • Add three regression tests and temporary investigation/smoke artifacts under .pr/.

Issue Number

Refs OpenHands/OpenHands#15769.

Related existing proposal: #384. This independent branch uses current main and the current strict schema. It avoids hard-coded Entra endpoints and the REST API token audience; the live MCP resource advertises https://mcp.dev.azure.com/.default.

How to Test

pip install -e . pytest jsonschema mcp
npm run build:integrations
PYTHONUTF8=1 pytest -q tests/test_catalogs.py tests/test_catalog_schema.py tests/test_integration_catalog_in_sync.py
python .pr/smoke_azure_devops.py
npm pack --dry-run
pip wheel --no-deps .

Observed locally on Windows, Python 3.13 and Node 24:

  • Before implementation: all three new Azure DevOps tests failed because the entry was absent.
  • After implementation: 120 passed across catalog contracts, strict JSON Schema, typed Python models, JS/Python parity, and filters.
  • The real catalog command launched published Azure DevOps MCP Server 2.10.0, negotiated MCP 2025-11-25, and returned 40 tools, including core_list_projects and work-item tools. This uses a synthetic PAT and performs no authenticated Azure API calls.
  • The extracted npm tarball and Python wheel both expose Azure DevOps lookup and MCP/OAuth filters; npm includes the SVG.
  • The actual Canvas adapter selected the PAT install form and exposed the organization and password fields.
  • Public hosted OAuth metadata returned 200; unauthenticated HTTP initialize returned 401 with the protected-resource metadata challenge.
  • scripts/sync_extensions.py --check and git diff --check passed. The sync script reported three existing non-blocking coverage warnings.

Details, inspected revisions, and reproducible smoke scripts: investigation.

Video/Screenshots

No UI source changes. Package, actual Canvas adapter, and MCP protocol evidence are recorded in .pr/analysis.md.

Notes

This is the extensions-owned catalog portion. Current Canvas skips strategy-only OAuth options in its marketplace modal and selects the PAT option. The catalog documents remote setup through the custom MCP editor, where the registered client ID can be supplied. It does not claim one-click hosted OAuth or a completed authenticated Azure smoke test.

After an extensions release containing this entry, Canvas needs its normal package/lockfile dependency update. A generic marketplace flow for OAuth client inputs and connection-option selection belongs in Canvas. Real project/work-item calls and OAuth login require a reviewer-owned Azure organization, PAT, and Entra app registration.

Kept draft under the repository template; the HUMAN section is untouched.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

📁 PR Artifacts Notice

This PR contains a .pr/ directory with temporary PR-specific documents. Because this is a fork PR, the workflow will open or update a cleanup PR against main after merge.

@enyst enyst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm an AI agent (Claude Code, based on Opus 5.5) helping Engel Nyst (@enyst) with project work.

Of the two Azure DevOps PRs, this is the one to take forward, and #384 should be closed in its favour. This PR is based on current main and passes the current schema. Its connection details match Microsoft's docs and the live OAuth metadata, which #384's do not. I'm leaving a comment rather than approving only because the PR is still a draft and the process gates are open.

To make it mergeable:

  1. Write the HUMAN: note. It still has the template placeholder, so Validate PR description will fail once the PR is marked ready.
  2. Link an issue in this repo that has ready-for-dev. OpenHands/OpenHands#15769 is in another repo, so the checker can't see it. As written, it would read the bare #384 in that section as the linked issue.
  3. The required test, sync-extensions and validate-claude-code checks haven't run on this fork head yet.

Minor, non-blocking:

  • azure-devops.json#L71: the link uses the anchor #personal-access-token-pat, which doesn't exist in GETTINGSTARTED.md. The heading is ### Personal Access Token, so the anchor should be #personal-access-token.
  • tests/test_catalogs.py#L125 pins the full transport and some of the notes wording. A later copy edit to the entry would then need a second file changed. This is optional, but you could cut the test down to the regression you care about (strategy-only OAuth and the PAT args), since the schema tests already check the entry's shape.

Checked:

  • In the microsoft/azure-devops-mcp source, --authentication pat is a valid choice. It reads PERSONAL_ACCESS_TOKEN as base64 of <email>:<PAT>, and yargs accepts the organization positional after the flags. The latest @azure-devops/mcp is 2.10.0, published 2026-09-09. Node 20+ is the documented requirement.
  • Microsoft's remote-server docs accept both https://mcp.dev.azure.com/ and /{organization}. They require a custom Entra app registration and say Entra doesn't support DCR. The notes field reflects all of this accurately.
  • The public /.well-known/oauth-protected-resource lists the scope https://mcp.dev.azure.com/.default and the authorization server login.microsoftonline.com/organizations/v2.0.
  • The JSON validates against main's schema, and catalog-index.js matches the build script's output. Main's catalog tests pass with the entry and icon added (117).
  • Not verified: Entra login and authenticated PAT tool calls.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants