@atehra/mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -1
- package/dist/env.d.ts +11 -4
- package/dist/env.js +23 -13
- package/dist/http-handler.d.ts +23 -0
- package/dist/http-handler.js +78 -0
- package/dist/index-http.d.ts +14 -0
- package/dist/index-http.js +84 -0
- package/dist/index.d.ts +4 -11
- package/dist/index.js +8 -29
- package/dist/register-tools.d.ts +11 -0
- package/dist/register-tools.js +23 -0
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -4,6 +4,29 @@ Servidor MCP (Model Context Protocol) oficial da Atehra. Permite que Claude, Cur
|
|
|
4
4
|
|
|
5
5
|
> **A primeira fintech brasileira projetada pra rodar via agente de IA.**
|
|
6
6
|
|
|
7
|
+
## Dois jeitos de usar
|
|
8
|
+
|
|
9
|
+
| Jeito | Quando usar | Como |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| **Remoto (HTTP/SSE)** | Maioria dos casos. Sem instalar nada. | Cola URL na UI dos Connectors do Claude |
|
|
12
|
+
| **Local (stdio)** | Self-hosting ou ambientes sem internet | `npx -y @atehra/mcp` via config JSON |
|
|
13
|
+
|
|
14
|
+
## Uso remoto (recomendado) — UI dos Connectors
|
|
15
|
+
|
|
16
|
+
No Claude Desktop, vai em **Settings → Connectors → Adicionar conector personalizado** e cola:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
URL: https://atehra-mcp-production.up.railway.app/mcp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Em **Configurações avançadas**, adiciona header:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
x-api-key: atk_test_SUA_CHAVE_AQUI
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Salva. Pronto — 16 ferramentas Atehra disponíveis no Claude.
|
|
29
|
+
|
|
7
30
|
## O que dá pra fazer
|
|
8
31
|
|
|
9
32
|
Com este servidor ligado, seu agente de IA pode:
|
|
@@ -17,12 +40,13 @@ Com este servidor ligado, seu agente de IA pode:
|
|
|
17
40
|
- **Ver métricas do negócio** (receita recorrente mensal, taxa de cancelamento, valor por cliente)
|
|
18
41
|
- **Listar clientes, assinaturas e faturas** com filtros
|
|
19
42
|
|
|
20
|
-
##
|
|
43
|
+
## Uso local (stdio)
|
|
21
44
|
|
|
22
45
|
### Pré-requisitos
|
|
23
46
|
|
|
24
47
|
1. Conta na Atehra (`atehra.com`)
|
|
25
48
|
2. API key (`atk_test_...` pra sandbox, `atk_live_...` pra produção)
|
|
49
|
+
3. Node.js 18+
|
|
26
50
|
|
|
27
51
|
### No Claude Desktop
|
|
28
52
|
|
package/dist/env.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuração do servidor MCP.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Duas formas de criar:
|
|
5
|
+
*
|
|
6
|
+
* 1. loadEnv() — lê do process.env (uso stdio: ATEHRA_API_KEY + ATEHRA_BASE_URL)
|
|
7
|
+
*
|
|
8
|
+
* 2. envFromApiKey(apiKey, baseUrl?) — constrói a partir de uma chave passada
|
|
9
|
+
* em runtime (uso HTTP: chave vem do header da requisição)
|
|
10
|
+
*
|
|
11
|
+
* Em ambos os casos, o modo (sandbox vs produção) é detectado pelo prefixo da chave:
|
|
5
12
|
* - atk_test_... → sandbox
|
|
6
13
|
* - atk_live_... → produção
|
|
7
|
-
*
|
|
8
|
-
* ATEHRA_BASE_URL (opcional) — URL base da API. Default: https://api.atehra.com
|
|
9
14
|
*/
|
|
10
15
|
export type Mode = "test" | "live";
|
|
11
16
|
export interface Env {
|
|
@@ -13,4 +18,6 @@ export interface Env {
|
|
|
13
18
|
baseUrl: string;
|
|
14
19
|
mode: Mode;
|
|
15
20
|
}
|
|
21
|
+
export declare function detectMode(apiKey: string): Mode;
|
|
22
|
+
export declare function envFromApiKey(apiKey: string, baseUrl?: string): Env;
|
|
16
23
|
export declare function loadEnv(): Env;
|
package/dist/env.js
CHANGED
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuração do servidor MCP.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Duas formas de criar:
|
|
5
|
+
*
|
|
6
|
+
* 1. loadEnv() — lê do process.env (uso stdio: ATEHRA_API_KEY + ATEHRA_BASE_URL)
|
|
7
|
+
*
|
|
8
|
+
* 2. envFromApiKey(apiKey, baseUrl?) — constrói a partir de uma chave passada
|
|
9
|
+
* em runtime (uso HTTP: chave vem do header da requisição)
|
|
10
|
+
*
|
|
11
|
+
* Em ambos os casos, o modo (sandbox vs produção) é detectado pelo prefixo da chave:
|
|
5
12
|
* - atk_test_... → sandbox
|
|
6
13
|
* - atk_live_... → produção
|
|
7
|
-
*
|
|
8
|
-
* ATEHRA_BASE_URL (opcional) — URL base da API. Default: https://api.atehra.com
|
|
9
14
|
*/
|
|
15
|
+
const DEFAULT_BASE_URL = "https://api.atehra.com";
|
|
16
|
+
export function detectMode(apiKey) {
|
|
17
|
+
if (apiKey.startsWith("atk_live_"))
|
|
18
|
+
return "live";
|
|
19
|
+
if (apiKey.startsWith("atk_test_"))
|
|
20
|
+
return "test";
|
|
21
|
+
throw new Error("Chave Atehra com prefixo inválido. Use atk_test_... (sandbox) ou atk_live_... (produção).");
|
|
22
|
+
}
|
|
23
|
+
export function envFromApiKey(apiKey, baseUrl) {
|
|
24
|
+
const mode = detectMode(apiKey);
|
|
25
|
+
const resolvedBaseUrl = (baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
26
|
+
return { apiKey, baseUrl: resolvedBaseUrl, mode };
|
|
27
|
+
}
|
|
10
28
|
export function loadEnv() {
|
|
11
29
|
const apiKey = process.env["ATEHRA_API_KEY"];
|
|
12
30
|
if (!apiKey) {
|
|
13
31
|
throw new Error("ATEHRA_API_KEY não definida. Gere uma chave em atehra.com e defina no ambiente.");
|
|
14
32
|
}
|
|
15
|
-
|
|
16
|
-
? "live"
|
|
17
|
-
: apiKey.startsWith("atk_test_")
|
|
18
|
-
? "test"
|
|
19
|
-
: (() => {
|
|
20
|
-
throw new Error("ATEHRA_API_KEY tem prefixo inválido. Use atk_test_... (sandbox) ou atk_live_... (produção).");
|
|
21
|
-
})();
|
|
22
|
-
const baseUrl = (process.env["ATEHRA_BASE_URL"] ?? "https://api.atehra.com").replace(/\/+$/, "");
|
|
23
|
-
return { apiKey, baseUrl, mode };
|
|
33
|
+
return envFromApiKey(apiKey, process.env["ATEHRA_BASE_URL"]);
|
|
24
34
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler HTTP do MCP — adapta uma requisição HTTP em uma sessão MCP.
|
|
3
|
+
*
|
|
4
|
+
* Usa o transporte Streamable HTTP do SDK oficial (modo stateless — cada
|
|
5
|
+
* requisição cria seu próprio servidor MCP). Isso simplifica deploy em
|
|
6
|
+
* ambientes serverless (Vercel, Cloudflare Workers, etc.) onde não há
|
|
7
|
+
* estado persistente entre invocações.
|
|
8
|
+
*
|
|
9
|
+
* Auth: lê a chave Atehra do header `x-api-key` ou `authorization: Bearer ...`.
|
|
10
|
+
* Sem chave, responde 401.
|
|
11
|
+
*/
|
|
12
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
13
|
+
export interface HttpHandlerOptions {
|
|
14
|
+
/** URL base da API Atehra. Default: https://api.atehra.com */
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Handler principal. Use em qualquer framework HTTP Node.js
|
|
19
|
+
* (express, fastify, vercel function, raw http server).
|
|
20
|
+
*
|
|
21
|
+
* Espera o body já parseado em opts.body (pra POST). Pra GET (SSE), passa null.
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleMcpRequest(req: IncomingMessage, res: ServerResponse, body: unknown, options?: HttpHandlerOptions): Promise<void>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler HTTP do MCP — adapta uma requisição HTTP em uma sessão MCP.
|
|
3
|
+
*
|
|
4
|
+
* Usa o transporte Streamable HTTP do SDK oficial (modo stateless — cada
|
|
5
|
+
* requisição cria seu próprio servidor MCP). Isso simplifica deploy em
|
|
6
|
+
* ambientes serverless (Vercel, Cloudflare Workers, etc.) onde não há
|
|
7
|
+
* estado persistente entre invocações.
|
|
8
|
+
*
|
|
9
|
+
* Auth: lê a chave Atehra do header `x-api-key` ou `authorization: Bearer ...`.
|
|
10
|
+
* Sem chave, responde 401.
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
13
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
14
|
+
import { envFromApiKey } from "./env.js";
|
|
15
|
+
import { AtehraClient } from "./client.js";
|
|
16
|
+
import { registerAllTools } from "./register-tools.js";
|
|
17
|
+
/**
|
|
18
|
+
* Lê a chave Atehra dos headers da requisição.
|
|
19
|
+
* Aceita `x-api-key: atk_xxx` OU `authorization: Bearer atk_xxx`.
|
|
20
|
+
*/
|
|
21
|
+
function extractApiKey(req) {
|
|
22
|
+
const xApiKey = req.headers["x-api-key"];
|
|
23
|
+
if (typeof xApiKey === "string" && xApiKey.length > 0)
|
|
24
|
+
return xApiKey;
|
|
25
|
+
if (Array.isArray(xApiKey) && xApiKey[0])
|
|
26
|
+
return xApiKey[0];
|
|
27
|
+
const auth = req.headers["authorization"];
|
|
28
|
+
if (typeof auth === "string" && auth.toLowerCase().startsWith("bearer ")) {
|
|
29
|
+
return auth.slice(7).trim();
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Handler principal. Use em qualquer framework HTTP Node.js
|
|
35
|
+
* (express, fastify, vercel function, raw http server).
|
|
36
|
+
*
|
|
37
|
+
* Espera o body já parseado em opts.body (pra POST). Pra GET (SSE), passa null.
|
|
38
|
+
*/
|
|
39
|
+
export async function handleMcpRequest(req, res, body, options = {}) {
|
|
40
|
+
const apiKey = extractApiKey(req);
|
|
41
|
+
if (!apiKey) {
|
|
42
|
+
res.statusCode = 401;
|
|
43
|
+
res.setHeader("content-type", "application/json");
|
|
44
|
+
res.end(JSON.stringify({
|
|
45
|
+
error: "missing_api_key",
|
|
46
|
+
message: "Passe a chave Atehra no header 'x-api-key' ou em 'authorization: Bearer atk_...'.",
|
|
47
|
+
}));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let env;
|
|
51
|
+
try {
|
|
52
|
+
env = envFromApiKey(apiKey, options.baseUrl);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
res.statusCode = 401;
|
|
56
|
+
res.setHeader("content-type", "application/json");
|
|
57
|
+
res.end(JSON.stringify({
|
|
58
|
+
error: "invalid_api_key",
|
|
59
|
+
message: err instanceof Error ? err.message : String(err),
|
|
60
|
+
}));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const client = new AtehraClient(env);
|
|
64
|
+
const server = new McpServer({ name: "atehra", version: "0.2.0" });
|
|
65
|
+
registerAllTools(server, client, env);
|
|
66
|
+
// Modo stateless: cada requisição cria seu próprio servidor + transporte.
|
|
67
|
+
// sessionIdGenerator: undefined desliga sessão persistente (compatível com serverless).
|
|
68
|
+
const transport = new StreamableHTTPServerTransport({
|
|
69
|
+
sessionIdGenerator: undefined,
|
|
70
|
+
});
|
|
71
|
+
// Limpa quando a conexão fecha (importante em serverless)
|
|
72
|
+
res.on("close", () => {
|
|
73
|
+
void transport.close();
|
|
74
|
+
void server.close();
|
|
75
|
+
});
|
|
76
|
+
await server.connect(transport);
|
|
77
|
+
await transport.handleRequest(req, res, body);
|
|
78
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entry point HTTP standalone — sobe um servidor HTTP escutando em PORT (default 3000)
|
|
4
|
+
* que aceita requisições MCP em /mcp.
|
|
5
|
+
*
|
|
6
|
+
* Pra uso local (testar antes de deploy) ou self-hosting (rodar em VPS/Railway/etc).
|
|
7
|
+
*
|
|
8
|
+
* Pra deploy serverless (Vercel), use api/mcp.ts em vez disso.
|
|
9
|
+
*
|
|
10
|
+
* Variáveis de ambiente:
|
|
11
|
+
* PORT — porta do servidor (default: 3000)
|
|
12
|
+
* ATEHRA_BASE_URL — URL da API Atehra (default: https://api.atehra.com)
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entry point HTTP standalone — sobe um servidor HTTP escutando em PORT (default 3000)
|
|
4
|
+
* que aceita requisições MCP em /mcp.
|
|
5
|
+
*
|
|
6
|
+
* Pra uso local (testar antes de deploy) ou self-hosting (rodar em VPS/Railway/etc).
|
|
7
|
+
*
|
|
8
|
+
* Pra deploy serverless (Vercel), use api/mcp.ts em vez disso.
|
|
9
|
+
*
|
|
10
|
+
* Variáveis de ambiente:
|
|
11
|
+
* PORT — porta do servidor (default: 3000)
|
|
12
|
+
* ATEHRA_BASE_URL — URL da API Atehra (default: https://api.atehra.com)
|
|
13
|
+
*/
|
|
14
|
+
import { createServer } from "node:http";
|
|
15
|
+
import { handleMcpRequest } from "./http-handler.js";
|
|
16
|
+
const PORT = Number.parseInt(process.env["PORT"] ?? "3000", 10);
|
|
17
|
+
const BASE_URL = process.env["ATEHRA_BASE_URL"];
|
|
18
|
+
async function readBody(req) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const chunks = [];
|
|
21
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
22
|
+
req.on("end", () => {
|
|
23
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
24
|
+
if (!raw)
|
|
25
|
+
return resolve(null);
|
|
26
|
+
try {
|
|
27
|
+
resolve(JSON.parse(raw));
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
reject(err);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
req.on("error", reject);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const server = createServer(async (req, res) => {
|
|
37
|
+
// CORS pra cliente MCP web
|
|
38
|
+
res.setHeader("access-control-allow-origin", "*");
|
|
39
|
+
res.setHeader("access-control-allow-methods", "GET, POST, OPTIONS");
|
|
40
|
+
res.setHeader("access-control-allow-headers", "content-type, x-api-key, authorization, mcp-session-id, mcp-protocol-version");
|
|
41
|
+
res.setHeader("access-control-expose-headers", "mcp-session-id");
|
|
42
|
+
if (req.method === "OPTIONS") {
|
|
43
|
+
res.statusCode = 204;
|
|
44
|
+
res.end();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
// Health check
|
|
48
|
+
if (req.url === "/health" || req.url === "/") {
|
|
49
|
+
res.statusCode = 200;
|
|
50
|
+
res.setHeader("content-type", "application/json");
|
|
51
|
+
res.end(JSON.stringify({
|
|
52
|
+
name: "atehra-mcp",
|
|
53
|
+
version: "0.2.0",
|
|
54
|
+
status: "ok",
|
|
55
|
+
usage: "POST /mcp com header x-api-key: atk_test_... ou atk_live_...",
|
|
56
|
+
}));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// MCP endpoint
|
|
60
|
+
if (req.url === "/mcp" || req.url?.startsWith("/mcp?")) {
|
|
61
|
+
try {
|
|
62
|
+
const body = req.method === "POST" ? await readBody(req) : null;
|
|
63
|
+
await handleMcpRequest(req, res, body, { baseUrl: BASE_URL });
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (!res.headersSent) {
|
|
67
|
+
res.statusCode = 500;
|
|
68
|
+
res.setHeader("content-type", "application/json");
|
|
69
|
+
res.end(JSON.stringify({
|
|
70
|
+
error: "internal_error",
|
|
71
|
+
message: err instanceof Error ? err.message : String(err),
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// 404
|
|
78
|
+
res.statusCode = 404;
|
|
79
|
+
res.setHeader("content-type", "application/json");
|
|
80
|
+
res.end(JSON.stringify({ error: "not_found" }));
|
|
81
|
+
});
|
|
82
|
+
server.listen(PORT, () => {
|
|
83
|
+
process.stderr.write(`[atehra-mcp-http] escutando em http://localhost:${PORT}/mcp\n`);
|
|
84
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @atehra/mcp — Servidor MCP oficial da Atehra
|
|
3
|
+
* @atehra/mcp — Servidor MCP oficial da Atehra (transporte stdio)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Pra uso local via npx ou config do Claude Desktop. Lê a chave da API
|
|
6
|
+
* da variável ATEHRA_API_KEY e roda como subprocess.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
* request_anticipation, request_withdrawal
|
|
9
|
-
*
|
|
10
|
-
* Cobrar (6): create_customer, list_customers, create_plan,
|
|
11
|
-
* create_checkout_session, create_checkout_link, list_recent_orders
|
|
12
|
-
*
|
|
13
|
-
* Números (3): get_metrics_overview, list_subscriptions, list_invoices
|
|
14
|
-
*
|
|
15
|
-
* Régua (2): get_dunning_config, update_dunning_config
|
|
8
|
+
* Pra uso remoto (via UI dos Connectors do Claude), veja src/index-http.ts.
|
|
16
9
|
*/
|
|
17
10
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,47 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @atehra/mcp — Servidor MCP oficial da Atehra
|
|
3
|
+
* @atehra/mcp — Servidor MCP oficial da Atehra (transporte stdio)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Pra uso local via npx ou config do Claude Desktop. Lê a chave da API
|
|
6
|
+
* da variável ATEHRA_API_KEY e roda como subprocess.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
* request_anticipation, request_withdrawal
|
|
9
|
-
*
|
|
10
|
-
* Cobrar (6): create_customer, list_customers, create_plan,
|
|
11
|
-
* create_checkout_session, create_checkout_link, list_recent_orders
|
|
12
|
-
*
|
|
13
|
-
* Números (3): get_metrics_overview, list_subscriptions, list_invoices
|
|
14
|
-
*
|
|
15
|
-
* Régua (2): get_dunning_config, update_dunning_config
|
|
8
|
+
* Pra uso remoto (via UI dos Connectors do Claude), veja src/index-http.ts.
|
|
16
9
|
*/
|
|
17
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
18
11
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19
12
|
import { loadEnv } from "./env.js";
|
|
20
13
|
import { AtehraClient } from "./client.js";
|
|
21
|
-
import {
|
|
22
|
-
import { registerCustomerTools } from "./tools/customers.js";
|
|
23
|
-
import { registerPlanTools } from "./tools/plans.js";
|
|
24
|
-
import { registerChargeTools } from "./tools/charges.js";
|
|
25
|
-
import { registerMetricsTools } from "./tools/metrics.js";
|
|
26
|
-
import { registerBillingTools } from "./tools/billing.js";
|
|
27
|
-
import { registerDunningTools } from "./tools/dunning.js";
|
|
14
|
+
import { registerAllTools } from "./register-tools.js";
|
|
28
15
|
async function main() {
|
|
29
16
|
const env = loadEnv();
|
|
30
17
|
const client = new AtehraClient(env);
|
|
31
18
|
const server = new McpServer({
|
|
32
19
|
name: "atehra",
|
|
33
|
-
version: "0.
|
|
20
|
+
version: "0.2.0",
|
|
34
21
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
registerCustomerTools(server, client);
|
|
38
|
-
registerPlanTools(server, client);
|
|
39
|
-
registerChargeTools(server, client);
|
|
40
|
-
registerMetricsTools(server, client);
|
|
41
|
-
registerBillingTools(server, client);
|
|
42
|
-
registerDunningTools(server, client);
|
|
43
|
-
// Log de boot vai pra stderr (stdout é reservado pro protocolo MCP)
|
|
44
|
-
process.stderr.write(`[atehra-mcp] iniciado. Modo: ${env.mode}. Base URL: ${env.baseUrl}\n`);
|
|
22
|
+
registerAllTools(server, client, env);
|
|
23
|
+
process.stderr.write(`[atehra-mcp] iniciado (stdio). Modo: ${env.mode}. Base URL: ${env.baseUrl}\n`);
|
|
45
24
|
const transport = new StdioServerTransport();
|
|
46
25
|
await server.connect(transport);
|
|
47
26
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registro centralizado das 16 ferramentas Atehra.
|
|
3
|
+
*
|
|
4
|
+
* Compartilhado entre o transporte stdio (uso local via npx) e o transporte
|
|
5
|
+
* HTTP/SSE (uso remoto via UI Connectors do Claude). Mantém a lista de tools
|
|
6
|
+
* em um único lugar — toda nova feature aparece nos dois transportes ao mesmo tempo.
|
|
7
|
+
*/
|
|
8
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import type { AtehraClient } from "./client.js";
|
|
10
|
+
import type { Env } from "./env.js";
|
|
11
|
+
export declare function registerAllTools(server: McpServer, client: AtehraClient, env: Env): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registro centralizado das 16 ferramentas Atehra.
|
|
3
|
+
*
|
|
4
|
+
* Compartilhado entre o transporte stdio (uso local via npx) e o transporte
|
|
5
|
+
* HTTP/SSE (uso remoto via UI Connectors do Claude). Mantém a lista de tools
|
|
6
|
+
* em um único lugar — toda nova feature aparece nos dois transportes ao mesmo tempo.
|
|
7
|
+
*/
|
|
8
|
+
import { registerBalanceTools } from "./tools/balance.js";
|
|
9
|
+
import { registerCustomerTools } from "./tools/customers.js";
|
|
10
|
+
import { registerPlanTools } from "./tools/plans.js";
|
|
11
|
+
import { registerChargeTools } from "./tools/charges.js";
|
|
12
|
+
import { registerMetricsTools } from "./tools/metrics.js";
|
|
13
|
+
import { registerBillingTools } from "./tools/billing.js";
|
|
14
|
+
import { registerDunningTools } from "./tools/dunning.js";
|
|
15
|
+
export function registerAllTools(server, client, env) {
|
|
16
|
+
registerBalanceTools(server, client, env);
|
|
17
|
+
registerCustomerTools(server, client);
|
|
18
|
+
registerPlanTools(server, client);
|
|
19
|
+
registerChargeTools(server, client);
|
|
20
|
+
registerMetricsTools(server, client);
|
|
21
|
+
registerBillingTools(server, client);
|
|
22
|
+
registerDunningTools(server, client);
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atehra/mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Servidor MCP oficial da Atehra — opere a infraestrutura financeira BR via Claude, Cursor, ChatGPT e qualquer cliente MCP",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Servidor MCP oficial da Atehra — opere a infraestrutura financeira BR via Claude, Cursor, ChatGPT e qualquer cliente MCP. Suporta stdio (local) e HTTP/SSE (remoto, via Connectors UI do Claude).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"atehra-mcp": "dist/index.js"
|
|
8
|
+
"atehra-mcp": "dist/index.js",
|
|
9
|
+
"atehra-mcp-http": "dist/index-http.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc && chmod +x dist/index.js dist/index-http.js",
|
|
16
17
|
"dev": "tsc --watch",
|
|
17
|
-
"start": "node dist/index.js",
|
|
18
|
+
"start": "node dist/index-http.js",
|
|
19
|
+
"start:stdio": "node dist/index.js",
|
|
18
20
|
"smoke": "node --test dist/tests/smoke.test.js",
|
|
19
21
|
"prepublishOnly": "npm run build"
|
|
20
22
|
},
|