
# Completions

> Autocomplete prompt arguments and template parameters.

`completion/complete` lets a client suggest values while the user is filling in a prompt argument or a resource-template parameter. You supply a `complete` callback; the method itself is wired for you on both eras.

## Prompt Arguments

Each argument can have its own callback, receiving the partial value typed so far:

```ts
import { defineMcpPrompt } from "h3-mcp";

const deployPrompt = defineMcpPrompt({
  name: "deploy",
  description: "Deploy to an environment",
  args: [
    {
      name: "environment",
      required: true,
      complete: async (value, event) => ({
        values: ["production", "staging", "development"].filter((e) => e.startsWith(value)),
      }),
    },
    {
      name: "region",
      complete: async (value) => ({
        values: ["us-east-1", "eu-west-1", "ap-south-1"].filter((r) => r.startsWith(value)),
        total: 3,
        hasMore: false,
      }),
    },
  ],
  handler: async (args) => ({
    messages: [
      {
        role: "user",
        content: { type: "text", text: `Deploy to ${args.environment} in ${args.region}` },
      },
    ],
  }),
});
```

`values` is required; `total` and `hasMore` are optional and let a client show "3 of 240 matches" instead of a truncated list.

## Resource Template Parameters

A template gets one callback for all of its parameters, so it receives the argument name too:

```ts
import { defineMcpResourceTemplate } from "h3-mcp";

const fileTemplate = defineMcpResourceTemplate({
  name: "project-file",
  uriTemplate: "app://files/{path}",
  description: "Project files",
  complete: async (argName, argValue, event) => {
    if (argName === "path") {
      return { values: await listFiles(argValue) };
    }
    return { values: [] };
  },
  handler: async (uri) => ({
    contents: [{ uri: uri.toString(), text: await readFile(uri.pathname) }],
  }),
});
```

## Capability

The server advertises `completions: {}` as soon as any prompt argument or resource template has a `complete` callback — there is nothing to enable.

> [!TIP]
> Completion callbacks run on every keystroke a client sends. Keep them cheap: filter an in-memory list, or cache the expensive lookup outside the callback.

> [!IMPORTANT]
> `argValue` is untrusted input. Completing against a database or filesystem means an attacker can probe it one prefix at a time — scope the lookup to what that request is allowed to see, and cap the number of values you return.
