Skip to content

Commit e6d35fd

Browse files
committed
Add Dev Proxy MCP Server. Closes #244
Closes #244
1 parent 4847d30 commit e6d35fd

File tree

7 files changed

+241
-4
lines changed

7 files changed

+241
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3737
- Command: `dev-proxy-toolkit.restart` - Restart Dev Proxy
3838
- Snippets: `devproxy-plugin-typespec-generator` - TypeSpecGeneratorPlugin instance
3939
- Snippets: `devproxy-plugin-typespec-generator-config` - TypeSpecGeneratorPlugin config section
40+
- MCP Server: Dev Proxy
4041

4142
### Changed:
4243

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ Shown when the active document is a Dev Proxy configuration file
5555
- Start recording
5656
- Stop recording
5757

58+
### MCP Server
59+
60+
- Find Dev Proxy documentation
61+
- Get the installed Dev Proxy version
62+
5863
### Notifications
5964

6065
- Not installed

package-lock.json

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
2+
"enabledApiProposals": [
3+
"mcpConfigurationProvider"
4+
],
25
"name": "dev-proxy-toolkit",
36
"displayName": "Dev Proxy Toolkit",
47
"description": "Makes it easy to create and update Dev Proxy configuration files.",
@@ -119,6 +122,12 @@
119122
}
120123
]
121124
},
125+
"modelContextServerCollections": [
126+
{
127+
"id": "devproxymcp",
128+
"label": "Dev Proxy"
129+
}
130+
],
122131
"snippets": [
123132
{
124133
"language": "json",
@@ -189,6 +198,7 @@
189198
"@types/vscode": "^1.89.0",
190199
"@typescript-eslint/eslint-plugin": "^6.21.0",
191200
"@typescript-eslint/parser": "^6.21.0",
201+
"@vscode/dts": "^0.4.1",
192202
"@vscode/test-cli": "^0.0.10",
193203
"@vscode/test-electron": "^2.4.1",
194204
"copy-webpack-plugin": "^12.0.2",
@@ -203,4 +213,4 @@
203213
"dependencies": {
204214
"json-to-ast": "^2.1.0"
205215
}
206-
}
216+
}

src/extension.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@ import { createStatusBar, statusBarLoop, updateStatusBar } from './statusbar';
77
import { registerCodeActions } from './codeactions';
88
import { updateGlobalState } from './state';
99
import { VersionPreference } from './enums';
10+
import { registerMcpServer } from './mcp';
1011

1112
export const activate = async (context: vscode.ExtensionContext): Promise<vscode.ExtensionContext> => {
13+
1214
const configuration = vscode.workspace.getConfiguration('dev-proxy-toolkit');
1315
const versionPreference = configuration.get('version') as VersionPreference;
14-
16+
1517
const statusBar = createStatusBar(context);
1618
await updateGlobalState(context, versionPreference);
17-
19+
1820
const collection = vscode.languages.createDiagnosticCollection('dev-proxy-toolkit');
19-
21+
2022
registerDocumentListeners(context, collection);
2123
registerCodeActions(context);
2224
registerCodeLens(context);
2325
registerCommands(context, configuration);
26+
registerMcpServer(context);
2427

2528
const notification = handleStartNotification(context);
2629
processNotification(notification);

src/mcp.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as vscode from 'vscode';
2+
3+
export const registerMcpServer = (context: vscode.ExtensionContext) => {
4+
5+
const didChangeEmitter = new vscode.EventEmitter<void>();
6+
7+
context.subscriptions.push(vscode.lm.registerMcpConfigurationProvider('devproxymcp', {
8+
onDidChange: didChangeEmitter.event,
9+
provideMcpServerDefinitions: async () => {
10+
const server: vscode.McpStdioServerDefinition =
11+
{
12+
label: "Dev Proxy",
13+
command: "npx",
14+
args: [
15+
"-y",
16+
"@devproxy/mcp"
17+
],
18+
env: {}
19+
};
20+
21+
return [server];
22+
}
23+
}));
24+
};
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
declare module 'vscode' {
6+
7+
// https://github.com/microsoft/vscode/issues/243522
8+
9+
/**
10+
* McpStdioServerDefinition represents an MCP server available by running
11+
* a local process and listening to its stdin and stdout streams.
12+
*/
13+
export class McpStdioServerDefinition {
14+
/**
15+
* The human-readable name of the server.
16+
*/
17+
label: string;
18+
19+
/**
20+
* The working directory used to start the server.
21+
*/
22+
cwd?: Uri;
23+
24+
/**
25+
* The command used to start the server. Node.js-based servers may use
26+
* `process.execPath` to use the editor's version of Node.js to run the script.
27+
*/
28+
command: string;
29+
/**
30+
* Additional command-line arguments passed to the server.
31+
*/
32+
args: string[];
33+
34+
/**
35+
* Optional additional environment information for the server. Variables
36+
* in this environment will overwrite or remove (if null) the default
37+
* environment variables.
38+
*/
39+
env: Record<string, string | number | null>;
40+
41+
/**
42+
* Optional version identification for the server. If this changes, the
43+
* editor will indicate that tools have changed and prompt to refresh them.
44+
*/
45+
version?: string;
46+
47+
/**
48+
* @param label The human-readable name of the server.
49+
* @param command The command used to start the server.
50+
* @param args Additional command-line arguments passed to the server.
51+
* @param env Optional additional environment information for the server.
52+
* @param version Optional version identification for the server.
53+
*/
54+
constructor(label: string, command: string, args?: string[], env?: Record<string, string | number | null>, version?: string);
55+
}
56+
57+
/**
58+
* McpHttpServerDefinition represents an MCP server available using the
59+
* Streamable HTTP transport.
60+
*/
61+
export class McpHttpServerDefinition {
62+
/**
63+
* The human-readable name of the server.
64+
*/
65+
label: string;
66+
67+
/**
68+
* The URI of the server. The editor will make a POST request to this URI
69+
* to begin each session.
70+
*/
71+
uri: Uri;
72+
73+
/**
74+
* Optional additional heads included with each request to the server.
75+
*/
76+
headers: Record<string, string>;
77+
78+
/**
79+
* Optional version identification for the server. If this changes, the
80+
* editor will indicate that tools have changed and prompt to refresh them.
81+
*/
82+
version?: string;
83+
84+
/**
85+
* @param label The human-readable name of the server.
86+
* @param uri The URI of the server.
87+
* @param headers Optional additional heads included with each request to the server.
88+
*/
89+
constructor(label: string, uri: Uri, headers?: Record<string, string>, version?: string);
90+
}
91+
92+
export type McpServerDefinition = McpStdioServerDefinition | McpHttpServerDefinition;
93+
94+
/**
95+
* A type that can provide server configurations. This may only be used in
96+
* conjunction with `contributes.modelContextServerCollections` in the
97+
* extension's package.json.
98+
*
99+
* To allow the editor to cache available servers, extensions should register
100+
* this before `activate()` resolves.
101+
*/
102+
export interface McpConfigurationProvider<T extends McpServerDefinition = McpServerDefinition> {
103+
/**
104+
* Optional event fired to signal that the set of available servers has changed.
105+
*/
106+
onDidChange?: Event<void>;
107+
108+
/**
109+
* Provides available MCP servers. The editor will call this method eagerly
110+
* to ensure the availability of servers for the language model, and so
111+
* extensions should not take actions which would require user
112+
* interaction, such as authentication.
113+
*
114+
* @param token A cancellation token.
115+
* @returns An array of MCP available MCP servers
116+
*/
117+
provideMcpServerDefinitions(token: CancellationToken): ProviderResult<T[]>;
118+
119+
/**
120+
* This function will be called when the editor needs to start MCP server.
121+
* At this point, the extension may take any actions which may require user
122+
* interaction, such as authentication.
123+
*
124+
* The extension may return undefined on error to indicate that the server
125+
* should not be started.
126+
*
127+
* @param server The MCP server to resolve
128+
* @param token A cancellation token.
129+
* @returns The given, resolved server or thenable that resolves to such.
130+
*/
131+
resolveMcpServerDefinition?(server: T, token: CancellationToken): ProviderResult<T>;
132+
}
133+
134+
namespace lm {
135+
export function registerMcpConfigurationProvider(id: string, provider: McpConfigurationProvider): Disposable;
136+
}
137+
}

0 commit comments

Comments
 (0)