Skip to main content
Glama
componentMapper.ts5.19 kB
import { V1Component } from "@pipedream/sdk" import { z, ZodRawShape } from "zod" import { CONFIGURE_COMPONENT_TOOL_NAME } from "./const" import { ConfigurableProp } from "@pipedream/sdk" import { ASYNC_OPTIONS_TOOL_NAME } from "./tools/async-options-tool" export const componentMapper = ( component: V1Component, asyncOptions?: boolean, configurableProps?: any[] ) => { const schema: ZodRawShape = {} let configurablePropsDescription = "" let appKey: string | undefined = undefined for (const cp of configurableProps || (component.configurable_props as ConfigurableProp[])) { if (cp.hidden) { continue } if (cp.type === "app") { // XXX handled directly in implementation // TODO: Handle multiple apps appKey = cp.name continue } else if (cp.type === "string") { if (cp.options && Array.isArray(cp.options) && cp.options.length > 0) { if (cp.options.some((o) => typeof o === "string")) { schema[cp.name] = z.enum(cp.options) } else if (cp.options.some((o) => typeof o === "object")) { schema[cp.name] = z.enum(cp.options.map((o) => o.value)) } else { schema[cp.name] = z.string() } } else { schema[cp.name] = z.string() } } else if (cp.type === "string[]") { if (cp.options && Array.isArray(cp.options) && cp.options.length > 0) { if (cp.options.some((o) => typeof o === "string")) { schema[cp.name] = z.array(z.enum(cp.options)) } else if (cp.options.some((o) => typeof o === "object")) { schema[cp.name] = z.array(z.enum(cp.options.map((o) => o.value))) } else { schema[cp.name] = z.array(z.string()) } } else { schema[cp.name] = z.array(z.string()) } // XXX maybe get rid of this, since the schema should communicate this correctly? configurablePropsDescription += `- ${cp.name}: Return JSON in this format: string[]\n` } else if (cp.type === "$.discord.channel") { schema[cp.name] = z.string() configurablePropsDescription += `- ${cp.name}: This property is a channel ID, not the channel name. You can get a list of name/id using the CONFIGURE_COMPONENT tool.\n` } else if (cp.type === "$.discord.channel[]") { schema[cp.name] = z.array(z.string()) configurablePropsDescription += `- ${cp.name}: This property is a channel ID, not the channel name. You can get a list of name/id using the CONFIGURE_COMPONENT tool.\n` } else if (cp.type === "object") { schema[cp.name] = z.object({}).passthrough() } else if (cp.type === "any") { schema[cp.name] = z.any() } else if (cp.type === "number") { schema[cp.name] = z.number() } else if (cp.type === "number[]") { schema[cp.name] = z.array(z.number()) } else if (cp.type === "integer") { schema[cp.name] = z.number().int() } else if (cp.type === "integer[]") { schema[cp.name] = z.array(z.number().int()) } else if (cp.type === "boolean") { schema[cp.name] = z.boolean() } else if (cp.type === "boolean[]") { schema[cp.name] = z.array(z.boolean()) } else if (cp.type === "$.interface.http") { // not yet supported } else if (cp.type === "$.interface.timer") { // not yet supported } else if (cp.type === "$.service.db") { // not yet supported } else if (cp.type === "datastore") { // not yet supported } else if (cp.type === "http_request") { // not yet supported } else if (cp.type === "sql") { // not yet supported } else if (cp.type === "alert") { // ignore alerts, as no user input required } else { console.error("unhandled type. Skipping", cp.name, cp.type) } if (schema[cp.name]) { if (cp.optional) { schema[cp.name] = schema[cp.name].optional().nullable() } let description: string = cp.description || "" if (cp.hidden) { description += `\n\nIMPORTANT: This property is hidden. Do not configure it and leave it blank.\n` } if (cp.remoteOptions) { if (asyncOptions) { description += `\n\nAlways use ${ASYNC_OPTIONS_TOOL_NAME}_${component.key.toUpperCase()}_${cp.name.toUpperCase()} to fetch the valid values` } else { description += `\n\nYou can use the "${CONFIGURE_COMPONENT_TOOL_NAME}" tool using these parameters to get the values. key: ${component.key}, propName: ${cp.name}` } if (cp.name.includes("id")) { description += `\n\nIMPORTANT: An ID is required for this property. If you don't have the id and only have the name, use the "${CONFIGURE_COMPONENT_TOOL_NAME}" tool to get the values.` } } if (description.trim()) { schema[cp.name] = schema[cp.name].describe(description.trim()) } } } const description = ` ${component.description ?? "No description available"} ${configurablePropsDescription ? "\n\n\n\nIMPORTANT: The arguments have specific formats. Please follow the instructions below:\n" + configurablePropsDescription : ""} `.trim() return { description, schema, appKey, } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rajnandan1/pd-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server