Skip to content

Commit af218df

Browse files
authored
mcp: fix authority-less MCP resources cannot be read by VS Code (microsoft#250908)
Fixes microsoft#250905
1 parent c9f19f8 commit af218df

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/vs/workbench/contrib/mcp/common/mcpTypes.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,14 +609,18 @@ export const mcpServerIcon = registerIcon('mcp-server', Codicon.mcp, localize('m
609609
export namespace McpResourceURI {
610610
export const scheme = 'mcp-resource';
611611

612+
// Random placeholder for empty authorities, otherwise they're represente as
613+
// `scheme//path/here` in the URI which would get normalized to `scheme/path/here`.
614+
const emptyAuthorityPlaceholder = 'dylo78gyp'; // chosen by a fair dice roll. Guaranteed to be random.
615+
612616
export function fromServer(def: McpDefinitionReference, resourceURI: URI | string): URI {
613617
if (typeof resourceURI === 'string') {
614618
resourceURI = URI.parse(resourceURI);
615619
}
616620
return resourceURI.with({
617621
scheme,
618622
authority: encodeHex(VSBuffer.fromString(def.id)),
619-
path: ['', resourceURI.scheme, resourceURI.authority].join('/') + resourceURI.path,
623+
path: ['', resourceURI.scheme, resourceURI.authority || emptyAuthorityPlaceholder].join('/') + resourceURI.path,
620624
});
621625
}
622626

@@ -636,8 +640,8 @@ export namespace McpResourceURI {
636640
definitionId: decodeHex(uri.authority).toString(),
637641
resourceURI: uri.with({
638642
scheme: serverScheme,
639-
authority,
640-
path: '/' + path.join('/'),
643+
authority: authority.toLowerCase() === emptyAuthorityPlaceholder ? '' : authority,
644+
path: path.length ? ('/' + path.join('/')) : '',
641645
}),
642646
};
643647
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
6+
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
7+
import { McpResourceURI } from '../../common/mcpTypes.js';
8+
import * as assert from 'assert';
9+
10+
suite('MCP Types', () => {
11+
ensureNoDisposablesAreLeakedInTestSuite();
12+
13+
test('McpResourceURI - round trips', () => {
14+
const roundTrip = (uri: string) => {
15+
const from = McpResourceURI.fromServer({ label: '', id: 'my-id' }, uri);
16+
const to = McpResourceURI.toServer(from);
17+
assert.strictEqual(to.definitionId, 'my-id');
18+
assert.strictEqual(to.resourceURI.toString(true), uri, `expected to round trip ${uri}`);
19+
};
20+
21+
roundTrip('file:///path/to/file.txt');
22+
roundTrip('custom-scheme://my-path/to/resource.txt');
23+
roundTrip('custom-scheme://my-path');
24+
roundTrip('custom-scheme://my-path/');
25+
roundTrip('custom-scheme://my-path/?with=query&params=here');
26+
});
27+
});

0 commit comments

Comments
 (0)