Aligned naming

This commit is contained in:
lorenzo.neumann 2025-10-27 12:22:49 +01:00
commit 8f28ea791b
4 changed files with 54 additions and 51 deletions

View file

@ -808,7 +808,7 @@ const App = () => {
const callTool = async ( const callTool = async (
name: string, name: string,
params: Record<string, unknown>, params: Record<string, unknown>,
meta?: Record<string, unknown>, metadata?: Record<string, unknown>,
) => { ) => {
lastToolCallOriginTabRef.current = currentTabRef.current; lastToolCallOriginTabRef.current = currentTabRef.current;
@ -824,7 +824,7 @@ const App = () => {
const mergedMeta = { const mergedMeta = {
...metadata, // General metadata first ...metadata, // General metadata first
progressToken: progressTokenRef.current++, progressToken: progressTokenRef.current++,
...(meta ?? {}), // Tool-specific metadata overrides ...(metadata ?? {}), // Tool-specific metadata overrides
}; };
const response = await sendMCPRequest( const response = await sendMCPRequest(
@ -1148,11 +1148,11 @@ const App = () => {
callTool={async ( callTool={async (
name: string, name: string,
params: Record<string, unknown>, params: Record<string, unknown>,
meta?: Record<string, unknown>, metadata?: Record<string, unknown>,
) => { ) => {
clearError("tools"); clearError("tools");
setToolResult(null); setToolResult(null);
await callTool(name, params, meta); await callTool(name, params, metadata);
}} }}
selectedTool={selectedTool} selectedTool={selectedTool}
setSelectedTool={(tool) => { setSelectedTool={(tool) => {

View file

@ -63,7 +63,7 @@ const ToolsTab = ({
callTool: ( callTool: (
name: string, name: string,
params: Record<string, unknown>, params: Record<string, unknown>,
meta?: Record<string, unknown>, metadata?: Record<string, unknown>,
) => Promise<void>; ) => Promise<void>;
selectedTool: Tool | null; selectedTool: Tool | null;
setSelectedTool: (tool: Tool | null) => void; setSelectedTool: (tool: Tool | null) => void;
@ -76,8 +76,8 @@ const ToolsTab = ({
const [params, setParams] = useState<Record<string, unknown>>({}); const [params, setParams] = useState<Record<string, unknown>>({});
const [isToolRunning, setIsToolRunning] = useState(false); const [isToolRunning, setIsToolRunning] = useState(false);
const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = useState(false); const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = useState(false);
const [isMetaExpanded, setIsMetaExpanded] = useState(false); const [isMetadataExpanded, setIsMetadataExpanded] = useState(false);
const [metaEntries, setMetaEntries] = useState< const [metadataEntries, setMetadataEntries] = useState<
{ id: string; key: string; value: string }[] { id: string; key: string; value: string }[]
>([]); >([]);
const [hasValidationErrors, setHasValidationErrors] = useState(false); const [hasValidationErrors, setHasValidationErrors] = useState(false);
@ -400,7 +400,7 @@ const ToolsTab = ({
variant="outline" variant="outline"
className="h-6 px-2" className="h-6 px-2"
onClick={() => onClick={() =>
setMetaEntries((prev) => [ setMetadataEntries((prev) => [
...prev, ...prev,
{ {
id: id:
@ -419,30 +419,30 @@ const ToolsTab = ({
Add Pair Add Pair
</Button> </Button>
</div> </div>
{metaEntries.length === 0 ? ( {metadataEntries.length === 0 ? (
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
No meta pairs. No metadata pairs.
</p> </p>
) : ( ) : (
<div className="space-y-2"> <div className="space-y-2">
{metaEntries.map((entry, index) => ( {metadataEntries.map((entry, index) => (
<div <div
key={entry.id} key={entry.id}
className="flex items-center gap-2 w-full" className="flex items-center gap-2 w-full"
> >
<Label <Label
htmlFor={`meta-key-${entry.id}`} htmlFor={`metadata-key-${entry.id}`}
className="text-xs shrink-0" className="text-xs shrink-0"
> >
Key Key
</Label> </Label>
<Input <Input
id={`meta-key-${entry.id}`} id={`metadata-key-${entry.id}`}
value={entry.key} value={entry.key}
placeholder="e.g. requestId" placeholder="e.g. requestId"
onChange={(e) => { onChange={(e) => {
const value = e.target.value; const value = e.target.value;
setMetaEntries((prev) => setMetadataEntries((prev) =>
prev.map((m, i) => prev.map((m, i) =>
i === index ? { ...m, key: value } : m, i === index ? { ...m, key: value } : m,
), ),
@ -451,18 +451,18 @@ const ToolsTab = ({
className="h-8 flex-1" className="h-8 flex-1"
/> />
<Label <Label
htmlFor={`meta-value-${entry.id}`} htmlFor={`metadata-value-${entry.id}`}
className="text-xs shrink-0" className="text-xs shrink-0"
> >
Value Value
</Label> </Label>
<Input <Input
id={`meta-value-${entry.id}`} id={`metadata-value-${entry.id}`}
value={entry.value} value={entry.value}
placeholder="e.g. 12345" placeholder="e.g. 12345"
onChange={(e) => { onChange={(e) => {
const value = e.target.value; const value = e.target.value;
setMetaEntries((prev) => setMetadataEntries((prev) =>
prev.map((m, i) => prev.map((m, i) =>
i === index ? { ...m, value } : m, i === index ? { ...m, value } : m,
), ),
@ -475,7 +475,7 @@ const ToolsTab = ({
variant="ghost" variant="ghost"
className="h-8 w-8 p-0 ml-auto shrink-0" className="h-8 w-8 p-0 ml-auto shrink-0"
onClick={() => onClick={() =>
setMetaEntries((prev) => setMetadataEntries((prev) =>
prev.filter((_, i) => i !== index), prev.filter((_, i) => i !== index),
) )
} }
@ -533,10 +533,12 @@ const ToolsTab = ({
<Button <Button
size="sm" size="sm"
variant="ghost" variant="ghost"
onClick={() => setIsMetaExpanded(!isMetaExpanded)} onClick={() =>
setIsMetadataExpanded(!isMetadataExpanded)
}
className="h-6 px-2" className="h-6 px-2"
> >
{isMetaExpanded ? ( {isMetadataExpanded ? (
<> <>
<ChevronUp className="h-3 w-3 mr-1" /> <ChevronUp className="h-3 w-3 mr-1" />
Collapse Collapse
@ -551,7 +553,9 @@ const ToolsTab = ({
</div> </div>
<div <div
className={`transition-all ${ className={`transition-all ${
isMetaExpanded ? "" : "max-h-[8rem] overflow-y-auto" isMetadataExpanded
? ""
: "max-h-[8rem] overflow-y-auto"
}`} }`}
> >
<JsonView data={selectedTool._meta} /> <JsonView data={selectedTool._meta} />
@ -565,17 +569,16 @@ const ToolsTab = ({
try { try {
setIsToolRunning(true); setIsToolRunning(true);
const meta = metaEntries.reduce<Record<string, unknown>>( const metadata = metadataEntries.reduce<
(acc, { key, value }) => { Record<string, unknown>
if (key.trim() !== "") acc[key] = value; >((acc, { key, value }) => {
return acc; if (key.trim() !== "") acc[key] = value;
}, return acc;
{}, }, {});
);
await callTool( await callTool(
selectedTool.name, selectedTool.name,
params, params,
Object.keys(meta).length ? meta : undefined, Object.keys(metadata).length ? metadata : undefined,
); );
} finally { } finally {
setIsToolRunning(false); setIsToolRunning(false);

View file

@ -716,10 +716,10 @@ describe("ToolsTab", () => {
}); });
}); });
describe("Meta Display", () => { describe("Metadata Display", () => {
const toolWithMeta = { const toolWithMetadata = {
name: "metaTool", name: "metaTool",
description: "Tool with meta", description: "Tool with metadata",
inputSchema: { inputSchema: {
type: "object" as const, type: "object" as const,
properties: { properties: {
@ -732,10 +732,10 @@ describe("ToolsTab", () => {
}, },
} as unknown as Tool; } as unknown as Tool;
it("should display meta section when tool has _meta", () => { it("should display metadata section when tool has _meta", () => {
renderToolsTab({ renderToolsTab({
tools: [toolWithMeta], tools: [toolWithMetadata],
selectedTool: toolWithMeta, selectedTool: toolWithMetadata,
}); });
expect(screen.getByText("Meta:")).toBeInTheDocument(); expect(screen.getByText("Meta:")).toBeInTheDocument();
@ -744,10 +744,10 @@ describe("ToolsTab", () => {
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
it("should toggle meta schema expansion", () => { it("should toggle metadata schema expansion", () => {
renderToolsTab({ renderToolsTab({
tools: [toolWithMeta], tools: [toolWithMetadata],
selectedTool: toolWithMeta, selectedTool: toolWithMetadata,
}); });
// There might be multiple Expand buttons (Output Schema, Meta). We need the one within Meta section // There might be multiple Expand buttons (Output Schema, Meta). We need the one within Meta section
@ -777,13 +777,13 @@ describe("ToolsTab", () => {
}); });
}); });
describe("Meta submission", () => { describe("Metadata submission", () => {
it("should send meta values when provided", async () => { it("should send metadata values when provided", async () => {
const callToolMock = jest.fn(async () => {}); const callToolMock = jest.fn(async () => {});
renderToolsTab({ selectedTool: mockTools[0], callTool: callToolMock }); renderToolsTab({ selectedTool: mockTools[0], callTool: callToolMock });
// Add a meta key/value pair // Add a metadata key/value pair
const addPairButton = screen.getByRole("button", { name: /add pair/i }); const addPairButton = screen.getByRole("button", { name: /add pair/i });
await act(async () => { await act(async () => {
fireEvent.click(addPairButton); fireEvent.click(addPairButton);
@ -815,19 +815,19 @@ describe("ToolsTab", () => {
}); });
}); });
describe("ToolResults Meta", () => { describe("ToolResults Metadata", () => {
it("should display meta information when present in toolResult", () => { it("should display metadata information when present in toolResult", () => {
const resultWithMeta = { const resultWithMetadata = {
content: [], content: [],
_meta: { info: "details", version: 2 }, _meta: { info: "details", version: 2 },
}; };
renderToolsTab({ renderToolsTab({
selectedTool: mockTools[0], selectedTool: mockTools[0],
toolResult: resultWithMeta, toolResult: resultWithMetadata,
}); });
// Only ToolResults meta should be present since selectedTool has no _meta // Only ToolResults metadata should be present since selectedTool has no _meta
expect(screen.getAllByText("Meta:")).toHaveLength(1); expect(screen.getAllByText("Meta:")).toHaveLength(1);
expect(screen.getByText(/info/i)).toBeInTheDocument(); expect(screen.getByText(/info/i)).toBeInTheDocument();
expect(screen.getByText(/version/i)).toBeInTheDocument(); expect(screen.getByText(/version/i)).toBeInTheDocument();

View file

@ -167,9 +167,9 @@ export function useConnection({
// Add metadata to the request if available, but skip for tool calls // Add metadata to the request if available, but skip for tool calls
// as they handle metadata merging separately // as they handle metadata merging separately
const shouldAddGeneralMeta = const shouldAddGeneralMetadata =
request.method !== "tools/call" && Object.keys(metadata).length > 0; request.method !== "tools/call" && Object.keys(metadata).length > 0;
const requestWithMeta = shouldAddGeneralMeta const requestWithMetadata = shouldAddGeneralMetadata
? { ? {
...request, ...request,
params: { params: {
@ -208,16 +208,16 @@ export function useConnection({
let response; let response;
try { try {
response = await mcpClient.request( response = await mcpClient.request(
requestWithMeta, requestWithMetadata,
schema, schema,
mcpRequestOptions, mcpRequestOptions,
); );
pushHistory(requestWithMeta, response); pushHistory(requestWithMetadata, response);
} catch (error) { } catch (error) {
const errorMessage = const errorMessage =
error instanceof Error ? error.message : String(error); error instanceof Error ? error.message : String(error);
pushHistory(requestWithMeta, { error: errorMessage }); pushHistory(requestWithMetadata, { error: errorMessage });
throw error; throw error;
} }