@happ-ai/platform-mcp 0.3.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/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.js +48 -0
- package/dist/credentials.js.map +1 -0
- package/dist/http.js +90 -0
- package/dist/http.js.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/login.js +76 -0
- package/dist/login.js.map +1 -0
- package/dist/tools/activity.tools.js +34 -0
- package/dist/tools/activity.tools.js.map +1 -0
- package/dist/tools/analytics.tools.js +162 -0
- package/dist/tools/analytics.tools.js.map +1 -0
- package/dist/tools/assistant-tools.tools.js +86 -0
- package/dist/tools/assistant-tools.tools.js.map +1 -0
- package/dist/tools/assistants.tools.js +179 -0
- package/dist/tools/assistants.tools.js.map +1 -0
- package/dist/tools/auth.tools.js +44 -0
- package/dist/tools/auth.tools.js.map +1 -0
- package/dist/tools/calls.tools.js +99 -0
- package/dist/tools/calls.tools.js.map +1 -0
- package/dist/tools/channels.tools.js +158 -0
- package/dist/tools/channels.tools.js.map +1 -0
- package/dist/tools/chats.tools.js +171 -0
- package/dist/tools/chats.tools.js.map +1 -0
- package/dist/tools/companies.tools.js +180 -0
- package/dist/tools/companies.tools.js.map +1 -0
- package/dist/tools/folders.tools.js +71 -0
- package/dist/tools/folders.tools.js.map +1 -0
- package/dist/tools/knowledge.tools.js +71 -0
- package/dist/tools/knowledge.tools.js.map +1 -0
- package/dist/tools/phones.tools.js +92 -0
- package/dist/tools/phones.tools.js.map +1 -0
- package/dist/tools/result.js +7 -0
- package/dist/tools/result.js.map +1 -0
- package/package.json +40 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { getConfig } from "./config.js";
|
|
2
|
+
import { clearCredentials, loadCredentials } from "./credentials.js";
|
|
3
|
+
import { HappApiError, happRequest } from "./http.js";
|
|
4
|
+
import { startLogin } from "./login.js";
|
|
5
|
+
const USAGE = `Использование: happ <команда> | happ-dev <команда>
|
|
6
|
+
|
|
7
|
+
Команды:
|
|
8
|
+
login Войти через браузер и сохранить токены в ~/.happ/credentials.json
|
|
9
|
+
logout Удалить сохранённые токены
|
|
10
|
+
whoami Показать текущего пользователя
|
|
11
|
+
|
|
12
|
+
Без команды процесс стартует как MCP-сервер (stdio).`;
|
|
13
|
+
export async function runCli(command) {
|
|
14
|
+
const { apiUrl } = getConfig();
|
|
15
|
+
switch (command) {
|
|
16
|
+
case "login": {
|
|
17
|
+
const { loginUrl, completion } = await startLogin();
|
|
18
|
+
console.log(`Вход в Happ (${apiUrl})`);
|
|
19
|
+
console.log(`Открываю браузер... Если не открылся, перейди по ссылке:\n${loginUrl}`);
|
|
20
|
+
try {
|
|
21
|
+
const { email } = await completion;
|
|
22
|
+
console.log(`Вход выполнен${email ? ` как ${email}` : ""}. Токены сохранены в ~/.happ/credentials.json.`);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error(`Не удалось завершить вход: ${error.message}`);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
case "logout": {
|
|
31
|
+
const had = loadCredentials() !== null;
|
|
32
|
+
clearCredentials();
|
|
33
|
+
console.log(had ? "Токены удалены." : "Токенов и не было — вход не выполнялся.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
case "whoami": {
|
|
37
|
+
try {
|
|
38
|
+
const me = await happRequest("GET", "/auth/me");
|
|
39
|
+
console.log(`${me.email ?? "<без email>"} (${apiUrl})`);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error instanceof HappApiError && error.status === 401) {
|
|
43
|
+
console.error("Не выполнен вход. Запусти: happ login (или happ-dev login).");
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.error(`Ошибка: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
case "help":
|
|
53
|
+
case "--help":
|
|
54
|
+
case "-h": {
|
|
55
|
+
console.log(USAGE);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
default: {
|
|
59
|
+
console.error(`Неизвестная команда: ${command}\n\n${USAGE}`);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,KAAK,GAAG;;;;;;;qDAOuC,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAe;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAE/B,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,OAAO,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,GAAG,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,6DAA6D,QAAQ,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC;gBACJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,UAAU,CAAC;gBACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,gDAAgD,CAAC,CAAC;YAC3G,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,8BAA+B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;gBACxE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,OAAO;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,MAAM,GAAG,GAAG,eAAe,EAAE,KAAK,IAAI,CAAC;YACvC,gBAAgB,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC;YACjF,OAAO;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,IAAI,CAAC;gBACJ,MAAM,EAAE,GAAG,MAAM,WAAW,CAAkD,KAAK,EAAE,UAAU,CAAC,CAAC;gBACjG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,aAAa,KAAK,MAAM,GAAG,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC3D,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;gBAC9E,CAAC;qBAAM,CAAC;oBACP,OAAO,CAAC,KAAK,CAAC,WAAY,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;gBACtD,CAAC;gBACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,OAAO;QACR,CAAC;QAED,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC,CAAC,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO;QACR,CAAC;QAED,OAAO,CAAC,CAAC,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,wBAAwB,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACtB,CAAC;IACF,CAAC;AACF,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,SAAS;IACxB,OAAO;QACN,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACpF,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;KACtF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getConfig } from "./config.js";
|
|
5
|
+
const CREDENTIALS_DIR = join(homedir(), ".happ");
|
|
6
|
+
const CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
|
|
7
|
+
function readFile() {
|
|
8
|
+
try {
|
|
9
|
+
const data = JSON.parse(readFileSync(CREDENTIALS_FILE, "utf8"));
|
|
10
|
+
// Legacy single-entry format: { apiUrl, accessToken, ... } at top level.
|
|
11
|
+
if (typeof data.accessToken === "string" && typeof data.apiUrl === "string") {
|
|
12
|
+
return { [data.apiUrl]: data };
|
|
13
|
+
}
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function writeFile(file) {
|
|
21
|
+
if (Object.keys(file).length === 0) {
|
|
22
|
+
try {
|
|
23
|
+
rmSync(CREDENTIALS_FILE);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// already gone
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });
|
|
31
|
+
writeFileSync(CREDENTIALS_FILE, JSON.stringify(file, null, 2), { mode: 0o600 });
|
|
32
|
+
}
|
|
33
|
+
export function loadCredentials() {
|
|
34
|
+
const { apiUrl } = getConfig();
|
|
35
|
+
return readFile()[apiUrl] ?? null;
|
|
36
|
+
}
|
|
37
|
+
export function saveCredentials(credentials) {
|
|
38
|
+
const file = readFile();
|
|
39
|
+
file[credentials.apiUrl] = credentials;
|
|
40
|
+
writeFile(file);
|
|
41
|
+
}
|
|
42
|
+
export function clearCredentials() {
|
|
43
|
+
const { apiUrl } = getConfig();
|
|
44
|
+
const file = readFile();
|
|
45
|
+
delete file[apiUrl];
|
|
46
|
+
writeFile(file);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAYxC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;AAEnE,SAAS,QAAQ;IAChB,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAA4B,CAAC;QAC3F,yEAAyE;QACzE,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7E,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAA+B,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,IAAwB,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CAAC,IAAsB;IACxC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACR,eAAe;QAChB,CAAC;QACD,OAAO;IACR,CAAC;IACD,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,eAAe;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAyB;IACxD,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC;IACvC,SAAS,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,SAAS,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { getConfig } from "./config.js";
|
|
2
|
+
import { loadCredentials, saveCredentials } from "./credentials.js";
|
|
3
|
+
export class HappApiError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
body;
|
|
6
|
+
constructor(status, message, body) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.body = body;
|
|
10
|
+
this.name = "HappApiError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function buildUrl(path, params) {
|
|
14
|
+
const { apiUrl } = getConfig();
|
|
15
|
+
const url = new URL(`${apiUrl}${path.startsWith("/") ? path : `/${path}`}`);
|
|
16
|
+
if (params) {
|
|
17
|
+
for (const [key, value] of Object.entries(params)) {
|
|
18
|
+
if (value !== undefined && value !== null) {
|
|
19
|
+
url.searchParams.set(key, String(value));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return url.toString();
|
|
24
|
+
}
|
|
25
|
+
async function rawRequest(method, url, body, accessToken) {
|
|
26
|
+
return fetch(url, {
|
|
27
|
+
method,
|
|
28
|
+
headers: {
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
"Accept": "application/json",
|
|
31
|
+
...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {})
|
|
32
|
+
},
|
|
33
|
+
body: body === undefined ? undefined : JSON.stringify(body)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function refreshTokens() {
|
|
37
|
+
const credentials = loadCredentials();
|
|
38
|
+
if (!credentials?.refreshToken) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const res = await rawRequest("POST", buildUrl("/auth/refresh"), { refreshToken: credentials.refreshToken });
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const tokens = (await res.json());
|
|
46
|
+
saveCredentials({
|
|
47
|
+
...credentials,
|
|
48
|
+
accessToken: tokens.accessToken,
|
|
49
|
+
refreshToken: tokens.refreshToken,
|
|
50
|
+
savedAt: new Date().toISOString()
|
|
51
|
+
});
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
async function parseBody(res) {
|
|
55
|
+
const text = await res.text();
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(text);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return text;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export async function happRequest(method, path, options = {}) {
|
|
64
|
+
const url = buildUrl(path, options.params);
|
|
65
|
+
let accessToken;
|
|
66
|
+
if (!options.unauthenticated) {
|
|
67
|
+
const credentials = loadCredentials();
|
|
68
|
+
if (!credentials?.accessToken) {
|
|
69
|
+
throw new HappApiError(401, "Не выполнен вход. Сначала вызови инструмент happ_login.");
|
|
70
|
+
}
|
|
71
|
+
accessToken = credentials.accessToken;
|
|
72
|
+
}
|
|
73
|
+
let res = await rawRequest(method, url, options.body, accessToken);
|
|
74
|
+
// Access token lives 15 minutes — transparently refresh and retry once.
|
|
75
|
+
if (res.status === 401 && !options.unauthenticated) {
|
|
76
|
+
const refreshed = await refreshTokens();
|
|
77
|
+
if (!refreshed) {
|
|
78
|
+
throw new HappApiError(401, "Сессия истекла. Вызови инструмент happ_login для повторного входа.");
|
|
79
|
+
}
|
|
80
|
+
accessToken = loadCredentials().accessToken;
|
|
81
|
+
res = await rawRequest(method, url, options.body, accessToken);
|
|
82
|
+
}
|
|
83
|
+
const body = await parseBody(res);
|
|
84
|
+
if (!res.ok) {
|
|
85
|
+
const message = typeof body === "object" && body !== null && "message" in body ? String(body.message) : res.statusText;
|
|
86
|
+
throw new HappApiError(res.status, message, body);
|
|
87
|
+
}
|
|
88
|
+
return body;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
// The same binary is exposed as `happ`, `happ-dev` and `happ-mcp`. The bin
|
|
4
|
+
// name picks the target environment; explicit HAPP_* env vars still win.
|
|
5
|
+
// Unrecognized bin names (e.g. plain `npx @happ-ai/platform-mcp`) default to prod;
|
|
6
|
+
// `happ-mcp` targets the local stack.
|
|
7
|
+
const ENV_PRESETS = {
|
|
8
|
+
"happ": { apiUrl: "https://api.happ.tools/api", clientUrl: "https://my.happ.tools" },
|
|
9
|
+
"happ-dev": { apiUrl: "https://api.dev.happ.tools/api", clientUrl: "https://dev.happ.tools" },
|
|
10
|
+
"happ-mcp": { apiUrl: "http://localhost:3000/api", clientUrl: "http://localhost:4001" }
|
|
11
|
+
};
|
|
12
|
+
const preset = ENV_PRESETS[basename(process.argv[1] ?? "")] ?? ENV_PRESETS["happ"];
|
|
13
|
+
process.env.HAPP_API_URL ??= preset.apiUrl;
|
|
14
|
+
process.env.HAPP_CLIENT_URL ??= preset.clientUrl;
|
|
15
|
+
const command = process.argv[2];
|
|
16
|
+
if (command !== undefined) {
|
|
17
|
+
const { runCli } = await import("./cli.js");
|
|
18
|
+
await runCli(command);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
await startMcpServer();
|
|
22
|
+
}
|
|
23
|
+
async function startMcpServer() {
|
|
24
|
+
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
25
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
26
|
+
const [{ registerActivityTools }, { registerAnalyticsTools }, { registerAssistantToolsTools }, { registerAssistantsTools }, { registerAuthTools }, { registerCallsTools }, { registerChannelsTools }, { registerChatsTools }, { registerCompaniesTools }, { registerFoldersTools }, { registerKnowledgeTools }, { registerPhonesTools }] = await Promise.all([
|
|
27
|
+
import("./tools/activity.tools.js"),
|
|
28
|
+
import("./tools/analytics.tools.js"),
|
|
29
|
+
import("./tools/assistant-tools.tools.js"),
|
|
30
|
+
import("./tools/assistants.tools.js"),
|
|
31
|
+
import("./tools/auth.tools.js"),
|
|
32
|
+
import("./tools/calls.tools.js"),
|
|
33
|
+
import("./tools/channels.tools.js"),
|
|
34
|
+
import("./tools/chats.tools.js"),
|
|
35
|
+
import("./tools/companies.tools.js"),
|
|
36
|
+
import("./tools/folders.tools.js"),
|
|
37
|
+
import("./tools/knowledge.tools.js"),
|
|
38
|
+
import("./tools/phones.tools.js")
|
|
39
|
+
]);
|
|
40
|
+
const server = new McpServer({
|
|
41
|
+
name: "happ",
|
|
42
|
+
version: "0.1.0"
|
|
43
|
+
});
|
|
44
|
+
registerAuthTools(server);
|
|
45
|
+
registerCompaniesTools(server);
|
|
46
|
+
registerAssistantsTools(server);
|
|
47
|
+
registerAssistantToolsTools(server);
|
|
48
|
+
registerFoldersTools(server);
|
|
49
|
+
registerKnowledgeTools(server);
|
|
50
|
+
registerPhonesTools(server);
|
|
51
|
+
registerChannelsTools(server);
|
|
52
|
+
registerChatsTools(server);
|
|
53
|
+
registerCallsTools(server);
|
|
54
|
+
registerAnalyticsTools(server);
|
|
55
|
+
registerActivityTools(server);
|
|
56
|
+
const transport = new StdioServerTransport();
|
|
57
|
+
await server.connect(transport);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/login.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
import { getConfig } from "./config.js";
|
|
5
|
+
import { saveCredentials } from "./credentials.js";
|
|
6
|
+
import { happRequest } from "./http.js";
|
|
7
|
+
const LOGIN_TIMEOUT_MS = 3 * 60 * 1000;
|
|
8
|
+
/**
|
|
9
|
+
* Browser hand-off login:
|
|
10
|
+
* 1. Start a loopback HTTP listener on a random port.
|
|
11
|
+
* 2. Open <clientUrl>/cli-auth?port=N&state=S in the browser.
|
|
12
|
+
* 3. The page (authenticated in the browser) fetches a one-time code from the
|
|
13
|
+
* API and delivers it to the listener.
|
|
14
|
+
* 4. Exchange the code for a token pair and persist it.
|
|
15
|
+
*/
|
|
16
|
+
export async function startLogin() {
|
|
17
|
+
const config = getConfig();
|
|
18
|
+
const state = randomBytes(16).toString("hex");
|
|
19
|
+
const server = createServer();
|
|
20
|
+
const port = await new Promise((resolve, reject) => {
|
|
21
|
+
server.once("error", reject);
|
|
22
|
+
server.listen(0, "127.0.0.1", () => {
|
|
23
|
+
const address = server.address();
|
|
24
|
+
if (address && typeof address === "object") {
|
|
25
|
+
resolve(address.port);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
reject(new Error("Failed to bind loopback listener"));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
const loginUrl = `${config.clientUrl}/cli-auth?port=${port}&state=${state}`;
|
|
33
|
+
const code = new Promise((resolve, reject) => {
|
|
34
|
+
const timeout = setTimeout(() => {
|
|
35
|
+
server.close();
|
|
36
|
+
reject(new Error("Время ожидания входа истекло (3 минуты). Запусти happ_login ещё раз."));
|
|
37
|
+
}, LOGIN_TIMEOUT_MS);
|
|
38
|
+
server.on("request", (req, res) => {
|
|
39
|
+
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
|
40
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
41
|
+
if (url.pathname !== "/callback") {
|
|
42
|
+
res.writeHead(404).end();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const receivedCode = url.searchParams.get("code");
|
|
46
|
+
const receivedState = url.searchParams.get("state");
|
|
47
|
+
if (!receivedCode || receivedState !== state) {
|
|
48
|
+
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" }).end("Invalid callback");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" }).end("OK");
|
|
52
|
+
clearTimeout(timeout);
|
|
53
|
+
server.close();
|
|
54
|
+
resolve(receivedCode);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
const completion = (async () => {
|
|
58
|
+
const oneTimeCode = await code;
|
|
59
|
+
const tokens = await happRequest("POST", "/auth/cli/exchange", {
|
|
60
|
+
body: { code: oneTimeCode },
|
|
61
|
+
unauthenticated: true
|
|
62
|
+
});
|
|
63
|
+
saveCredentials({
|
|
64
|
+
apiUrl: config.apiUrl,
|
|
65
|
+
accessToken: tokens.accessToken,
|
|
66
|
+
refreshToken: tokens.refreshToken,
|
|
67
|
+
savedAt: new Date().toISOString()
|
|
68
|
+
});
|
|
69
|
+
const me = await happRequest("GET", "/auth/me");
|
|
70
|
+
return { email: me?.email };
|
|
71
|
+
})();
|
|
72
|
+
// Best effort — if the browser doesn't open, the user can follow the URL manually.
|
|
73
|
+
exec(`open "${loginUrl}"`);
|
|
74
|
+
return { loginUrl, completion };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { happRequest } from "../http.js";
|
|
3
|
+
import { jsonResult } from "./result.js";
|
|
4
|
+
export function registerActivityTools(server) {
|
|
5
|
+
server.registerTool("happ_activity_list", {
|
|
6
|
+
title: "Журнал действий",
|
|
7
|
+
description: "Журнал действий компании — кто что сделал (GET /audit). Доступен только owner/admin. client='cli' — только действия из терминала. Возвращает компактную ленту + nextCursor для подгрузки.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
companyId: z.string().uuid().describe("ID компании"),
|
|
10
|
+
client: z.enum(["cli"]).optional().describe("Только действия из терминала"),
|
|
11
|
+
action: z.string().optional().describe("Фильтр по коду действия, например assistant.create"),
|
|
12
|
+
userId: z.string().uuid().optional().describe("Фильтр по пользователю"),
|
|
13
|
+
status: z.enum(["ok", "failed"]).optional().describe("Только успешные или только ошибки"),
|
|
14
|
+
from: z.string().optional().describe("С какой даты, ISO"),
|
|
15
|
+
to: z.string().optional().describe("По какую дату, ISO"),
|
|
16
|
+
cursor: z.string().optional().describe("nextCursor из предыдущего ответа"),
|
|
17
|
+
limit: z.number().int().min(1).max(200).optional().describe("Сколько записей (по умолчанию 50)")
|
|
18
|
+
}
|
|
19
|
+
}, async (params) => {
|
|
20
|
+
const result = await happRequest("GET", "/audit", { params });
|
|
21
|
+
const feed = (result?.data ?? []).map((row) => ({
|
|
22
|
+
at: row.createdAt,
|
|
23
|
+
who: row.user
|
|
24
|
+
? [row.user.firstName, row.user.lastName].filter(Boolean).join(" ") || row.user.email || "—"
|
|
25
|
+
: "система",
|
|
26
|
+
action: row.action,
|
|
27
|
+
resource: row.resourceType,
|
|
28
|
+
status: row.status,
|
|
29
|
+
via: row.metadata?.client === "cli" ? "терминал" : "веб"
|
|
30
|
+
}));
|
|
31
|
+
return jsonResult({ totalCount: result?.totalCount ?? 0, nextCursor: result?.nextCursor ?? null, feed });
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=activity.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.tools.js","sourceRoot":"","sources":["../../src/tools/activity.tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CAClB,oBAAoB,EACpB;QACC,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACV,2LAA2L;QAC5L,WAAW,EAAE;YACZ,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YACpD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YAC3E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;YAC5F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YACvE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACzF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACzD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACxD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;SAChG;KACD,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QAChB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAoB,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACjF,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC/C,EAAE,EAAE,GAAG,CAAC,SAAS;YACjB,GAAG,EAAE,GAAG,CAAC,IAAI;gBACZ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG;gBAC5F,CAAC,CAAC,SAAS;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,YAAY;YAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK;SACxD,CAAC,CAAC,CAAC;QACJ,OAAO,UAAU,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { happRequest } from "../http.js";
|
|
3
|
+
import { jsonResult } from "./result.js";
|
|
4
|
+
const METRIC_PATHS = {
|
|
5
|
+
"overview": "/analytics/company/overview",
|
|
6
|
+
"usage": "/analytics/company/usage",
|
|
7
|
+
"ai-performance": "/analytics/company/ai-performance",
|
|
8
|
+
"assistants": "/analytics/company/assistants",
|
|
9
|
+
"assistants-time-series": "/analytics/company/assistants/time-series",
|
|
10
|
+
"tokens": "/analytics/company/tokens",
|
|
11
|
+
"tokens-time-series": "/analytics/company/tokens/time-series",
|
|
12
|
+
"channels": "/analytics/company/channels",
|
|
13
|
+
"channels-time-series": "/analytics/company/channels/time-series",
|
|
14
|
+
"contacts": "/analytics/company/contacts",
|
|
15
|
+
"recent-contacts": "/analytics/company/recent-contacts",
|
|
16
|
+
"tools": "/analytics/company/tools",
|
|
17
|
+
"calls": "/analytics/company/calls"
|
|
18
|
+
};
|
|
19
|
+
export function registerAnalyticsTools(server) {
|
|
20
|
+
server.registerTool("happ_analytics", {
|
|
21
|
+
title: "Статистика компании",
|
|
22
|
+
description: "Метрики компании (GET /analytics/company/*). metric: overview (сводка), usage (использование по периодам), ai-performance, assistants (по ассистентам), tokens (расход токенов), channels (по каналам), contacts / recent-contacts (контакты), tools (вызовы инструментов), calls (звонки). Варианты *-time-series возвращают динамику по времени.",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
metric: z
|
|
25
|
+
.enum([
|
|
26
|
+
"overview",
|
|
27
|
+
"usage",
|
|
28
|
+
"ai-performance",
|
|
29
|
+
"assistants",
|
|
30
|
+
"assistants-time-series",
|
|
31
|
+
"tokens",
|
|
32
|
+
"tokens-time-series",
|
|
33
|
+
"channels",
|
|
34
|
+
"channels-time-series",
|
|
35
|
+
"contacts",
|
|
36
|
+
"recent-contacts",
|
|
37
|
+
"tools",
|
|
38
|
+
"calls"
|
|
39
|
+
])
|
|
40
|
+
.describe("Какую метрику получить"),
|
|
41
|
+
companyId: z.string().uuid().describe("ID компании"),
|
|
42
|
+
from: z.string().optional().describe("Начало периода, ISO-дата (например 2026-06-01)"),
|
|
43
|
+
to: z.string().optional().describe("Конец периода, ISO-дата"),
|
|
44
|
+
groupBy: z.enum(["hour", "day", "week", "month"]).optional().describe("Группировка (для usage и time-series)"),
|
|
45
|
+
assistantId: z.string().uuid().optional().describe("Фильтр по ассистенту (для tools/channels/time-series)"),
|
|
46
|
+
take: z.number().int().min(1).optional().describe("Лимит (для contacts/recent-contacts)"),
|
|
47
|
+
skip: z.number().int().min(0).optional()
|
|
48
|
+
}
|
|
49
|
+
}, async ({ metric, ...params }) => {
|
|
50
|
+
const result = await happRequest("GET", METRIC_PATHS[metric], { params });
|
|
51
|
+
return jsonResult(result);
|
|
52
|
+
});
|
|
53
|
+
server.registerTool("happ_monitors_list", {
|
|
54
|
+
title: "Мониторы качества",
|
|
55
|
+
description: "Список мониторов анализа диалогов (GET /conversation-analytics/monitors).",
|
|
56
|
+
inputSchema: {
|
|
57
|
+
companyId: z.string().uuid().optional().describe("ID компании"),
|
|
58
|
+
targetType: z.enum(["chat", "call"]).optional().describe("Тип цели анализа")
|
|
59
|
+
}
|
|
60
|
+
}, async (params) => {
|
|
61
|
+
const result = await happRequest("GET", "/conversation-analytics/monitors", { params });
|
|
62
|
+
return jsonResult(result);
|
|
63
|
+
});
|
|
64
|
+
server.registerTool("happ_monitor_create", {
|
|
65
|
+
title: "Создать монитор",
|
|
66
|
+
description: "Создаёт монитор качества диалогов (POST /conversation-analytics/monitors) — LLM оценивает чаты/звонки по критериям. criteria: массив {id, name, description (5-500 симв.), type, minValue?, maxValue?, values?, language?}.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
companyId: z.string().uuid().describe("ID компании"),
|
|
69
|
+
name: z.string().describe("Название монитора"),
|
|
70
|
+
targetType: z.enum(["chat", "call"]).describe("Что анализировать: чаты или звонки"),
|
|
71
|
+
integrationIds: z.array(z.string().uuid()).describe("ID интеграций-каналов, чьи диалоги анализировать"),
|
|
72
|
+
description: z.string().optional(),
|
|
73
|
+
script: z.string().optional().describe("Скрипт/сценарий, по которому оценивать"),
|
|
74
|
+
isActive: z.boolean().optional(),
|
|
75
|
+
criteria: z.array(z.record(z.unknown())).optional().describe("Критерии оценки")
|
|
76
|
+
}
|
|
77
|
+
}, async (input) => {
|
|
78
|
+
const body = Object.fromEntries(Object.entries(input).filter(([, v]) => v !== undefined));
|
|
79
|
+
const result = await happRequest("POST", "/conversation-analytics/monitors", { body });
|
|
80
|
+
return jsonResult(result);
|
|
81
|
+
});
|
|
82
|
+
server.registerTool("happ_monitor_update", {
|
|
83
|
+
title: "Обновить монитор",
|
|
84
|
+
description: "Обновляет монитор качества (PATCH /conversation-analytics/monitors/:id).",
|
|
85
|
+
inputSchema: {
|
|
86
|
+
monitorId: z.string().uuid().describe("ID монитора"),
|
|
87
|
+
name: z.string().optional(),
|
|
88
|
+
description: z.string().optional(),
|
|
89
|
+
script: z.string().optional(),
|
|
90
|
+
isActive: z.boolean().optional(),
|
|
91
|
+
integrationIds: z.array(z.string().uuid()).optional(),
|
|
92
|
+
criteria: z.array(z.record(z.unknown())).optional()
|
|
93
|
+
}
|
|
94
|
+
}, async ({ monitorId, ...rest }) => {
|
|
95
|
+
const body = Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined));
|
|
96
|
+
const result = await happRequest("PATCH", `/conversation-analytics/monitors/${monitorId}`, { body });
|
|
97
|
+
return jsonResult(result);
|
|
98
|
+
});
|
|
99
|
+
server.registerTool("happ_monitor_delete", {
|
|
100
|
+
title: "Удалить монитор",
|
|
101
|
+
description: "Удаляет монитор качества (DELETE /conversation-analytics/monitors/:id).",
|
|
102
|
+
inputSchema: {
|
|
103
|
+
monitorId: z.string().uuid().describe("ID монитора")
|
|
104
|
+
}
|
|
105
|
+
}, async ({ monitorId }) => {
|
|
106
|
+
const result = await happRequest("DELETE", `/conversation-analytics/monitors/${monitorId}`);
|
|
107
|
+
return jsonResult(result);
|
|
108
|
+
});
|
|
109
|
+
server.registerTool("happ_monitor_conversations", {
|
|
110
|
+
title: "Диалоги монитора",
|
|
111
|
+
description: "Диалоги, попадающие под монитор, с их оценками (GET /conversation-analytics/monitors/:id/conversations).",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
monitorId: z.string().uuid().describe("ID монитора"),
|
|
114
|
+
search: z.string().optional(),
|
|
115
|
+
analysisStatus: z.enum(["analyzed", "not_analyzed"]).optional(),
|
|
116
|
+
minScore: z.number().optional(),
|
|
117
|
+
maxScore: z.number().optional(),
|
|
118
|
+
dateFrom: z.string().optional().describe("ISO-дата"),
|
|
119
|
+
dateTo: z.string().optional().describe("ISO-дата"),
|
|
120
|
+
skip: z.number().int().min(0).optional(),
|
|
121
|
+
take: z.number().int().min(1).optional()
|
|
122
|
+
}
|
|
123
|
+
}, async ({ monitorId, ...params }) => {
|
|
124
|
+
const result = await happRequest("GET", `/conversation-analytics/monitors/${monitorId}/conversations`, {
|
|
125
|
+
params
|
|
126
|
+
});
|
|
127
|
+
return jsonResult(result);
|
|
128
|
+
});
|
|
129
|
+
server.registerTool("happ_analysis_run", {
|
|
130
|
+
title: "Запустить анализ диалога",
|
|
131
|
+
description: "Запускает LLM-анализ конкретного чата или звонка (POST /conversation-analytics/analyses/run). targetId — id чата или звонка.",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
companyId: z.string().uuid().describe("ID компании"),
|
|
134
|
+
targetType: z.enum(["chat", "call"]).describe("Тип цели"),
|
|
135
|
+
targetId: z.string().uuid().describe("ID чата или звонка"),
|
|
136
|
+
monitorIds: z.array(z.string().uuid()).optional().describe("Какими мониторами анализировать")
|
|
137
|
+
}
|
|
138
|
+
}, async (input) => {
|
|
139
|
+
const body = Object.fromEntries(Object.entries(input).filter(([, v]) => v !== undefined));
|
|
140
|
+
const result = await happRequest("POST", "/conversation-analytics/analyses/run", { body });
|
|
141
|
+
return jsonResult(result);
|
|
142
|
+
});
|
|
143
|
+
server.registerTool("happ_analyses_list", {
|
|
144
|
+
title: "Результаты анализов",
|
|
145
|
+
description: "Результаты LLM-анализов диалогов (GET /conversation-analytics/analyses). analysisId указан — вернёт один анализ целиком.",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
companyId: z.string().uuid().describe("ID компании"),
|
|
148
|
+
analysisId: z.string().uuid().optional().describe("ID конкретного анализа"),
|
|
149
|
+
targetType: z.enum(["chat", "call"]).optional(),
|
|
150
|
+
targetId: z.string().uuid().optional().describe("Фильтр по чату/звонку"),
|
|
151
|
+
monitorId: z.string().uuid().optional(),
|
|
152
|
+
skip: z.number().int().min(0).optional(),
|
|
153
|
+
take: z.number().int().min(1).optional()
|
|
154
|
+
}
|
|
155
|
+
}, async ({ analysisId, ...params }) => {
|
|
156
|
+
const result = analysisId
|
|
157
|
+
? await happRequest("GET", `/conversation-analytics/analyses/${analysisId}`)
|
|
158
|
+
: await happRequest("GET", "/conversation-analytics/analyses", { params });
|
|
159
|
+
return jsonResult(result);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=analytics.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.tools.js","sourceRoot":"","sources":["../../src/tools/analytics.tools.ts"],"names":[],"mappings":"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"}
|