From 1cca27ad809994f37abe14db353718b3c9ed5e02 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Thu, 17 Jul 2025 16:59:18 -0400 Subject: [PATCH 1/2] feat: add MCP API headers to requests --- src/api/apiClient.ts | 2 +- src/mcp/index.ts | 9 ++++++++- src/mcp/utils/api.ts | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/api/apiClient.ts b/src/api/apiClient.ts index 8e4afd1fc..e5d5dd161 100644 --- a/src/api/apiClient.ts +++ b/src/api/apiClient.ts @@ -12,7 +12,7 @@ export const setDVCReferrer = ( version: string, caller = 'cli', ): void => { - axiosClient.defaults.headers.common['dvc-referrer'] = 'cli' + axiosClient.defaults.headers.common['dvc-referrer'] = caller // Ensure we have valid values before stringifying const metadata = { diff --git a/src/mcp/index.ts b/src/mcp/index.ts index f21ac9a26..03027efb7 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -5,6 +5,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { DevCycleMCPServer } from './server' import { readFileSync } from 'fs' import { join } from 'path' +import { setMCPHeaders } from './utils/headers' // Get version for MCP server function getVersion(): string { @@ -46,10 +47,16 @@ if (args.includes('--help') || args.includes('-h')) { } async function main() { + const version = getVersion() + + // Set up MCP-specific headers for all API requests + // This ensures that requests from the MCP server are properly identified + setMCPHeaders(version) + const server = new Server( { name: 'devcycle', - version: getVersion(), + version, }, { capabilities: { diff --git a/src/mcp/utils/api.ts b/src/mcp/utils/api.ts index 6cf03b42e..8b7334182 100644 --- a/src/mcp/utils/api.ts +++ b/src/mcp/utils/api.ts @@ -1,4 +1,5 @@ import { DevCycleAuth } from './auth' +import { setMCPToolCommand } from './headers' function getErrorMessage(error: unknown): string { if (error instanceof Error && error.message) { @@ -49,6 +50,9 @@ export class DevCycleApiClient { this.auth.requireProject() } + // Set the specific MCP tool command in headers before making API calls + setMCPToolCommand(operationName) + const authToken = this.auth.getAuthToken() const projectKey = requiresProject ? this.auth.getProjectKey() : '' From aa0e7546166c5dcc6bba1bd3489d3f5e72284728 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Thu, 17 Jul 2025 16:59:37 -0400 Subject: [PATCH 2/2] feat: add headers.ts file --- src/mcp/utils/headers.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/mcp/utils/headers.ts diff --git a/src/mcp/utils/headers.ts b/src/mcp/utils/headers.ts new file mode 100644 index 000000000..2ec4aa63e --- /dev/null +++ b/src/mcp/utils/headers.ts @@ -0,0 +1,29 @@ +import { setDVCReferrer } from '../../api/apiClient' + +// Store the version for reuse in tool commands +let mcpVersion: string = 'unknown' + +/** + * Sets up MCP-specific headers for all API requests + * This ensures that API calls made from the MCP server are properly identified + * and can be tracked separately from CLI commands + */ +export function setMCPHeaders(version: string): void { + // Store version for later use in tool commands + mcpVersion = version + + // Set the referrer to identify this as an MCP request + // Command will be set dynamically for each tool call + // Caller is 'mcp' to distinguish from 'cli' and other callers + setDVCReferrer('mcp', version, 'mcp') +} + +/** + * Updates the command in the headers for a specific MCP tool call + * This allows tracking of individual MCP operations (e.g., "list_features", "create_project") + * @param toolName - The name of the MCP tool being called + */ +export function setMCPToolCommand(toolName: string): void { + // Update the command to be the tool name, keeping version and caller the same + setDVCReferrer(toolName, mcpVersion, 'mcp') +}