post_customer
Create new customer leads in the Hub by registering them from external sources. This tool validates Brazilian CPF/CNPJ IDs and manages customer records through structured operations.
Instructions
Cria um novo cliente (lead) no Hub. Use esta ferramenta para registrar leads encontrados em outras fontes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| codigo | Yes | ||
| tipo | Yes | Tipo de pessoa. 1=Jurídica, 2=Física, 3=Exportação | |
| cnpjCpf | Yes | Somente dígitos: CPF (11 dígitos) ou CNPJ (14 dígitos) | |
| nomeFantasia | Yes | ||
| status | Yes |
Implementation Reference
- src/tools/customer/handler.ts:41-83 (handler)The handler function that executes the post_customer logic, including validation and the HTTP request to create a customer.
async ({ cnpjCpf, codigo, nomeFantasia, status, tipo }) => { if (tipo === constants.PESSOA.TIPO.FISICA) { if (!constants.CPF.test(cnpjCpf)) { return { isError: true, content: [{ type: "text", text: "Erro: cnpjCpf deve ser um CPF válido com 11 dígitos numéricos (sem pontos ou traços)" }], }; } } else if ( tipo === constants.PESSOA.TIPO.JURIDICA || tipo === constants.PESSOA.TIPO.EXPORTACAO ) { if (!constants.CNPJ.test(cnpjCpf)) { return { isError: true, content: [{ type: "text", text: "Erro: cnpjCpf deve ser um CNPJ válido com 14 dígitos numéricos (sem pontos, barras ou traços)" }], }; } } const { data, error } = await request<CustomerRequest, CustomerResponse>( "/clientes", "POST", { codigo, tipo, cnpjCpf, nomeFantasia, status }, ); if (error || !data) { return { isError: true, content: [{ type: "text", text: `Falha ao criar cliente: ${error ?? "resposta vazia"}` }], }; } return { content: [ { type: "text", text: `Cliente criado com sucesso!\n\n${JSON.stringify(data, null, 2)}`, }, ], }; }, ); - src/tools/customer/handler.ts:11-39 (schema)The input schema definition using Zod for the post_customer tool.
inputSchema: z.object({ codigo: z .string({ required_error: "codigo é obrigatório" }) .min(1, "codigo não pode ser vazio") .max(40, "codigo deve ter no máximo 40 caracteres"), tipo: z .nativeEnum(constants.PESSOA.TIPO, { required_error: "tipo é obrigatório", invalid_type_error: `tipo deve ser: ${Object.entries(constants.PESSOA.TIPO) .map(([k, v]) => `${v}=${k}`) .join(", ")}`, }) .describe("Tipo de pessoa. 1=Jurídica, 2=Física, 3=Exportação"), cnpjCpf: z .string({ required_error: "cnpjCpf é obrigatório" }) .min(1, "cnpjCpf não pode ser vazio") .max(40, "cnpjCpf deve ter no máximo 40 caracteres") .describe("Somente dígitos: CPF (11 dígitos) ou CNPJ (14 dígitos)"), nomeFantasia: z .string({ required_error: "nomeFantasia é obrigatório" }) .min(1, "nomeFantasia não pode ser vazio") .max(250, "nomeFantasia deve ter no máximo 250 caracteres"), status: z .number({ required_error: "status é obrigatório" }) .refine( (v) => Object.values(constants.STATUS).includes(v), { message: `status deve ser ${Object.values(constants.STATUS).join(" ou ")} (0=Inativo, 1=Ativo)` }, ), }), - src/tools/customer/handler.ts:7-83 (registration)The registration of the post_customer tool with the MCP server.
server.registerTool( "post_customer", { description: "Cria um novo cliente (lead) no Hub. Use esta ferramenta para registrar leads encontrados em outras fontes.", inputSchema: z.object({ codigo: z .string({ required_error: "codigo é obrigatório" }) .min(1, "codigo não pode ser vazio") .max(40, "codigo deve ter no máximo 40 caracteres"), tipo: z .nativeEnum(constants.PESSOA.TIPO, { required_error: "tipo é obrigatório", invalid_type_error: `tipo deve ser: ${Object.entries(constants.PESSOA.TIPO) .map(([k, v]) => `${v}=${k}`) .join(", ")}`, }) .describe("Tipo de pessoa. 1=Jurídica, 2=Física, 3=Exportação"), cnpjCpf: z .string({ required_error: "cnpjCpf é obrigatório" }) .min(1, "cnpjCpf não pode ser vazio") .max(40, "cnpjCpf deve ter no máximo 40 caracteres") .describe("Somente dígitos: CPF (11 dígitos) ou CNPJ (14 dígitos)"), nomeFantasia: z .string({ required_error: "nomeFantasia é obrigatório" }) .min(1, "nomeFantasia não pode ser vazio") .max(250, "nomeFantasia deve ter no máximo 250 caracteres"), status: z .number({ required_error: "status é obrigatório" }) .refine( (v) => Object.values(constants.STATUS).includes(v), { message: `status deve ser ${Object.values(constants.STATUS).join(" ou ")} (0=Inativo, 1=Ativo)` }, ), }), }, async ({ cnpjCpf, codigo, nomeFantasia, status, tipo }) => { if (tipo === constants.PESSOA.TIPO.FISICA) { if (!constants.CPF.test(cnpjCpf)) { return { isError: true, content: [{ type: "text", text: "Erro: cnpjCpf deve ser um CPF válido com 11 dígitos numéricos (sem pontos ou traços)" }], }; } } else if ( tipo === constants.PESSOA.TIPO.JURIDICA || tipo === constants.PESSOA.TIPO.EXPORTACAO ) { if (!constants.CNPJ.test(cnpjCpf)) { return { isError: true, content: [{ type: "text", text: "Erro: cnpjCpf deve ser um CNPJ válido com 14 dígitos numéricos (sem pontos, barras ou traços)" }], }; } } const { data, error } = await request<CustomerRequest, CustomerResponse>( "/clientes", "POST", { codigo, tipo, cnpjCpf, nomeFantasia, status }, ); if (error || !data) { return { isError: true, content: [{ type: "text", text: `Falha ao criar cliente: ${error ?? "resposta vazia"}` }], }; } return { content: [ { type: "text", text: `Cliente criado com sucesso!\n\n${JSON.stringify(data, null, 2)}`, }, ], }; }, );