> ## 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.

# Quick start

> Create, test, and deploy your first Jelou Function in less than 5 minutes.

<Steps>
  <Step title="Install the CLI">
    ```bash theme={null}
    npm install -g @jelou/cli
    ```

    Verify the installation:

    ```bash theme={null}
    jelou --version
    ```
  </Step>

  <Step title="Authenticate">
    You need a personal access token (create one in the Jelou dashboard).

    ```bash theme={null}
    jelou login
    # Paste your access token: ****
    # ✓ Logged in
    ```

    <Tip>
      In CI you can pass the token directly: `jelou login --token jfn_pat_your_token`
    </Tip>
  </Step>

  <Step title="Initialize a project">
    Create a directory and run `jelou functions init`:

    ```bash theme={null}
    mkdir query-customer && cd query-customer
    jelou functions init
    # ? Function slug: query-customer
    # ? Description: Looks up customer information for the WhatsApp bot
    # ? Create new or link existing? Create new
    # ✓ Created query-customer
    ```

    This generates the base files:

    | File         | Purpose                     |
    | ------------ | --------------------------- |
    | `index.ts`   | Your main function          |
    | `jelou.json` | Project configuration       |
    | `deno.json`  | SDK import map              |
    | `.env`       | Local environment variables |
  </Step>

  <Step title="Write your function">
    Replace the contents of `index.ts` with a function that looks up customers by phone:

    ```typescript index.ts theme={null}
    import { define, z } from "@jelou/functions";

    export default define({
      name: "query-customer",
      description: "Looks up customer information by phone number for the support bot",
      input: z.object({
        phone: z.string().min(10).describe("Customer phone number"),
      }),
      output: z.object({
        name: z.string(),
        email: z.string(),
        plan: z.string(),
        balance: z.number(),
      }),
      handler: async (input, ctx) => {
        ctx.log("Looking up customer", {
          phone: input.phone,
          company: ctx.company.id,
        });

        const apiKey = ctx.env.get("CRM_API_KEY");
        const res = await fetch(
          `https://crm.example.com/api/customers?tel=${input.phone}`,
          { headers: { Authorization: `Bearer ${apiKey}` } },
        );
        const customer = await res.json();

        return {
          name: customer.name,
          email: customer.email,
          plan: customer.plan,
          balance: customer.balance,
        };
      },
    });
    ```
  </Step>

  <Step title="Run locally">
    Start the development server:

    ```bash theme={null}
    jelou functions dev
    # ▸ Listening on http://localhost:3000
    # ▸ Watching for changes...
    ```

    Your server reloads automatically when you edit files.
  </Step>

  <Step title="Test with curl">
    In another terminal, send a request:

    ```bash theme={null}
    curl -X POST http://localhost:3000 \
      -H "Content-Type: application/json" \
      -d '{"phone": "593987654321"}'
    ```

    Response:

    ```json theme={null}
    {
      "name": "Maria Garcia",
      "email": "maria@example.com",
      "plan": "Premium",
      "balance": 150.00
    }
    ```

    <Tip>
      You can also test the MCP endpoint at `http://localhost:3000/mcp` and the health check at `http://localhost:3000/__health`.
    </Tip>
  </Step>

  <Step title="Configure secrets">
    Before deploying, add the environment variables your function needs:

    ```bash theme={null}
    jelou secrets set query-customer CRM_API_KEY=YOUR_CRM_API_KEY
    # ✓ Set 1 secret
    ```
  </Step>

  <Step title="Deploy to production">
    ```bash theme={null}
    jelou functions deploy
    # ▸ Files: index.ts (1.2 KB), jelou.json (98 B), deno.json (65 B)
    # ? Deploy query-customer? (Y/n) y
    # ✓ Deployed to https://query-customer.fn.jelou.ai
    # ⚠ A default runtime token was created for this function.
    #   Save it now — it will not be shown again.
    # ▸ Token    jfn_rt_abc123...
    ```

    <Warning>
      Save the token — it will not be shown again. You need it to call your function in production.
    </Warning>

    Your function is now available in production. Jelou AI agents can invoke it as an MCP tool automatically.
  </Step>

  <Step title="Verify in production">
    ```bash theme={null}
    curl -X POST https://query-customer.fn.jelou.ai \
      -H "Content-Type: application/json" \
      -H "X-Jelou-Token: jfn_rt_abc123..." \
      -d '{"phone": "593987654321"}'
    ```

    Monitor logs in real time:

    ```bash theme={null}
    jelou functions logs query-customer
    ```
  </Step>
</Steps>

## Next steps

* [Input/output validation](/guides/functions/validacion) — Zod schemas, type coercion, and error format
* [Multi-tool functions](/guides/functions/multi-tool) — group multiple tools in a single deployment with `app()`
