O GitHub Copilot é bom a escrever código que parece correto. No entanto, o problema surge no código de integração. Se lhe pedir para interligar uma API de assinatura eletrónica, ele irá inventar com toda a confiança um endpoint, adivinhar o formato do payload ou recorrer a um prefixo Bearer que o seu fornecedor não utiliza. Acaba a depurar o assistente em vez de lançar a funcionalidade.
A solução é fornecer ao Copilot o contrato real da API enquanto ele trabalha. A Firma.dev disponibiliza um servidor Docs MCP e um conjunto de convenções para repositórios que, em conjunto, fazem com que o Copilot gere código de integração correto logo à primeira tentativa. Como a Firma.dev é uma plataforma de assinatura eletrónica API-first faturada a €0,049 por envelope (~5¢ USD), sem licenças individuais ou custos mínimos, a integração em si é pequena. O objetivo é permitir que o Copilot escreva essa pequena integração de forma correta e não apenas de forma plausível.
Isto abrange três etapas de configuração: ligar o Docs MCP, adicionar um ficheiro de instruções a nível de repositório e fornecer ao Copilot os padrões de referência correspondentes.
Passo 1: ligar o Docs MCP da Firma.dev
O servidor de Docs MCP expõe toda a documentação da Firma.dev como ferramentas de pesquisa. Com este servidor associado, o Copilot consulta endpoints reais, formatos de solicitação atuais e esquemas de payload de webhook em vez de adivinhar. É de leitura exclusiva e não requer autenticação, pelo que nunca terá de lhe enviar uma chave de API.
No VS Code, adicione-o ao nível do workspace em .vscode/mcp.json:
{
"servers": {
"firma-docs": {
"type": "http",
"url": "https://docs.firma.dev/mcp"
}
}
}{
"servers": {
"firma-docs": {
"type": "http",
"url": "https://docs.firma.dev/mcp"
}
}
}{
"servers": {
"firma-docs": {
"type": "http",
"url": "https://docs.firma.dev/mcp"
}
}
}Recarregue a janela e confirme que o firma-docs aparece no selecionador de ferramentas do Copilot Chat. Para a CLI do Copilot, adicione o mesmo servidor a ~/.copilot/mcp-config.json e reinicie. No JetBrains ou Visual Studio, abra as Definições → Copilot → Servidores MCP e adicione um servidor HTTP com o nome firma-docs e o URL https://docs.firma.dev/mcp.
Passo 2: adicionar um ficheiro de instruções do Copilot ao repositório
O ficheiro .github/copilot-instructions.md é carregado automaticamente pelo Copilot Chat, pelo agente de programação e pela revisão de código em todos os ambientes suportados. É aqui que fixa as convenções que mantêm o código gerado em conformidade com o contrato. Crie ou adicione ao ficheiro:
## Integração de assinatura eletrónica Firma.dev
Ao gerar código que envia, recebe ou incorpora assinaturas eletrónicas Firma, siga estas convenções:
- URL base da API: `https://api.firma.dev/functions/v1/signing-request-api`
- Autenticação: cabeçalho `Authorization` definido com a chave de API da Firma em bruto (sem o prefixo `Bearer`)
- A chave reside em `FIRMA_API_KEY` como variável de ambiente. Chame a Firma apenas a partir do backend, nunca do browser. Nunca guarde o valor no repositório.
- Use por defeito `POST /signing-requests/create-and-send` ao enviar a partir de um modelo. Utilize o fluxo em dois passos `POST /signing-requests` e depois `POST /signing-requests/{id}/send` apenas quando o utilizador necessitar de rever o rascunho antes de enviar.
- Estrutura do objeto destinatário: `{ first_name, last_name, email, designation: "Signer", order: 1 }`
- Para processadores de webhook, ramifique em `payload.type` (ex: `signing_request.completed`). O objeto de pedido de assinatura reside em `payload.data.signing_request`.
- Para assinatura incorporada, use um iframe `https://app.firma.dev/signing/{signing_request_user_id}` com `allow="camera;microphone;clipboard-write"`.
- Em caso de dúvida sobre um endpoint ou estrutura de campo, utilize o servidor MCP `firma-docs`. Não adivinhe
## Integração de assinatura eletrónica Firma.dev
Ao gerar código que envia, recebe ou incorpora assinaturas eletrónicas Firma, siga estas convenções:
- URL base da API: `https://api.firma.dev/functions/v1/signing-request-api`
- Autenticação: cabeçalho `Authorization` definido com a chave de API da Firma em bruto (sem o prefixo `Bearer`)
- A chave reside em `FIRMA_API_KEY` como variável de ambiente. Chame a Firma apenas a partir do backend, nunca do browser. Nunca guarde o valor no repositório.
- Use por defeito `POST /signing-requests/create-and-send` ao enviar a partir de um modelo. Utilize o fluxo em dois passos `POST /signing-requests` e depois `POST /signing-requests/{id}/send` apenas quando o utilizador necessitar de rever o rascunho antes de enviar.
- Estrutura do objeto destinatário: `{ first_name, last_name, email, designation: "Signer", order: 1 }`
- Para processadores de webhook, ramifique em `payload.type` (ex: `signing_request.completed`). O objeto de pedido de assinatura reside em `payload.data.signing_request`.
- Para assinatura incorporada, use um iframe `https://app.firma.dev/signing/{signing_request_user_id}` com `allow="camera;microphone;clipboard-write"`.
- Em caso de dúvida sobre um endpoint ou estrutura de campo, utilize o servidor MCP `firma-docs`. Não adivinhe
## Integração de assinatura eletrónica Firma.dev
Ao gerar código que envia, recebe ou incorpora assinaturas eletrónicas Firma, siga estas convenções:
- URL base da API: `https://api.firma.dev/functions/v1/signing-request-api`
- Autenticação: cabeçalho `Authorization` definido com a chave de API da Firma em bruto (sem o prefixo `Bearer`)
- A chave reside em `FIRMA_API_KEY` como variável de ambiente. Chame a Firma apenas a partir do backend, nunca do browser. Nunca guarde o valor no repositório.
- Use por defeito `POST /signing-requests/create-and-send` ao enviar a partir de um modelo. Utilize o fluxo em dois passos `POST /signing-requests` e depois `POST /signing-requests/{id}/send` apenas quando o utilizador necessitar de rever o rascunho antes de enviar.
- Estrutura do objeto destinatário: `{ first_name, last_name, email, designation: "Signer", order: 1 }`
- Para processadores de webhook, ramifique em `payload.type` (ex: `signing_request.completed`). O objeto de pedido de assinatura reside em `payload.data.signing_request`.
- Para assinatura incorporada, use um iframe `https://app.firma.dev/signing/{signing_request_user_id}` com `allow="camera;microphone;clipboard-write"`.
- Em caso de dúvida sobre um endpoint ou estrutura de campo, utilize o servidor MCP `firma-docs`. Não adivinhe
Submeta as alterações (commit). A partir daí, uma instrução como "adicionar um pedido de assinatura Firma.dev quando o utilizador clica em Enviar Contrato" começa com as predefinições corretas integradas. Se o seu repositório tiver um limite claro para o backend, pode adicionar um ficheiro para um caminho específico em .github/instructions/firma.instructions.md com uma máscara applyTo para que as regras sejam carregadas apenas quando o Copilot editar o seu código do servidor, mantendo o ficheiro global curto.
Passo 3: fornecer ao Copilot os padrões de referência
O Copilot escreve no idioma correspondente aos ficheiros circundantes. As estruturas abaixo descrevem as chamadas canónicas da Firma.dev. O ficheiro de instruções orienta o Copilot em direção a elas e o MCP preenche os detalhes atuais.
Criar e enviar em TypeScript:
const FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api";
export async function sendForSignature(opts: {
templateId: string;
signer: { firstName: string; lastName: string; email: string };
}) {
const res = await fetch(`${FIRMA_API}/signing-requests/create-and-send`, {
method: "POST",
headers: {
Authorization: process.env.FIRMA_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
template_id: opts.templateId,
recipients: [
{
first_name: opts.signer.firstName,
last_name: opts.signer.lastName,
email: opts.signer.email,
designation: "Signer",
order: 1,
},
],
}),
});
if (!res.ok) throw new Error(`Firma error: ${res.status}`);
return res.json();
}const FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api";
export async function sendForSignature(opts: {
templateId: string;
signer: { firstName: string; lastName: string; email: string };
}) {
const res = await fetch(`${FIRMA_API}/signing-requests/create-and-send`, {
method: "POST",
headers: {
Authorization: process.env.FIRMA_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
template_id: opts.templateId,
recipients: [
{
first_name: opts.signer.firstName,
last_name: opts.signer.lastName,
email: opts.signer.email,
designation: "Signer",
order: 1,
},
],
}),
});
if (!res.ok) throw new Error(`Firma error: ${res.status}`);
return res.json();
}const FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api";
export async function sendForSignature(opts: {
templateId: string;
signer: { firstName: string; lastName: string; email: string };
}) {
const res = await fetch(`${FIRMA_API}/signing-requests/create-and-send`, {
method: "POST",
headers: {
Authorization: process.env.FIRMA_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
template_id: opts.templateId,
recipients: [
{
first_name: opts.signer.firstName,
last_name: opts.signer.lastName,
email: opts.signer.email,
designation: "Signer",
order: 1,
},
],
}),
});
if (!res.ok) throw new Error(`Firma error: ${res.status}`);
return res.json();
}Um processador de webhook ramifica-se no tipo de evento e lê o pedido de assinatura a partir dos dados (data):
export async function POST(req: Request) {
const payload = await req.json();
const { type, data } = payload;
if (type === "signing_request.completed") {
const signingRequestId = data.signing_request.id;
}
return new Response(JSON.stringify({ received: true }), { status: 200 });
}export async function POST(req: Request) {
const payload = await req.json();
const { type, data } = payload;
if (type === "signing_request.completed") {
const signingRequestId = data.signing_request.id;
}
return new Response(JSON.stringify({ received: true }), { status: 200 });
}export async function POST(req: Request) {
const payload = await req.json();
const { type, data } = payload;
if (type === "signing_request.completed") {
const signingRequestId = data.signing_request.id;
}
return new Response(JSON.stringify({ received: true }), { status: 200 });
}Com estes padrões no repositório, o Copilot tem algo concreto para fazer corresponder em vez de uma página em branco para improvisar.
Bónus: o agente de programação do Copilot
Se o seu repositório estiver configurado para o agente de programação do Copilot, aplica-se o mesmo ficheiro .github/copilot-instructions.md. Assim que o MCP e as instruções estiverem implementados, um problema como "Adicionar um botão Enviar Contrato que envie um pedido de assinatura Firma.dev a partir do modelo tmpl_abc123" transforma-se num Pull Request que configura a variável de ambiente, o processador de backend, a rota do webhook e o botão da UI sem precisar de muita ajuda. Peça-lhe para apresentar o URL do webhook e o ID do modelo como TODOs na descrição do PR, para que o revisor possa registar o webhook antes de fundir o código. Mesmo com uma automação tão boa, continuará a querer que um humano receba e verifique esse PR antes de o colocar em produção.
📘 Leia o guia completo de integração do GitHub Copilot
Todos os ficheiros de configuração, regras para caminhos específicos e padrões de referência estão na documentação: https://docs.firma.dev/guides/github-copilot-integration
Começar
Ligue o MCP, adicione o ficheiro de instruções e o Copilot deixará de tentar adivinhar a sua integração. Comece a utilizar a Firma.dev gratuitamente, sem necessidade de cartão de crédito, e deixe o seu assistente escrever o código de assinatura eletrónica corretamente à primeira.