> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mka1.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Usar ferramentas MCP

> Conecte um servidor MCP ao recurso de Respostas da API MKA1, limite as ferramentas permitidas e, opcionalmente, exija aprovação do usuário final.

Use ferramentas MCP quando quiser que a API MKA1 chame ferramentas de um servidor MCP externo durante uma resposta.
Defina o servidor MCP em `tools`.
Limite quais ferramentas o modelo pode chamar com `allowed_tools`.
Use `require_approval` quando quiser que seu aplicativo pause e peça ao usuário final antes de executar a ferramenta.

Use `X-On-Behalf-Of` para o usuário final da API MKA1.
Passe as credenciais do servidor MCP upstream na definição da ferramenta MCP.

## Chamar uma ferramenta MCP diretamente

Defina `require_approval` como `'never'` quando a ferramenta puder ser executada imediatamente.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm responses create --body '{
    "model": "meetkai:functionary-pt",
    "instructions": "Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.",
    "input": "Liste meu problema mais recente do Linear atribuído a mim.",
    "store": true,
    "stream": false,
    "tools": [
      {
        "type": "mcp",
        "server_label": "Linear MCP",
        "server_description": "Acesse problemas do Linear através do MCP.",
        "server_url": "https://mcp.linear.app/mcp",
        "allowed_tools": ["issues.list"],
        "headers": {
          "Authorization": "Bearer <linear-api-key>"
        },
        "require_approval": "never"
      }
    ]
  }' \
    -H 'X-On-Behalf-Of: <end-user-id>'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1';
  import type * as components from '@meetkai/mka1/models/components';

  const mka1 = new SDK({
    bearerAuth: `Bearer ${YOUR_API_KEY}`,
  });

  const response = await mka1.llm.responses.create(
    {
      model: 'meetkai:functionary-pt',
      instructions:
        'Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.',
      input: 'Liste meu problema mais recente do Linear atribuído a mim.',
      store: true,
      stream: false,
      tools: [
        {
          type: 'mcp',
          serverLabel: 'Linear MCP',
          serverDescription: 'Acesse problemas do Linear através do MCP.',
          serverUrl: 'https://mcp.linear.app/mcp',
          allowedTools: ['issues.list'],
          headers: {
            Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
          },
          requireApproval: 'never',
        },
      ],
    },
    { headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
  );

  // Chamadas de ferramentas MCP aparecem como itens function_call na saída
  const mcpCalls = response.output.filter(
    (item): item is components.MCPToolCall => item.type === 'mcp_call',
  );

  const assistantText = response.output
    .filter(
      (item): item is components.OutputMessage =>
        item.type === 'message' && item.role === 'assistant',
    )
    .flatMap(item =>
      item.content.flatMap(content =>
        content.type === 'output_text' ? [content.text] : [],
      ),
    )
    .join('\n\n')
    .trim();

  console.log(assistantText);
  ```

  ```ts OpenAI SDK theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: '<mka1-api-key>',
    baseURL: 'https://apigw.mka1.com/api/v1/llm/',
    defaultHeaders: { 'X-On-Behalf-Of': '<end-user-id>' },
  });

  const response = await openai.responses.create({
    model: 'meetkai:functionary-pt',
    instructions:
      'Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.',
    input: 'Liste meu problema mais recente do Linear atribuído a mim.',
    store: true,
    stream: false,
    tools: [
      {
        type: 'mcp',
        server_label: 'Linear MCP',
        server_description: 'Acesse problemas do Linear através do MCP.',
        server_url: 'https://mcp.linear.app/mcp',
        allowed_tools: ['issues.list'],
        headers: {
          Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
        },
        require_approval: 'never',
      },
    ],
  });

  // Chamadas de ferramentas MCP aparecem como itens function_call na saída
  const functionCall = response.output.find((item) => item.type === 'function_call');
  const message = response.output.find((item) => item.type === 'message');
  console.log(response.output_text);
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(
      bearerAuth: "Bearer <mka1-api-key>",
      serverUrl: "https://apigw.mka1.com"
  );

  var response = await sdk.Llm.Responses.CreateAsync(
      new ResponsesCreateRequest()
      {
          Model = "meetkai:functionary-pt",
          Input = ResponsesCreateRequestInput.CreateStr(
              "Liste meu problema mais recente do Linear atribuído a mim."
          ),
      }
  );

  // Ferramentas MCP requerem um endpoint de servidor MCP em execução.
  // O SDK constrói o mesmo formato de requisição dos exemplos em TypeScript e curl.
  Console.WriteLine(response);
  ```

  ```python Python SDK theme={null}
  from mka1 import SDK
  import os

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  response = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      instructions="Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.",
      input="Liste meu problema mais recente do Linear atribuído a mim.",
      store=True,
      stream=False,
      tools=[
          {
              "type": "mcp",
              "server_label": "Linear MCP",
              "server_description": "Acesse problemas do Linear através do MCP.",
              "server_url": "https://mcp.linear.app/mcp",
              "allowed_tools": ["issues.list"],
              "headers": {
                  "Authorization": f"Bearer {os.environ['LINEAR_API_KEY']}",
              },
              "require_approval": "never",
          },
      ],
  )

  print(response.output_text)
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>' \
    --data '{
      "model": "meetkai:functionary-pt",
      "instructions": "Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.",
      "input": "Liste meu problema mais recente do Linear atribuído a mim.",
      "store": true,
      "stream": false,
      "tools": [
        {
          "type": "mcp",
          "server_label": "Linear MCP",
          "server_description": "Acesse problemas do Linear através do MCP.",
          "server_url": "https://mcp.linear.app/mcp",
          "allowed_tools": ["issues.list"],
          "headers": {
            "Authorization": "Bearer <linear-api-key>"
          },
          "require_approval": "never"
        }
      ]
    }'
  ```
</CodeGroup>

Esse é o fluxo mais simples.
O modelo chama a ferramenta MCP permitida e retorna a mensagem final do assistente em uma única requisição.

O array `output` da resposta contém:

1. `function_call` — a chamada do modelo para a ferramenta descoberta pelo MCP
2. `function_call_output` — os dados retornados pelo servidor MCP
3. `message` — a resposta em texto do modelo resumindo os resultados

## Exigir aprovação do usuário final

Defina `require_approval` como `'always'` quando seu aplicativo deve parar e aguardar uma decisão de aprovação.
Neste fluxo, crie a resposta em modo background, faça polling e procure um item `mcp_approval_request` em `output`.

<CodeGroup>
  ```bash CLI theme={null}
  # Passo 1: Crie uma resposta em background exigindo aprovação
  mka1 llm responses create --body '{
    "model": "meetkai:functionary-pt",
    "instructions": "Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP.",
    "input": "Liste meu problema mais recente do Linear atribuído a mim.",
    "background": true,
    "store": true,
    "stream": false,
    "tools": [
      {
        "type": "mcp",
        "server_label": "Linear MCP",
        "server_url": "https://mcp.linear.app/mcp",
        "allowed_tools": ["issues.list"],
        "headers": { "Authorization": "Bearer <linear-api-key>" },
        "require_approval": "always"
      }
    ]
  }'

  # Passo 2: Faça polling da resposta pelo id até aparecer um mcp_approval_request
  mka1 llm responses get --response-id <response-id>

  # Passo 3: Envie a aprovação para continuar
  mka1 llm responses create --body '{
    "model": "meetkai:functionary-pt",
    "previous_response_id": "<response-id>",
    "input": [
      {
        "type": "mcp_approval_response",
        "approval_request_id": "<approval-request-id>",
        "approve": true
      }
    ],
    "store": true,
    "stream": false
  }'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1';
  import type * as components from '@meetkai/mka1/models/components';

  const mka1 = new SDK({
    bearerAuth: `Bearer ${YOUR_API_KEY}`,
  });

  // Passo 1: Crie uma resposta em background exigindo aprovação
  let pendingResponse = await mka1.llm.responses.create(
    {
      model: 'meetkai:functionary-pt',
      instructions:
        'Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.',
      input: 'Liste meu problema mais recente do Linear atribuído a mim.',
      background: true,
      store: true,
      stream: false,
      tools: [
        {
          type: 'mcp',
          serverLabel: 'Linear MCP',
          serverDescription: 'Acesse problemas do Linear através do MCP.',
          serverUrl: 'https://mcp.linear.app/mcp',
          allowedTools: ['issues.list'],
          headers: {
            Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
          },
          requireApproval: 'always',
        },
      ],
    },
    { headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
  );

  // Passo 2: Faça polling até aparecer uma solicitação de aprovação
  let approvalRequest: components.MCPApprovalRequest | undefined;

  while (
    pendingResponse.status === 'queued' ||
    pendingResponse.status === 'in_progress'
  ) {
    approvalRequest = pendingResponse.output.find(
      (item): item is components.MCPApprovalRequest =>
        item.type === 'mcp_approval_request',
    );

    if (approvalRequest) break;

    await new Promise(resolve => setTimeout(resolve, 1000));

    pendingResponse = await mka1.llm.responses.get(
      { responseId: pendingResponse.id },
      { headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
    );
  }

  if (!approvalRequest) {
    throw new Error(`Nenhuma solicitação de aprovação encontrada. Resposta finalizou com ${pendingResponse.status}.`);
  }

  // Passo 3: Mostre ao usuário o que o modelo deseja fazer
  console.log('Servidor:', approvalRequest.serverLabel);
  console.log('Ferramenta:', approvalRequest.name);
  console.log('Argumentos:', approvalRequest.arguments);

  // Passo 4: Envie a aprovação (ou negação) para continuar
  const approve = true; // Substitua pela decisão da sua UI

  const continuedResponse = await mka1.llm.responses.create(
    {
      model: 'meetkai:functionary-pt',
      previousResponseId: pendingResponse.id,
      input: [
        {
          type: 'mcp_approval_response',
          approvalRequestId: approvalRequest.id,
          approve,
        },
      ],
      store: true,
      stream: false,
    },
    { headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
  );

  const assistantText = continuedResponse.output
    .filter(
      (item): item is components.OutputMessage =>
        item.type === 'message' && item.role === 'assistant',
    )
    .flatMap(item =>
      item.content.flatMap(content =>
        content.type === 'output_text' ? [content.text] : [],
      ),
    )
    .join('\n\n')
    .trim();

  console.log(assistantText);
  ```

  ```ts OpenAI SDK theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: '<mka1-api-key>',
    baseURL: 'https://apigw.mka1.com/api/v1/llm/',
    defaultHeaders: { 'X-On-Behalf-Of': '<end-user-id>' },
  });

  // Passo 1: Crie uma resposta em background exigindo aprovação
  let pendingResponse = await openai.responses.create({
    model: 'meetkai:functionary-pt',
    instructions:
      'Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.',
    input: 'Liste meu problema mais recente do Linear atribuído a mim.',
    background: true,
    store: true,
    stream: false,
    tools: [
      {
        type: 'mcp',
        server_label: 'Linear MCP',
        server_description: 'Acesse problemas do Linear através do MCP.',
        server_url: 'https://mcp.linear.app/mcp',
        allowed_tools: ['issues.list'],
        headers: {
          Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
        },
        require_approval: 'always',
      },
    ],
  });

  // Passo 2: Faça polling até aparecer uma solicitação de aprovação
  let approvalRequest;

  while (
    pendingResponse.status === 'queued' ||
    pendingResponse.status === 'in_progress'
  ) {
    approvalRequest = pendingResponse.output.find(
      (item) => item.type === 'mcp_approval_request',
    );

    if (approvalRequest) break;

    await new Promise(resolve => setTimeout(resolve, 1000));
    pendingResponse = await openai.responses.retrieve(pendingResponse.id);
  }

  if (!approvalRequest) {
    throw new Error(`Nenhuma solicitação de aprovação encontrada. Resposta finalizou com ${pendingResponse.status}.`);
  }

  // Passo 3: Mostre ao usuário o que o modelo deseja fazer
  console.log('Servidor:', approvalRequest.server_label);
  console.log('Ferramenta:', approvalRequest.name);
  console.log('Argumentos:', approvalRequest.arguments);

  // Passo 4: Envie a aprovação (ou negação) para continuar
  const approve = true; // Substitua pela decisão da sua UI

  const continuedResponse = await openai.responses.create({
    model: 'meetkai:functionary-pt',
    previous_response_id: pendingResponse.id,
    input: [
      {
        type: 'mcp_approval_response',
        approval_request_id: approvalRequest.id,
        approve,
      },
    ],
    store: true,
    stream: false,
  });

  console.log(continuedResponse.output_text);
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(
      bearerAuth: "Bearer <mka1-api-key>",
      serverUrl: "https://apigw.mka1.com"
  );

  // O fluxo de aprovação MCP requer um servidor MCP em execução.
  // O SDK pode construir requisições em background com ferramentas MCP.
  var request = new ResponsesCreateRequest()
  {
      Model = "meetkai:functionary-pt",
      Input = ResponsesCreateRequestInput.CreateStr("Execute a ferramenta aprovada."),
      Background = true,
  };

  Console.WriteLine(request);
  ```

  ```python Python SDK theme={null}
  import os
  import time

  # Passo 1: Crie uma resposta em background exigindo aprovação
  pending = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      instructions="Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP. Use ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos. Mantenha a resposta final concisa.",
      input="Liste meu problema mais recente do Linear atribuído a mim.",
      background=True,
      store=True,
      stream=False,
      tools=[
          {
              "type": "mcp",
              "server_label": "Linear MCP",
              "server_description": "Acesse problemas do Linear através do MCP.",
              "server_url": "https://mcp.linear.app/mcp",
              "allowed_tools": ["issues.list"],
              "headers": {
                  "Authorization": f"Bearer {os.environ['LINEAR_API_KEY']}",
              },
              "require_approval": "always",
          },
      ],
  )

  # Passo 2: Faça polling até aparecer uma solicitação de aprovação
  approval_request = None
  while pending.status in ("queued", "in_progress"):
      for item in pending.output:
          if item.type == "mcp_approval_request":
              approval_request = item
              break
      if approval_request:
          break
      time.sleep(1)
      pending = sdk.llm.responses.get(response_id=pending.id)

  # Passo 3: Mostre ao usuário o que o modelo deseja fazer
  print("Servidor:", approval_request.server_label)
  print("Ferramenta:", approval_request.name)
  print("Argumentos:", approval_request.arguments)

  # Passo 4: Envie a aprovação (ou negação) para continuar
  continued = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      previous_response_id=pending.id,
      input=[
          {
              "type": "mcp_approval_response",
              "approval_request_id": approval_request.id,
              "approve": True,
          },
      ],
      store=True,
      stream=False,
  )

  print(continued.output_text)
  ```

  ```bash bash theme={null}
  # Passo 1: Crie resposta em background exigindo aprovação
  RESPONSE=$(curl -s https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>' \
    --data '{
      "model": "meetkai:functionary-pt",
      "instructions": "Você é um assistente de gerenciamento de projetos com acesso ao Linear via MCP.",
      "input": "Liste meu problema mais recente do Linear atribuído a mim.",
      "background": true,
      "store": true,
      "stream": false,
      "tools": [
        {
          "type": "mcp",
          "server_label": "Linear MCP",
          "server_url": "https://mcp.linear.app/mcp",
          "allowed_tools": ["issues.list"],
          "headers": { "Authorization": "Bearer <linear-api-key>" },
          "require_approval": "always"
        }
      ]
    }')

  RESPONSE_ID=$(echo "$RESPONSE" | jq -r '.id')

  # Passo 2: Faça polling até aparecer solicitação de aprovação
  while true; do
    RESPONSE=$(curl -s "https://apigw.mka1.com/api/v1/llm/responses/$RESPONSE_ID" \
      --header 'Authorization: Bearer <mka1-api-key>' \
      --header 'X-On-Behalf-Of: <end-user-id>')

    APPROVAL_ID=$(echo "$RESPONSE" | jq -r '.output[] | select(.type == "mcp_approval_request") | .id')
    if [ -n "$APPROVAL_ID" ] && [ "$APPROVAL_ID" != "null" ]; then break; fi
    sleep 1
  done

  # Passo 3: Envie a aprovação para continuar
  curl https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>' \
    --data "{
      \"model\": \"meetkai:functionary-pt\",
      \"previous_response_id\": \"$RESPONSE_ID\",
      \"input\": [
        {
          \"type\": \"mcp_approval_response\",
          \"approval_request_id\": \"$APPROVAL_ID\",
          \"approve\": true
        }
      ],
      \"store\": true,
      \"stream\": false
    }"
  ```
</CodeGroup>

Se o usuário final negar a chamada da ferramenta, envie `approve: false`.
Você também pode incluir um campo `reason` no item `mcp_approval_response`.

Para interfaces de aprovação, mostre:

* `server_label` — qual servidor MCP está sendo usado
* `name` — qual ferramenta o modelo deseja chamar
* `arguments` — quais argumentos pretende enviar

## Referência de definição de ferramenta MCP

| Parâmetro            | Tipo                    | Padrão     | Descrição                                                                    |
| -------------------- | ----------------------- | ---------- | ---------------------------------------------------------------------------- |
| `type`               | `"mcp"`                 | —          | Obrigatório. Identifica como uma ferramenta MCP.                             |
| `server_label`       | string                  | —          | Obrigatório. Nome de exibição para o servidor MCP.                           |
| `server_url`         | string                  | —          | URL do endpoint do servidor MCP.                                             |
| `server_description` | string                  | —          | Descrição opcional do propósito do servidor.                                 |
| `allowed_tools`      | string\[]               | —          | Limita quais ferramentas o modelo pode chamar.                               |
| `headers`            | object                  | —          | Headers a serem enviados ao servidor MCP (ex: tokens de autenticação).       |
| `require_approval`   | `"always"` \| `"never"` | `"always"` | Se deve pausar para aprovação do usuário final antes de chamar.              |
| `connector_id`       | string                  | —          | Use um conector pré-configurado em vez de uma URL de servidor personalizada. |

As credenciais passadas em `headers` são automaticamente mascaradas em respostas armazenadas e eventos de streaming.

## Próximos passos

* Veja [gerar uma resposta](/pt/docs/generate-a-response) para o fluxo básico de Respostas
* Veja [respostas em background](/pt/docs/background-responses) para padrões de polling e streaming
* Veja [conversas](/pt/docs/conversations) se quiser manter o mesmo usuário final em um thread mais longo
* Consulte a [referência da API](/pt/api-reference/introduction) para o esquema completo de Respostas
