feat: add X-Dataverse-Skills tracking header to all execution surfaces#36
Open
arorashivam96 wants to merge 1 commit into
Open
feat: add X-Dataverse-Skills tracking header to all execution surfaces#36arorashivam96 wants to merge 1 commit into
arorashivam96 wants to merge 1 commit into
Conversation
f300fc3 to
8d8729a
Compare
Inject a custom HTTP header (X-Dataverse-Skills) on every Dataverse API
call so server-side telemetry can trace requests back to the execution
surface (python-sdk, web-api, mcp-proxy) and plugin version.
- Add tracking_headers() and create_client() to auth.py
- Patch OData _headers in create_client() for automatic SDK injection
- Update mcp_proxy.py to include header on forwarded requests
- Migrate all skill SDK blocks to create_client() shorthand
- Add **tracking_headers("web-api") to all raw Web API headers dicts
- Bump plugin version to 1.2.0 across all five version locations
- Document auth.py as 5th version file in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8d8729a to
4b43a8f
Compare
suyask-msft
reviewed
Apr 18, 2026
| import sys | ||
| from pathlib import Path | ||
|
|
||
| PLUGIN_VERSION = "1.2.0" |
Collaborator
There was a problem hiding this comment.
This can't be hardcoded string right?
suyask-msft
reviewed
Apr 18, 2026
| _orig = odata._headers | ||
| def _with_tracking(): | ||
| h = _orig() | ||
| h.update(tracking_headers("python-sdk")) |
Collaborator
There was a problem hiding this comment.
Do we know which skill was loaded?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a custom HTTP header
X-Dataverse-Skillsto every Dataverse API call made through the plugin's Python SDK and Web API code paths. This enables server-side telemetry to trace requests back to the specific execution surface and plugin version that produced them.Header format:
X-Dataverse-Skills: surface=<surface>; version=<version>Motivation
Dataverse telemetry captures HTTP headers but not request bodies. Without a surface identifier, there is no way to distinguish whether a call originated from the Python SDK, a raw Web API script, or the MCP proxy. This header closes that observability gap for debugging, usage analytics, and support triage.
What Changed
.github/plugins/dataverse/scripts/auth.pyPLUGIN_VERSION,tracking_headers(),create_client().github/plugins/dataverse/scripts/mcp_proxy.pyforward()requestskills/dv-data/SKILL.mdcreate_client()skills/dv-query/SKILL.mdcreate_client(); Web API blocks addtracking_headers("web-api")skills/dv-metadata/SKILL.mdcreate_client(); Web API blocks addtracking_headers("web-api")skills/dv-solution/SKILL.mdcreate_client(); Web API blocks addtracking_headers("web-api")skills/dv-overview/SKILL.mdcreate_clientCLAUDE.md1.2.0Tracking Header Coverage
create_client())python-sdk_headers()method. Every SDK HTTP call carries the header with zero code changes at call sites.urllib.request)web-api**tracking_headers("web-api")in each headers dict. Used for forms, views,$apply, N:N$expand— operations the SDK does not support.mcp_proxy.py)mcp-proxyforward(), butmcp_proxy.pyis legacy code not used in any documented workflow. The/api/mcpendpoint also returns 403 for device-code tokens because the calling app ID is not registered as an MCP client.@microsoft/dataverse)What Works and What Does Not
create_client()to create/read/update/delete recordsCreateMultiple,UpdateMultiple,UpsertMultiple)$apply, N:N$expand**tracking_headers("web-api")merged into every headers dict in skill examplesget_credential()+ manualDataverseClient()create_client()injects the header. Legacy pattern still works but has no tracking.create_record,read_query, etc.)mcp_proxy.py) called standalone/api/mcprejects device-code tokens — app ID not in MCP client allowlistpac solution export, etc.)InteractiveBrowserCredentialdirectlyauth.pyentirely — nocreate_client()in that pathTesting
python .github/evals/static_checks.pypasses (6 skill files, 70 Python blocks, 5 categories)X-Dataverse-Skills: surface=python-sdk; version=1.2.0present in actual HTTP requests viarequests.Session.sendinterceptioncreate_client()— server-side telemetry verification pending/api/mcpreturns 403 with device-code auth — confirms mcp_proxy.py is not usable in current auth setupKnown Limitations
npm MCP server has no header injection — Microsoft's
@microsoft/dataversepackage is opaque. No MCP protocol mechanism exists for client-side HTTP header customization. This is the biggest coverage gap since MCP is the primary tool for interactive queries.mcp_proxy.py is dead code — It exists in the repo and has the tracking header, but is not referenced in any skill file, not used in any MCP configuration, and cannot authenticate to
/api/mcpwith the standard device-code flow. It was superseded by the npm package.Legacy SDK pattern not covered — Scripts that use the old
get_credential()+DataverseClient()pattern directly (withoutcreate_client()) will not have tracking headers. The skill files have been updated to usecreate_client(), but user scripts written before this change are unaffected.Version
1.1.0->1.2.0(minor — new pattern, no breaking changes)