Skip to content

Commit 770a704

Browse files
authored
Merge pull request #38 from docker/cm/usage
Basic usage tracking & docs inclusions
2 parents bc5a574 + a07a882 commit 770a704

File tree

5 files changed

+86
-4
lines changed

5 files changed

+86
-4
lines changed

docs/content/tools/docs/_index.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ title: Documentation
66

77
* [How to author prompts](prompts)
88
* [Updating Claude Desktop](claude-desktop)
9+
* [Adding to the catalog](adding-to-catalog)
910

1011

docs/content/tools/quickstart.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ weight: 1
77

88
### Install
99

10-
[Configure Docker Desktop](../docs/claude-desktop) to use the `mcp/run` Docker container.
10+
## Quick Start w/ Docker Desktop Extension
11+
12+
1. Install [Docker Labs AI Tools for Devs](https://hub.docker.com/extensions/docker/labs-ai-tools-for-devs)
13+
2. Click on the Claude button to add `mcp_docker` toolbox to your Claude Desktop.
14+
3. Select any prompts you would like to add from the catalog to your toolbox.
15+
16+
or manually [configure claude desktop](../docs/claude-desktop) to use the `mcp/run` Docker container.
1117

1218
### Restart Claude Desktop
1319

1420
Restarting desktop should be a one-time activity. However, Claude
1521
Desktop does not support the `tools/list_changed` notification so we
16-
currently have to restart desktop more less continuously. :)
22+
currently have to restart desktop more less continuously. Fire up those keybinds :)
1723

1824
### Try a prompt
1925

src/extension/ui/src/Usage.tsx

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Anonymous tracking event for registry changes
3+
*/
4+
5+
interface Record {
6+
event: string;
7+
properties: object;
8+
event_timestamp: number;
9+
source: string;
10+
};
11+
12+
export interface RegistryChangedRecord extends Record {
13+
event: 'registry-changed';
14+
properties: {
15+
name: string;
16+
ref: string;
17+
action: 'remove' | 'add';
18+
};
19+
};
20+
21+
export interface ClaudeConfigChangedRecord extends Record {
22+
event: 'claude-config-changed';
23+
properties: {
24+
action: 'add' | 'remove';
25+
};
26+
};
27+
28+
const eventsQueue: Record[] = [];
29+
30+
let processInterval: NodeJS.Timeout;
31+
32+
type Event = (RegistryChangedRecord | ClaudeConfigChangedRecord)['event'];
33+
type Properties = (RegistryChangedRecord | ClaudeConfigChangedRecord)['properties'];
34+
35+
export const trackEvent = (event: Event, properties: Properties) => {
36+
const record: Record = {
37+
event,
38+
properties,
39+
event_timestamp: Date.now(),
40+
source: 'labs-ai-tools-for-devs-dd'
41+
};
42+
43+
eventsQueue.push(record);
44+
45+
if (processInterval) clearInterval(processInterval);
46+
47+
processInterval = setInterval(() => {
48+
processEventsQueue();
49+
}, 1000);
50+
};
51+
52+
const processEventsQueue = () => {
53+
if (eventsQueue.length === 0) return clearInterval(processInterval);
54+
55+
const events = eventsQueue.splice(0, eventsQueue.length);
56+
57+
sendRecords(events);
58+
};
59+
60+
const sendRecords = (records: Record[]) => {
61+
const url = 'https://nd14xwptgj.execute-api.us-east-1.amazonaws.com/stage/v1/track';
62+
const apiKey = '1234567890';
63+
64+
fetch(url, {
65+
method: 'POST',
66+
headers: {
67+
'Content-Type': 'application/json',
68+
'x-api-key': apiKey
69+
},
70+
body: JSON.stringify({ records })
71+
});
72+
};

src/extension/ui/src/components/ClaudeConfigSyncStatus.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { v1 } from "@docker/extension-api-client-types";
22
import { Badge, Button, Dialog, DialogContent, DialogContentText, DialogTitle, Typography } from "@mui/material";
33
import { useEffect, useState } from "react";
44
import { writeFilesToHost } from "../FileWatcher";
5+
import { trackEvent } from "../Usage";
56

67
const DOCKER_MCP_CONFIG = {
78
"command": "docker",
@@ -94,6 +95,7 @@ export const ClaudeConfigSyncStatus = ({ client }: { client: v1.DockerDesktopCli
9495
return <Dialog open={showConfigModal} onClose={() => setShowConfigModal(false)} maxWidth="lg">
9596
<DialogTitle>Current Claude Desktop Config</DialogTitle>
9697
{status.state === 'has docker_mcp' && <Button onClick={async () => {
98+
trackEvent('claude-config-changed', { action: 'remove' })
9799
// Remove docker_mcp from config
98100
if (claudeConfig && claudeConfig.mcpServers) {
99101
const newConfig = { ...claudeConfig }
@@ -104,6 +106,7 @@ export const ClaudeConfigSyncStatus = ({ client }: { client: v1.DockerDesktopCli
104106
}
105107
}}>Remove Docker MCP</Button>}
106108
{status.state === 'missing docker_mcp' && <Button onClick={() => {
109+
trackEvent('claude-config-changed', { action: 'add' })
107110
// Add docker_mcp to config
108111
if (claudeConfig && claudeConfig.mcpServers) {
109112
const newConfig = { ...claudeConfig }

src/extension/ui/src/components/PromptCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { CircularProgress, Stack } from "@mui/material";
22
import Button from '@mui/material/Button';
3-
4-
53
import { Card, CardActions, CardContent, CardMedia, Typography } from "@mui/material";
64
import { Ref } from "../Refs";
75
import { useState } from "react";
6+
import { trackEvent } from "../Usage";
87

98
export interface CatalogItem {
109
description?: string;
@@ -42,6 +41,7 @@ export function CatalogItemCard({ openUrl, item, canRegister, registered, regist
4241
<Button
4342
size="small"
4443
onClick={() => {
44+
trackEvent('registry-changed', { name: item.name, ref: item.ref, action: registered ? 'remove' : 'add' });
4545
setIsRegistering(true)
4646
if (registered) {
4747
unregister(item).then(() => {

0 commit comments

Comments
 (0)