Skip to content

Commit 4dbd41d

Browse files
committed
feat: use markdown every time for all json data
1 parent 1ef2be7 commit 4dbd41d

13 files changed

+37
-27
lines changed

src/tools/actor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { ensureOutputWithinCharLimit, getActorDefinitionStorageFieldNames, getAc
2222
import { fetchActorDetails } from '../utils/actor-details.js';
2323
import { buildActorResponseContent } from '../utils/actor-response.js';
2424
import { ajv } from '../utils/ajv.js';
25+
import { jsonSchemaToMarkdown } from '../utils/json-schema-to-markdown.js';
2526
import { buildMCPResponse } from '../utils/mcp.js';
2627
import type { ProgressTracker } from '../utils/progress.js';
2728
import type { JsonSchemaProperty } from '../utils/schema-generation.js';
@@ -388,7 +389,7 @@ The step parameter enforces this workflow - you cannot call an Actor without fir
388389
client = await connectMCPClient(mcpServerUrl, apifyToken);
389390
const toolsResponse = await client.listTools();
390391

391-
const toolsInfo = toolsResponse.tools.map((tool) => `**${tool.name}**\n${tool.description || 'No description'}\nInput Schema: ${JSON.stringify(tool.inputSchema, null, 2)}`,
392+
const toolsInfo = toolsResponse.tools.map((tool) => `**${tool.name}**\n${tool.description || 'No description'}\n\n${jsonSchemaToMarkdown(tool.inputSchema)}`,
392393
).join('\n\n');
393394

394395
return buildMCPResponse([`This is an MCP Server Actor with the following tools:\n\n${toolsInfo}\n\nTo call a tool, use step="call" with actor name format: "${baseActorName}:{toolName}"`]);
@@ -402,7 +403,7 @@ The step parameter enforces this workflow - you cannot call an Actor without fir
402403
return buildMCPResponse([`Actor information for '${baseActorName}' was not found. Please check the Actor ID or name and ensure the Actor exists.`]);
403404
}
404405
const content = [
405-
{ type: 'text', text: `**Input Schema:**\n${JSON.stringify(details.inputSchema, null, 0)}` },
406+
{ type: 'text', text: jsonSchemaToMarkdown(details.inputSchema) },
406407
];
407408
/**
408409
* Add Skyfire instructions also in the info step since clients are most likely truncating the long tool description of the call-actor.
@@ -478,7 +479,7 @@ The step parameter enforces this workflow - you cannot call an Actor without fir
478479
if (errors && errors.length > 0) {
479480
return buildMCPResponse([
480481
`Input validation failed for Actor '${actorName}': ${errors.map((e) => e.message).join(', ')}`,
481-
`Input Schema:\n${JSON.stringify(actor.tool.inputSchema)}`,
482+
jsonSchemaToMarkdown(actor.tool.inputSchema),
482483
]);
483484
}
484485
}

src/tools/build.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
ToolEntry,
1414
} from '../types.js';
1515
import { ajv } from '../utils/ajv.js';
16+
import { jsonSchemaToMarkdown } from '../utils/json-schema-to-markdown.js';
1617
import { filterSchemaProperties, shortenProperties } from './utils.js';
1718

1819
/**
@@ -131,7 +132,7 @@ export const actorDefinitionTool: ToolEntry = {
131132
const properties = filterSchemaProperties(v.input.properties as { [key: string]: ISchemaProperties });
132133
v.input.properties = shortenProperties(properties);
133134
}
134-
return { content: [{ type: 'text', text: JSON.stringify(v) }] };
135+
return { content: [{ type: 'text', text: jsonSchemaToMarkdown(v.input) }] };
135136
},
136137
} as InternalTool,
137138
};

src/tools/dataset.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
88
import { parseCommaSeparatedList } from '../utils/generic.js';
9+
import { jsonSchemaToMarkdown } from '../utils/json-schema-to-markdown.js';
10+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
911
import { generateSchemaFromItems } from '../utils/schema-generation.js';
1012

1113
const getDatasetArgs = z.object({
@@ -61,7 +63,7 @@ export const getDataset: ToolEntry = {
6163
if (!v) {
6264
return { content: [{ type: 'text', text: `Dataset '${parsed.datasetId}' not found.` }] };
6365
}
64-
return { content: [{ type: 'text', text: JSON.stringify(v) }] };
66+
return { content: [{ type: 'text', text: jsonToMarkdown(v) }] };
6567
},
6668
} as InternalTool,
6769
};
@@ -108,7 +110,7 @@ export const getDatasetItems: ToolEntry = {
108110
if (!v) {
109111
return { content: [{ type: 'text', text: `Dataset '${parsed.datasetId}' not found.` }] };
110112
}
111-
return { content: [{ type: 'text', text: JSON.stringify(v) }] };
113+
return { content: [{ type: 'text', text: jsonToMarkdown(v) }] };
112114
},
113115
} as InternalTool,
114116
};
@@ -176,7 +178,7 @@ export const getDatasetSchema: ToolEntry = {
176178
return {
177179
content: [{
178180
type: 'text',
179-
text: JSON.stringify(schema),
181+
text: jsonSchemaToMarkdown(schema),
180182
}],
181183
};
182184
},

src/tools/dataset_collection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApifyClient } from '../apify-client.js';
55
import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
8+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
89

910
const getUserDatasetsListArgs = z.object({
1011
offset: z.number()
@@ -48,7 +49,7 @@ export const getUserDatasetsList: ToolEntry = {
4849
desc: parsed.desc,
4950
unnamed: parsed.unnamed,
5051
});
51-
return { content: [{ type: 'text', text: JSON.stringify(datasets) }] };
52+
return { content: [{ type: 'text', text: jsonToMarkdown(datasets) }] };
5253
},
5354
} as InternalTool,
5455
};

src/tools/fetch-actor-details.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { fetchActorDetails } from '../utils/actor-details.js';
88
import { ajv } from '../utils/ajv.js';
9-
import { inputSchemaToMarkdown } from '../utils/input-schema-to-markdown.js';
9+
import { jsonSchemaToMarkdown } from '../utils/json-schema-to-markdown.js';
1010

1111
const fetchActorDetailsToolArgsSchema = z.object({
1212
actor: z.string()
@@ -43,7 +43,7 @@ export const fetchActorDetailsTool: ToolEntry = {
4343
content: [
4444
{ type: 'text', text: `**Actor card**:\n${details.actorCard}` },
4545
{ type: 'text', text: `**README:**\n${details.readme}` },
46-
{ type: 'text', text: inputSchemaToMarkdown(details.inputSchema) },
46+
{ type: 'text', text: jsonSchemaToMarkdown(details.inputSchema) },
4747
],
4848
};
4949
},

src/tools/get-actor-output.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { HelperTools, SKYFIRE_TOOL_INSTRUCTIONS, TOOL_MAX_OUTPUT_CHARS } from '.
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
88
import { getValuesByDotKeys, parseCommaSeparatedList } from '../utils/generic.js';
9+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
910

1011
/**
1112
* Zod schema for get-actor-output tool arguments
@@ -134,7 +135,7 @@ Note: This tool is automatically included if the Apify MCP Server is configured
134135
.map((item) => cleanEmptyProperties(item))
135136
.filter((item) => item !== undefined);
136137

137-
let outputText = JSON.stringify(cleanedItems);
138+
let outputText = jsonToMarkdown(cleanedItems);
138139
let truncated = false;
139140
if (outputText.length > TOOL_MAX_OUTPUT_CHARS) {
140141
outputText = outputText.slice(0, TOOL_MAX_OUTPUT_CHARS);

src/tools/key_value_store.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApifyClient } from '../apify-client.js';
55
import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
8+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
89

910
const getKeyValueStoreArgs = z.object({
1011
storeId: z.string()
@@ -30,7 +31,7 @@ export const getKeyValueStore: ToolEntry = {
3031
const parsed = getKeyValueStoreArgs.parse(args);
3132
const client = new ApifyClient({ token: apifyToken });
3233
const store = await client.keyValueStore(parsed.storeId).get();
33-
return { content: [{ type: 'text', text: JSON.stringify(store) }] };
34+
return { content: [{ type: 'text', text: jsonToMarkdown(store) }] };
3435
},
3536
} as InternalTool,
3637
};
@@ -70,7 +71,7 @@ export const getKeyValueStoreKeys: ToolEntry = {
7071
exclusiveStartKey: parsed.exclusiveStartKey,
7172
limit: parsed.limit,
7273
});
73-
return { content: [{ type: 'text', text: JSON.stringify(keys) }] };
74+
return { content: [{ type: 'text', text: jsonToMarkdown(keys) }] };
7475
},
7576
} as InternalTool,
7677
};
@@ -104,7 +105,7 @@ export const getKeyValueStoreRecord: ToolEntry = {
104105
const parsed = getKeyValueStoreRecordArgs.parse(args);
105106
const client = new ApifyClient({ token: apifyToken });
106107
const record = await client.keyValueStore(parsed.storeId).getRecord(parsed.recordKey);
107-
return { content: [{ type: 'text', text: JSON.stringify(record) }] };
108+
return { content: [{ type: 'text', text: jsonToMarkdown(record) }] };
108109
},
109110
} as InternalTool,
110111
};

src/tools/key_value_store_collection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApifyClient } from '../apify-client.js';
55
import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
8+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
89

910
const getUserKeyValueStoresListArgs = z.object({
1011
offset: z.number()
@@ -48,7 +49,7 @@ export const getUserKeyValueStoresList: ToolEntry = {
4849
desc: parsed.desc,
4950
unnamed: parsed.unnamed,
5051
});
51-
return { content: [{ type: 'text', text: JSON.stringify(stores) }] };
52+
return { content: [{ type: 'text', text: jsonToMarkdown(stores) }] };
5253
},
5354
} as InternalTool,
5455
};

src/tools/run.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApifyClient } from '../apify-client.js';
55
import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
8+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
89

910
const getActorRunArgs = z.object({
1011
runId: z.string()
@@ -40,7 +41,7 @@ export const getActorRun: ToolEntry = {
4041
if (!v) {
4142
return { content: [{ type: 'text', text: `Run with ID '${parsed.runId}' not found.` }] };
4243
}
43-
return { content: [{ type: 'text', text: JSON.stringify(v) }] };
44+
return { content: [{ type: 'text', text: jsonToMarkdown(v) }] };
4445
},
4546
} as InternalTool,
4647
};
@@ -96,7 +97,7 @@ export const abortActorRun: ToolEntry = {
9697
const parsed = abortRunArgs.parse(args);
9798
const client = new ApifyClient({ token: apifyToken });
9899
const v = await client.run(parsed.runId).abort({ gracefully: parsed.gracefully });
99-
return { content: [{ type: 'text', text: JSON.stringify(v) }] };
100+
return { content: [{ type: 'text', text: jsonToMarkdown(v) }] };
100101
},
101102
} as InternalTool,
102103
};

src/tools/run_collection.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApifyClient } from '../apify-client.js';
55
import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
8+
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
89

910
const getUserRunsListArgs = z.object({
1011
offset: z.number()
@@ -40,7 +41,7 @@ export const getUserRunsList: ToolEntry = {
4041
const parsed = getUserRunsListArgs.parse(args);
4142
const client = new ApifyClient({ token: apifyToken });
4243
const runs = await client.runs().list({ limit: parsed.limit, offset: parsed.offset, desc: parsed.desc, status: parsed.status });
43-
return { content: [{ type: 'text', text: JSON.stringify(runs) }] };
44+
return { content: [{ type: 'text', text: jsonToMarkdown(runs) }] };
4445
},
4546
} as InternalTool,
4647
};

0 commit comments

Comments
 (0)