introspect_filters
Discover filter fields and their types for a Gadget model to construct valid filter arguments for queries and counts.
Instructions
Show all available filter fields and their types for a Gadget model. Use this to construct valid filter arguments for query_records and count_records.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model name in singular camelCase, e.g. shopifyOrder, label |
Implementation Reference
- src/tools.ts:295-333 (handler)Handler case for 'introspect_filters' inside handleTool(). Extracts the 'model' arg, resolves the list field to get the filter type name, then runs a GraphQL introspection query (__type) to get inputFields (name, description, type) for that filter type. Returns the filter schema as JSON.
case "introspect_filters": { const { model } = args as { model: string }; const resolved = await resolveListField(model); if (!resolved?.filterArgType) { return { content: [{ type: "text", text: `No filter type found for model "${model}". Use list_models to verify the model name.` }], isError: true, }; } // Extract base type name from e.g. "[ShopifyOrderFilter!]" → "ShopifyOrderFilter" const filterTypeName = resolved.filterArgType.replace(/[\[\]!]/g, ""); const data = await gql(` query IntrospectFilters($name: String!) { __type(name: $name) { name inputFields { name description type { name kind ofType { name kind ofType { name kind } } } } } } `, { name: filterTypeName }); if (!data.__type) { return { content: [{ type: "text", text: `Filter type "${filterTypeName}" not found in schema.` }], isError: true, }; } return { content: [{ type: "text", text: JSON.stringify(data.__type, null, 2) }] }; } - src/tools.ts:527-538 (registration)Tool definition for 'introspect_filters' in the TOOL_DEFINITIONS array. Declares the name, description ('Show all available filter fields and their types for a Gadget model'), inputSchema (required 'model' string in camelCase), and is registered via ListToolsRequestSchema handler in index.ts.
{ name: "introspect_filters", description: "Show all available filter fields and their types for a Gadget model. Use this to construct valid filter arguments for query_records and count_records.", inputSchema: { type: "object", required: ["model"], properties: { model: { type: "string", description: "Model name in singular camelCase, e.g. shopifyOrder, label" }, }, }, }, - src/tools.ts:64-115 (helper)resolveListField() helper used by the introspect_filters handler. Introspects the GraphQL schema to find the query field for a model's connection type and extracts the filter argument type string (e.g., '[ShopifyOrderFilter!]'). This is cached per model for efficiency.
async function resolveListField(model: string): Promise<ResolvedListField | null> { const cached = listFieldCache.get(model); if (cached !== undefined) return cached; if (!queryFieldsCache) { const data = await gql(` query { __schema { queryType { fields { name args { name type { kind name ofType { kind name ofType { kind name ofType { kind name } } } } } type { kind name ofType { kind name ofType { kind name } } } } } } } `); queryFieldsCache = data.__schema.queryType.fields; } const modelType = model.charAt(0).toUpperCase() + model.slice(1); // Find the query field whose return type is <ModelType>Connection const field = queryFieldsCache!.find((f: any) => { let t = f.type; // Unwrap NON_NULL if (t?.kind === "NON_NULL") t = t.ofType; return t?.name === `${modelType}Connection`; }); if (!field) { listFieldCache.set(model, null); return null; } const filterArg = field.args?.find((a: any) => a.name === "filter"); const filterArgType = filterArg ? typeString(filterArg.type) : undefined; const sortArg = field.args?.find((a: any) => a.name === "sort"); const sortArgType = sortArg ? typeString(sortArg.type) : undefined; const result: ResolvedListField = { fieldName: field.name, filterArgType, sortArgType }; listFieldCache.set(model, result); return result; } - src/index.ts:48-53 (registration)MCP server request handlers. ListToolsRequestSchema returns the TOOL_DEFINITIONS array (which includes introspect_filters). CallToolRequestSchema dispatches to handleTool() which routes to the introspect_filters case.
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOL_DEFINITIONS })); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; return handleTool(name, (args ?? {}) as Record<string, any>); });