Skip to content

Commit a669272

Browse files
committed
Track subscribed resources and show the appropriate subscribe or unsubscribe button on selected resource panel.
If the server does not support resource subscriptions, do not show any subscription buttons. * In App.tsx - useState for resourceSubscriptions, setResourceSubscriptions a Set of type string. - in subscribeToResource() - only make the request to subscribe if the uri is not in the resourceSubscriptions set - in unsubscribeFromResource() - only make the request to unsubscribe if the uri is in the resourceSubscriptions set - in ResourceTab element, - pass a boolean resourceSubscriptionsSupported as serverCapabilities.resources.subscribe - pass resourceSubscriptions as a prop * In ResourcesTab.tsx - deconstruct resourceSubscriptions and resourceSubscriptionsSupported from props and add prop type - in selected resource panel - don't show subscribe or unsubscribe buttons unless resourceSubscriptionsSupported is true - only show subscribe button if selected resource uri is not in resourceSubscriptions set - only show unsubscribe button if selected resource uri is in resourceSubscriptions set - wrap buttons in a flex div that is - justified right - has a minimal gap between - 2/5 wide (just big enough to contain two buttons and leave the h3 text 3/5 of the row to render and not overflow.
1 parent 747c015 commit a669272

File tree

4 files changed

+45
-23
lines changed

4 files changed

+45
-23
lines changed

client/src/App.tsx

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ const App = () => {
128128
const [selectedResource, setSelectedResource] = useState<Resource | null>(
129129
null,
130130
);
131+
const [resourceSubscriptions, setResourceSubscriptions] = useState<Set<string>>(new Set<string>());
132+
131133
const [selectedPrompt, setSelectedPrompt] = useState<Prompt | null>(null);
132134
const [selectedTool, setSelectedTool] = useState<Tool | null>(null);
133135
const [nextResourceCursor, setNextResourceCursor] = useState<
@@ -310,26 +312,37 @@ const App = () => {
310312

311313
const subscribeToResource = async (uri: string) => {
312314

313-
await makeRequest(
314-
{
315-
method: "resources/subscribe" as const,
316-
params: { uri },
317-
},
318-
z.object({}),
319-
"resources",
320-
);
315+
if (!resourceSubscriptions.has(uri)) {
316+
await makeRequest(
317+
{
318+
method: "resources/subscribe" as const,
319+
params: { uri },
320+
},
321+
z.object({}),
322+
"resources",
323+
);
324+
const clone = new Set(resourceSubscriptions);
325+
clone.add(uri);
326+
setResourceSubscriptions(clone);
327+
}
328+
321329
};
322330

323331
const unsubscribeFromResource = async (uri: string) => {
324332

325-
await makeRequest(
326-
{
327-
method: "resources/unsubscribe" as const,
328-
params: { uri },
329-
},
330-
z.object({}),
331-
"resources",
332-
);
333+
if (resourceSubscriptions.has(uri)) {
334+
await makeRequest(
335+
{
336+
method: "resources/unsubscribe" as const,
337+
params: { uri },
338+
},
339+
z.object({}),
340+
"resources",
341+
);
342+
const clone = new Set(resourceSubscriptions);
343+
clone.delete(uri);
344+
setResourceSubscriptions(clone);
345+
}
333346
};
334347

335348

@@ -510,6 +523,8 @@ const App = () => {
510523
clearError("resources");
511524
setSelectedResource(resource);
512525
}}
526+
resourceSubscriptionsSupported={serverCapabilities?.resources?.subscribe || false}
527+
resourceSubscriptions={resourceSubscriptions}
513528
subscribeToResource={(uri) => {
514529
clearError("resources");
515530
subscribeToResource(uri);

client/src/components/ResourcesTab.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const ResourcesTab = ({
2626
readResource,
2727
selectedResource,
2828
setSelectedResource,
29+
resourceSubscriptionsSupported,
30+
resourceSubscriptions,
2931
subscribeToResource,
3032
unsubscribeFromResource,
3133
handleCompletion,
@@ -54,6 +56,8 @@ const ResourcesTab = ({
5456
nextCursor: ListResourcesResult["nextCursor"];
5557
nextTemplateCursor: ListResourceTemplatesResult["nextCursor"];
5658
error: string | null;
59+
resourceSubscriptionsSupported: boolean;
60+
resourceSubscriptions: Set<string>;
5761
subscribeToResource: (uri: string) => void;
5862
unsubscribeFromResource: (uri: string) => void;
5963
}) => {
@@ -168,21 +172,24 @@ const ResourcesTab = ({
168172
: "Select a resource or template"}
169173
</h3>
170174
{selectedResource && (
171-
<>
172-
<Button
175+
<div className="flex row-auto gap-1 justify-end w-2/5">
176+
{ resourceSubscriptionsSupported && !resourceSubscriptions.has(selectedResource.uri) && <Button
173177
variant="outline"
174178
size="sm"
175179
onClick={() => subscribeToResource(selectedResource.uri)}
176180
>
177181
Subscribe
178182
</Button>
183+
}
184+
{ resourceSubscriptionsSupported && resourceSubscriptions.has(selectedResource.uri) &&
179185
<Button
180186
variant="outline"
181187
size="sm"
182188
onClick={() => unsubscribeFromResource(selectedResource.uri)}
183189
>
184190
Unsubscribe
185191
</Button>
192+
}
186193
<Button
187194
variant="outline"
188195
size="sm"
@@ -191,7 +198,7 @@ const ResourcesTab = ({
191198
<RefreshCw className="w-4 h-4 mr-2" />
192199
Refresh
193200
</Button>
194-
</>
201+
</div>
195202
)}
196203
</div>
197204
<div className="p-4">

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
"publish-all": "npm publish --workspaces --access public && npm publish --access public"
3535
},
3636
"dependencies": {
37-
"@modelcontextprotocol/inspector-client": "0.4.1",
38-
"@modelcontextprotocol/inspector-server": "0.4.1",
37+
"@modelcontextprotocol/inspector-client": "^0.5.1",
38+
"@modelcontextprotocol/inspector-server": "^0.5.1",
3939
"concurrently": "^9.0.1",
4040
"shell-quote": "^1.8.2",
4141
"spawn-rx": "^5.1.2",

0 commit comments

Comments
 (0)