Documentation Index
Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
Use this file to discover all available pages before exploring further.
You expose a function as an MCP tool for AI agents to invoke. With .describe() you tell the agent what each parameter does.
Pattern: clear name + description + .describe() on each field + MCP active (default).
import { define, z } from "@jelou/functions";
export default define({
name: "search-products",
description: "Searches the product catalog by name, category, or price range",
input: z.object({
query: z.string().min(1).describe("Search term: product name or keywords"),
category: z.string().optional().describe("Filter by category: electronics, clothing, home, food"),
minPrice: z.number().optional().describe("Minimum price in USD"),
maxPrice: z.number().optional().describe("Maximum price in USD"),
limit: z.number().default(5).describe("Maximum number of results (1-20)"),
}),
output: z.object({
results: z.array(z.object({
id: z.string(),
name: z.string(),
price: z.number(),
category: z.string(),
inStock: z.boolean(),
})),
total: z.number(),
}),
handler: async (input, ctx) => {
ctx.log("Product search", {
query: input.query,
category: input.category,
company: ctx.company.id,
});
const apiKey = ctx.env.get("CATALOG_API_KEY");
const params = new URLSearchParams({ q: input.query });
if (input.category) params.set("category", input.category);
if (input.minPrice) params.set("min_price", String(input.minPrice));
if (input.maxPrice) params.set("max_price", String(input.maxPrice));
params.set("limit", String(input.limit));
const res = await fetch(
`https://catalog.example.com/api/search?${params}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
const data = await res.json();
return {
results: data.items.map((item: any) => ({
id: item.id,
name: item.name,
price: item.price,
category: item.category,
inStock: item.stock > 0,
})),
total: data.total,
};
},
});
Local testing
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{"query": "laptop", "category": "electronics", "maxPrice": 1500}'
Why it works this way
name and description are what the AI agent sees to decide when to use this tool.
.describe() on each field generates the parameter descriptions in the MCP schema.
- The
output schema documents what structure the function returns.
- MCP is active by default (
config.mcp: true), so the /mcp endpoint automatically exposes the tool.
- An AI agent can call this function when a user asks “do you have laptops under $1500?”.