Skip to content

Commit 842aa3c

Browse files
committed
Added general meta data section to add pairs for all requests
1 parent 78c56b3 commit 842aa3c

File tree

8 files changed

+835
-25
lines changed

8 files changed

+835
-25
lines changed

cli/src/client/prompts.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ type JsonValue =
1212
| { [key: string]: JsonValue };
1313

1414
// List available prompts
15-
export async function listPrompts(client: Client): Promise<McpResponse> {
15+
export async function listPrompts(
16+
client: Client,
17+
metaData?: Record<string, string>,
18+
): Promise<McpResponse> {
1619
try {
17-
const response = await client.listPrompts();
20+
const params =
21+
metaData && Object.keys(metaData).length > 0 ? { _meta: metaData } : {};
22+
const response = await client.listPrompts(params);
1823
return response;
1924
} catch (error) {
2025
throw new Error(
@@ -28,6 +33,7 @@ export async function getPrompt(
2833
client: Client,
2934
name: string,
3035
args?: Record<string, JsonValue>,
36+
metaData?: Record<string, string>,
3137
): Promise<McpResponse> {
3238
try {
3339
// Convert all arguments to strings for prompt arguments
@@ -44,10 +50,16 @@ export async function getPrompt(
4450
}
4551
}
4652

47-
const response = await client.getPrompt({
53+
const params: any = {
4854
name,
4955
arguments: stringArgs,
50-
});
56+
};
57+
58+
if (metaData && Object.keys(metaData).length > 0) {
59+
params._meta = metaData;
60+
}
61+
62+
const response = await client.getPrompt(params);
5163

5264
return response;
5365
} catch (error) {

cli/src/client/resources.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
22
import { McpResponse } from "./types.js";
33

44
// List available resources
5-
export async function listResources(client: Client): Promise<McpResponse> {
5+
export async function listResources(
6+
client: Client,
7+
metaData?: Record<string, string>,
8+
): Promise<McpResponse> {
69
try {
7-
const response = await client.listResources();
10+
const params =
11+
metaData && Object.keys(metaData).length > 0 ? { _meta: metaData } : {};
12+
const response = await client.listResources(params);
813
return response;
914
} catch (error) {
1015
throw new Error(
@@ -17,9 +22,14 @@ export async function listResources(client: Client): Promise<McpResponse> {
1722
export async function readResource(
1823
client: Client,
1924
uri: string,
25+
metaData?: Record<string, string>,
2026
): Promise<McpResponse> {
2127
try {
22-
const response = await client.readResource({ uri });
28+
const params: any = { uri };
29+
if (metaData && Object.keys(metaData).length > 0) {
30+
params._meta = metaData;
31+
}
32+
const response = await client.readResource(params);
2333
return response;
2434
} catch (error) {
2535
throw new Error(
@@ -31,9 +41,12 @@ export async function readResource(
3141
// List resource templates
3242
export async function listResourceTemplates(
3343
client: Client,
44+
metaData?: Record<string, string>,
3445
): Promise<McpResponse> {
3546
try {
36-
const response = await client.listResourceTemplates();
47+
const params =
48+
metaData && Object.keys(metaData).length > 0 ? { _meta: metaData } : {};
49+
const response = await client.listResourceTemplates(params);
3750
return response;
3851
} catch (error) {
3952
throw new Error(

cli/src/client/tools.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ type JsonSchemaType = {
1919
items?: JsonSchemaType;
2020
};
2121

22-
export async function listTools(client: Client): Promise<McpResponse> {
22+
export async function listTools(
23+
client: Client,
24+
metaData?: Record<string, string>,
25+
): Promise<McpResponse> {
2326
try {
24-
const response = await client.listTools();
27+
const params =
28+
metaData && Object.keys(metaData).length > 0 ? { _meta: metaData } : {};
29+
const response = await client.listTools(params);
2530
return response;
2631
} catch (error) {
2732
throw new Error(
@@ -82,9 +87,11 @@ export async function callTool(
8287
client: Client,
8388
name: string,
8489
args: Record<string, JsonValue>,
90+
generalMetaData?: Record<string, string>,
91+
toolSpecificMetaData?: Record<string, string>,
8592
): Promise<McpResponse> {
8693
try {
87-
const toolsResponse = await listTools(client);
94+
const toolsResponse = await listTools(client, generalMetaData);
8895
const tools = toolsResponse.tools as Tool[];
8996
const tool = tools.find((t) => t.name === name);
9097

@@ -106,9 +113,23 @@ export async function callTool(
106113
}
107114
}
108115

116+
// Merge general metadata with tool-specific metadata
117+
// Tool-specific metadata takes precedence over general metadata
118+
let mergedMeta: Record<string, string> | undefined;
119+
if (generalMetaData || toolSpecificMetaData) {
120+
mergedMeta = {
121+
...(generalMetaData || {}),
122+
...(toolSpecificMetaData || {}),
123+
};
124+
}
125+
109126
const response = await client.callTool({
110127
name: name,
111128
arguments: convertedArgs,
129+
_meta:
130+
mergedMeta && Object.keys(mergedMeta).length > 0
131+
? mergedMeta
132+
: undefined,
112133
});
113134
return response;
114135
} catch (error) {

cli/src/index.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ type Args = {
4242
logLevel?: LogLevel;
4343
toolName?: string;
4444
toolArg?: Record<string, JsonValue>;
45+
toolMeta?: Record<string, string>;
4546
transport?: "sse" | "stdio" | "http";
4647
headers?: Record<string, string>;
48+
metaData?: Record<string, string>;
4749
};
4850

4951
function createTransportOptions(
@@ -121,41 +123,52 @@ async function callMethod(args: Args): Promise<void> {
121123

122124
// Tools methods
123125
if (args.method === "tools/list") {
124-
result = await listTools(client);
126+
result = await listTools(client, args.metaData);
125127
} else if (args.method === "tools/call") {
126128
if (!args.toolName) {
127129
throw new Error(
128130
"Tool name is required for tools/call method. Use --tool-name to specify the tool name.",
129131
);
130132
}
131133

132-
result = await callTool(client, args.toolName, args.toolArg || {});
134+
result = await callTool(
135+
client,
136+
args.toolName,
137+
args.toolArg || {},
138+
args.metaData,
139+
args.toolMeta,
140+
);
133141
}
134142
// Resources methods
135143
else if (args.method === "resources/list") {
136-
result = await listResources(client);
144+
result = await listResources(client, args.metaData);
137145
} else if (args.method === "resources/read") {
138146
if (!args.uri) {
139147
throw new Error(
140148
"URI is required for resources/read method. Use --uri to specify the resource URI.",
141149
);
142150
}
143151

144-
result = await readResource(client, args.uri);
152+
result = await readResource(client, args.uri, args.metaData);
145153
} else if (args.method === "resources/templates/list") {
146-
result = await listResourceTemplates(client);
154+
result = await listResourceTemplates(client, args.metaData);
147155
}
148156
// Prompts methods
149157
else if (args.method === "prompts/list") {
150-
result = await listPrompts(client);
158+
result = await listPrompts(client, args.metaData);
151159
} else if (args.method === "prompts/get") {
152160
if (!args.promptName) {
153161
throw new Error(
154162
"Prompt name is required for prompts/get method. Use --prompt-name to specify the prompt name.",
155163
);
156164
}
157165

158-
result = await getPrompt(client, args.promptName, args.promptArgs || {});
166+
result = await getPrompt(
167+
client,
168+
args.promptName,
169+
args.promptArgs || {},
170+
args.metaData,
171+
);
159172
}
160173
// Logging methods
161174
else if (args.method === "logging/setLevel") {
@@ -327,6 +340,8 @@ function parseArgs(): Args {
327340

328341
const options = program.opts() as Omit<Args, "target"> & {
329342
header?: Record<string, string>;
343+
meta?: Record<string, JsonValue>;
344+
toolMeta?: Record<string, JsonValue>;
330345
};
331346

332347
let remainingArgs = program.args;
@@ -344,6 +359,22 @@ function parseArgs(): Args {
344359
target: finalArgs,
345360
...options,
346361
headers: options.header, // commander.js uses 'header' field, map to 'headers'
362+
metaData: options.meta
363+
? Object.fromEntries(
364+
Object.entries(options.meta).map(([key, value]) => [
365+
key,
366+
String(value),
367+
]),
368+
)
369+
: undefined,
370+
toolMeta: options.toolMeta
371+
? Object.fromEntries(
372+
Object.entries(options.toolMeta).map(([key, value]) => [
373+
key,
374+
String(value),
375+
]),
376+
)
377+
: undefined,
347378
};
348379
}
349380

client/src/App.tsx

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {
4747
Hash,
4848
Key,
4949
MessageSquare,
50+
Settings,
5051
} from "lucide-react";
5152

5253
import { z } from "zod";
@@ -80,6 +81,7 @@ import {
8081
CustomHeaders,
8182
migrateFromLegacyAuth,
8283
} from "./lib/types/customHeaders";
84+
import MetaDataTab from "./components/MetaDataTab";
8385

8486
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
8587

@@ -195,9 +197,27 @@ const App = () => {
195197
const [authState, setAuthState] =
196198
useState<AuthDebuggerState>(EMPTY_DEBUGGER_STATE);
197199

200+
// Meta data state - persisted in localStorage
201+
const [metaData, setMetaData] = useState<Record<string, string>>(() => {
202+
const savedMetaData = localStorage.getItem("lastMetaData");
203+
if (savedMetaData) {
204+
try {
205+
return JSON.parse(savedMetaData);
206+
} catch (error) {
207+
console.warn("Failed to parse saved meta data:", error);
208+
}
209+
}
210+
return {};
211+
});
212+
198213
const updateAuthState = (updates: Partial<AuthDebuggerState>) => {
199214
setAuthState((prev) => ({ ...prev, ...updates }));
200215
};
216+
217+
const handleMetaDataChange = (newMetaData: Record<string, string>) => {
218+
setMetaData(newMetaData);
219+
localStorage.setItem("lastMetaData", JSON.stringify(newMetaData));
220+
};
201221
const nextRequestId = useRef(0);
202222
const rootsRef = useRef<Root[]>([]);
203223

@@ -299,6 +319,7 @@ const App = () => {
299319
},
300320
getRoots: () => rootsRef.current,
301321
defaultLoggingLevel: logLevel,
322+
metaData,
302323
});
303324

304325
useEffect(() => {
@@ -789,16 +810,21 @@ const App = () => {
789810
? cleanParams(params, tool.inputSchema as JsonSchemaType)
790811
: params;
791812

813+
// Merge general metadata with tool-specific metadata
814+
// Tool-specific metadata takes precedence over general metadata
815+
const mergedMeta = {
816+
...metaData, // General metadata first
817+
progressToken: progressTokenRef.current++,
818+
...(meta ?? {}), // Tool-specific metadata overrides
819+
};
820+
792821
const response = await sendMCPRequest(
793822
{
794823
method: "tools/call" as const,
795824
params: {
796825
name,
797826
arguments: cleanedParams,
798-
_meta: {
799-
progressToken: progressTokenRef.current++,
800-
...(meta ?? {}),
801-
},
827+
_meta: mergedMeta,
802828
},
803829
},
804830
CompatibilityCallToolResultSchema,
@@ -994,6 +1020,10 @@ const App = () => {
9941020
<Key className="w-4 h-4 mr-2" />
9951021
Auth
9961022
</TabsTrigger>
1023+
<TabsTrigger value="metadata">
1024+
<Settings className="w-4 h-4 mr-2" />
1025+
Meta Data
1026+
</TabsTrigger>
9971027
</TabsList>
9981028

9991029
<div className="w-full">
@@ -1154,6 +1184,10 @@ const App = () => {
11541184
onRootsChange={handleRootsChange}
11551185
/>
11561186
<AuthDebuggerWrapper />
1187+
<MetaDataTab
1188+
metaData={metaData}
1189+
onMetaDataChange={handleMetaDataChange}
1190+
/>
11571191
</>
11581192
)}
11591193
</div>

0 commit comments

Comments
 (0)