@chronova/mcp-server 1.0.0 → 1.0.2
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/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/chronova-client.d.ts +7 -0
- package/dist/lib/chronova-client.d.ts.map +1 -0
- package/dist/lib/chronova-client.js +44 -0
- package/dist/lib/chronova-client.js.map +1 -0
- package/dist/lib/config.d.ts +15 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +71 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +9 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +53 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/types.d.ts +113 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +88 -0
- package/dist/server.js.map +1 -0
- package/dist/stdio.d.ts +3 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +30 -0
- package/dist/stdio.js.map +1 -0
- package/dist/tools/get-ai-insights.d.ts +4 -0
- package/dist/tools/get-ai-insights.d.ts.map +1 -0
- package/dist/tools/get-ai-insights.js +49 -0
- package/dist/tools/get-ai-insights.js.map +1 -0
- package/dist/tools/get-developer-context.d.ts +4 -0
- package/dist/tools/get-developer-context.d.ts.map +1 -0
- package/dist/tools/get-developer-context.js +36 -0
- package/dist/tools/get-developer-context.js.map +1 -0
- package/dist/tools/get-productivity-summary.d.ts +4 -0
- package/dist/tools/get-productivity-summary.d.ts.map +1 -0
- package/dist/tools/get-productivity-summary.js +57 -0
- package/dist/tools/get-productivity-summary.js.map +1 -0
- package/dist/tools/get-recent-activity.d.ts +4 -0
- package/dist/tools/get-recent-activity.d.ts.map +1 -0
- package/dist/tools/get-recent-activity.js +93 -0
- package/dist/tools/get-recent-activity.js.map +1 -0
- package/package.json +2 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startServer } from "./server.js";
|
|
3
|
+
const HELP_TEXT = `
|
|
4
|
+
Usage: @chronova/mcp-server [options]
|
|
5
|
+
|
|
6
|
+
Options:
|
|
7
|
+
--port <number> Port to listen on (default: 3001)
|
|
8
|
+
--api-url <url> Chronova API URL (default: https://chronova.dev/api/v1)
|
|
9
|
+
--help Show this help message
|
|
10
|
+
|
|
11
|
+
Configuration priority:
|
|
12
|
+
1. Environment variables (CHRONOVA_API_KEY, CHRONOVA_API_URL)
|
|
13
|
+
2. ~/.chronova.cfg file (api_key, api_url under [settings])
|
|
14
|
+
3. ~/.wakatime.cfg file (api_key, api_url under [settings])
|
|
15
|
+
4. Defaults
|
|
16
|
+
|
|
17
|
+
Environment variables:
|
|
18
|
+
CHRONOVA_API_KEY Your Chronova API key (required if no config file)
|
|
19
|
+
CHRONOVA_API_URL Chronova API URL (default: https://chronova.dev/api/v1)
|
|
20
|
+
PORT Server port (default: 3001)
|
|
21
|
+
`;
|
|
22
|
+
function parseArgs() {
|
|
23
|
+
const args = process.argv.slice(2);
|
|
24
|
+
let i = 0;
|
|
25
|
+
while (i < args.length) {
|
|
26
|
+
const arg = args[i];
|
|
27
|
+
if (arg === "--help") {
|
|
28
|
+
console.log(HELP_TEXT.trim());
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if (arg === "--port") {
|
|
32
|
+
const value = args[++i];
|
|
33
|
+
if (!value || isNaN(Number(value))) {
|
|
34
|
+
console.error("Error: --port requires a number");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
process.env.PORT = value;
|
|
38
|
+
}
|
|
39
|
+
else if (arg === "--api-url") {
|
|
40
|
+
const value = args[++i];
|
|
41
|
+
if (!value) {
|
|
42
|
+
console.error("Error: --api-url requires a URL");
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
process.env.CHRONOVA_API_URL = value;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error(`Error: Unknown option '${arg}'`);
|
|
49
|
+
console.log(HELP_TEXT.trim());
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
i++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
parseArgs();
|
|
56
|
+
startServer();
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;CAkBjB,CAAC;AAEF,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC;QAC3B,CAAC;aAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,GAAG,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,CAAC,EAAE,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,EAAE,CAAC;AACZ,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chronova-client.d.ts","sourceRoot":"","sources":["../../src/lib/chronova-client.ts"],"names":[],"mappings":"AAIA,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAGrB,OAAO,GAAE,MAAsE,EAC/E,MAAM,GAAE,MAA2C;IAQ/C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAkCxE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { mapHttpStatusToError, mapNetworkError } from "./errors.js";
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
3
|
+
export class ChronovaClient {
|
|
4
|
+
baseUrl;
|
|
5
|
+
apiKey;
|
|
6
|
+
constructor(baseUrl = process.env.CHRONOVA_API_URL ?? "https://chronova.dev/api/v1", apiKey = process.env.CHRONOVA_API_KEY ?? "") {
|
|
7
|
+
// Ensure trailing slash so new URL("users/current", baseUrl) resolves correctly
|
|
8
|
+
// Without it, new URL("path", "https://host/api/v1") yields "https://host/path"
|
|
9
|
+
this.baseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
10
|
+
this.apiKey = apiKey;
|
|
11
|
+
}
|
|
12
|
+
async get(path, params) {
|
|
13
|
+
const url = new URL(path, this.baseUrl);
|
|
14
|
+
if (params) {
|
|
15
|
+
for (const [key, value] of Object.entries(params)) {
|
|
16
|
+
if (value !== undefined && value !== "") {
|
|
17
|
+
url.searchParams.set(key, value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const urlStr = url.toString();
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(urlStr, {
|
|
24
|
+
method: "GET",
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
27
|
+
Accept: "application/json",
|
|
28
|
+
},
|
|
29
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw mapHttpStatusToError(response, urlStr);
|
|
33
|
+
}
|
|
34
|
+
return (await response.json());
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof TypeError || (error instanceof Error && error.name === "AbortError")) {
|
|
38
|
+
throw mapNetworkError(error, urlStr);
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=chronova-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chronova-client.js","sourceRoot":"","sources":["../../src/lib/chronova-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEpE,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,OAAO,cAAc;IACjB,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YACE,UAAkB,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,6BAA6B,EAC/E,SAAiB,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAEnD,gFAAgF;QAChF,gFAAgF;QAChF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;QAC/D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,MAA+B;QACxD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;oBACxC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE9B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;gBACnC,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;oBACtC,MAAM,EAAE,kBAAkB;iBAC3B;gBACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;aAChD,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;YAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,SAAS,IAAI,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;gBAC1F,MAAM,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ChronovaConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
port: number;
|
|
5
|
+
configSource: "env" | "chronova.cfg" | "wakatime.cfg" | "none";
|
|
6
|
+
}
|
|
7
|
+
export interface ResolveConfigOptions {
|
|
8
|
+
readFile?: (path: string) => Record<string, string> | null;
|
|
9
|
+
getHomeDir?: () => string;
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
}
|
|
12
|
+
export declare function parseIniFile(content: string): Record<string, string>;
|
|
13
|
+
export declare function readConfigFile(filePath: string): Record<string, string> | null;
|
|
14
|
+
export declare function resolveConfig(options?: ResolveConfigOptions): ChronovaConfig;
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,KAAK,GAAG,cAAc,GAAG,cAAc,GAAG,MAAM,CAAC;CAChE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3D,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcpE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAO9E;AAED,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,cAAc,CA4C5E"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const DEFAULT_API_URL = "https://chronova.dev/api/v1";
|
|
5
|
+
const DEFAULT_PORT = 3001;
|
|
6
|
+
export function parseIniFile(content) {
|
|
7
|
+
const result = {};
|
|
8
|
+
for (const line of content.split("\n")) {
|
|
9
|
+
const trimmed = line.trim();
|
|
10
|
+
if (trimmed === "" || trimmed.startsWith("[") || trimmed.startsWith("#") || trimmed.startsWith(";")) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
const eqIndex = trimmed.indexOf("=");
|
|
14
|
+
if (eqIndex === -1)
|
|
15
|
+
continue;
|
|
16
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
17
|
+
const value = trimmed.slice(eqIndex + 1).trim();
|
|
18
|
+
result[key] = value;
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
export function readConfigFile(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
const content = readFileSync(filePath, "utf-8");
|
|
25
|
+
return parseIniFile(content);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function resolveConfig(options) {
|
|
32
|
+
const readFile = options?.readFile ?? readConfigFile;
|
|
33
|
+
const getHome = options?.getHomeDir ?? homedir;
|
|
34
|
+
const env = options?.env ?? process.env;
|
|
35
|
+
const envApiKey = env.CHRONOVA_API_KEY;
|
|
36
|
+
const envApiUrl = env.CHRONOVA_API_URL;
|
|
37
|
+
const envPort = env.PORT;
|
|
38
|
+
if (envApiKey) {
|
|
39
|
+
return {
|
|
40
|
+
apiKey: envApiKey,
|
|
41
|
+
apiUrl: envApiUrl ?? DEFAULT_API_URL,
|
|
42
|
+
port: envPort ? Number(envPort) : DEFAULT_PORT,
|
|
43
|
+
configSource: "env",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const chronovaCfg = readFile(join(getHome(), ".chronova.cfg"));
|
|
47
|
+
if (chronovaCfg?.api_key) {
|
|
48
|
+
return {
|
|
49
|
+
apiKey: chronovaCfg.api_key,
|
|
50
|
+
apiUrl: envApiUrl ?? chronovaCfg.api_url ?? DEFAULT_API_URL,
|
|
51
|
+
port: envPort ? Number(envPort) : DEFAULT_PORT,
|
|
52
|
+
configSource: "chronova.cfg",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const wakatimeCfg = readFile(join(getHome(), ".wakatime.cfg"));
|
|
56
|
+
if (wakatimeCfg?.api_key) {
|
|
57
|
+
return {
|
|
58
|
+
apiKey: wakatimeCfg.api_key,
|
|
59
|
+
apiUrl: envApiUrl ?? wakatimeCfg.api_url ?? DEFAULT_API_URL,
|
|
60
|
+
port: envPort ? Number(envPort) : DEFAULT_PORT,
|
|
61
|
+
configSource: "wakatime.cfg",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
apiKey: "",
|
|
66
|
+
apiUrl: envApiUrl ?? DEFAULT_API_URL,
|
|
67
|
+
port: envPort ? Number(envPort) : DEFAULT_PORT,
|
|
68
|
+
configSource: "none",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class ChronovaApiError extends Error {
|
|
2
|
+
statusCode: number;
|
|
3
|
+
code: string;
|
|
4
|
+
retryAfter?: number;
|
|
5
|
+
constructor(message: string, statusCode: number, code: string, retryAfter?: number);
|
|
6
|
+
}
|
|
7
|
+
export declare function mapHttpStatusToError(response: Response, url: string): ChronovaApiError;
|
|
8
|
+
export declare function mapNetworkError(error: unknown, url: string): ChronovaApiError;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;gBAER,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAOnF;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CA8DtF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAM7E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export class ChronovaApiError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
code;
|
|
4
|
+
retryAfter;
|
|
5
|
+
constructor(message, statusCode, code, retryAfter) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ChronovaApiError";
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.retryAfter = retryAfter;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function mapHttpStatusToError(response, url) {
|
|
14
|
+
const status = response.status;
|
|
15
|
+
const statusText = response.statusText;
|
|
16
|
+
switch (status) {
|
|
17
|
+
case 401:
|
|
18
|
+
return new ChronovaApiError("Unauthorized: Invalid or expired API key. Check your CHRONOVA_API_KEY configuration.", 401, "UNAUTHORIZED");
|
|
19
|
+
case 429: {
|
|
20
|
+
let retryAfter;
|
|
21
|
+
const retryAfterHeader = response.headers.get("Retry-After");
|
|
22
|
+
if (retryAfterHeader) {
|
|
23
|
+
const parsed = Number(retryAfterHeader);
|
|
24
|
+
if (!Number.isNaN(parsed)) {
|
|
25
|
+
retryAfter = parsed;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (retryAfter === undefined) {
|
|
29
|
+
const resetHeader = response.headers.get("X-RateLimit-Reset");
|
|
30
|
+
if (resetHeader) {
|
|
31
|
+
const resetEpoch = Number(resetHeader);
|
|
32
|
+
if (!Number.isNaN(resetEpoch) && resetEpoch > 0) {
|
|
33
|
+
const remaining = Math.max(0, Math.ceil(resetEpoch - Date.now() / 1000));
|
|
34
|
+
retryAfter = remaining;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const suffix = retryAfter !== undefined ? ` Retry after ${retryAfter} seconds.` : "";
|
|
39
|
+
return new ChronovaApiError(`Rate limited: Too many requests.${suffix}`, 429, "RATE_LIMITED", retryAfter);
|
|
40
|
+
}
|
|
41
|
+
case 404:
|
|
42
|
+
return new ChronovaApiError("Not found: The requested resource does not exist.", 404, "NOT_FOUND");
|
|
43
|
+
default:
|
|
44
|
+
if (status >= 500) {
|
|
45
|
+
return new ChronovaApiError(`Chronova server error: ${statusText}. Please try again later.`, status, "SERVER_ERROR");
|
|
46
|
+
}
|
|
47
|
+
return new ChronovaApiError(`Chronova API error: ${status} ${statusText}`, status, "API_ERROR");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function mapNetworkError(error, url) {
|
|
51
|
+
return new ChronovaApiError(`Cannot connect to Chronova at ${url}. Check CHRONOVA_API_URL configuration.`, 0, "CONNECTION_ERROR");
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,UAAU,CAAS;IACnB,IAAI,CAAS;IACb,UAAU,CAAU;IAEpB,YAAY,OAAe,EAAE,UAAkB,EAAE,IAAY,EAAE,UAAmB;QAChF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAkB,EAAE,GAAW;IAClE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IAEvC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,GAAG;YACN,OAAO,IAAI,gBAAgB,CACzB,sFAAsF,EACtF,GAAG,EACH,cAAc,CACf,CAAC;QAEJ,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,IAAI,UAA8B,CAAC;YACnC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7D,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,UAAU,GAAG,MAAM,CAAC;gBACtB,CAAC;YACH,CAAC;YACD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBAC9D,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;oBACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;wBAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;wBACzE,UAAU,GAAG,SAAS,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,UAAU,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,OAAO,IAAI,gBAAgB,CACzB,mCAAmC,MAAM,EAAE,EAC3C,GAAG,EACH,cAAc,EACd,UAAU,CACX,CAAC;QACJ,CAAC;QAED,KAAK,GAAG;YACN,OAAO,IAAI,gBAAgB,CACzB,mDAAmD,EACnD,GAAG,EACH,WAAW,CACZ,CAAC;QAEJ;YACE,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;gBAClB,OAAO,IAAI,gBAAgB,CACzB,0BAA0B,UAAU,2BAA2B,EAC/D,MAAM,EACN,cAAc,CACf,CAAC;YACJ,CAAC;YAED,OAAO,IAAI,gBAAgB,CACzB,uBAAuB,MAAM,IAAI,UAAU,EAAE,EAC7C,MAAM,EACN,WAAW,CACZ,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,GAAW;IACzD,OAAO,IAAI,gBAAgB,CACzB,iCAAiC,GAAG,yCAAyC,EAC7E,CAAC,EACD,kBAAkB,CACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export interface ChronovaUser {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
email: string;
|
|
5
|
+
avatar_url: string | null;
|
|
6
|
+
subscription: {
|
|
7
|
+
plan: string;
|
|
8
|
+
status: string;
|
|
9
|
+
};
|
|
10
|
+
github_connected: boolean;
|
|
11
|
+
organizations: Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
role: string;
|
|
15
|
+
}>;
|
|
16
|
+
created_at: string;
|
|
17
|
+
modified_at: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ChronovaStatsRange {
|
|
20
|
+
range: string;
|
|
21
|
+
total_seconds: number;
|
|
22
|
+
languages: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
total_seconds: number;
|
|
25
|
+
percent: number;
|
|
26
|
+
}>;
|
|
27
|
+
projects: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
total_seconds: number;
|
|
30
|
+
percent: number;
|
|
31
|
+
}>;
|
|
32
|
+
editors: Array<{
|
|
33
|
+
name: string;
|
|
34
|
+
total_seconds: number;
|
|
35
|
+
percent: number;
|
|
36
|
+
}>;
|
|
37
|
+
operating_systems: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
total_seconds: number;
|
|
40
|
+
percent: number;
|
|
41
|
+
}>;
|
|
42
|
+
daily_stats: Array<{
|
|
43
|
+
date: string;
|
|
44
|
+
total_seconds: number;
|
|
45
|
+
}>;
|
|
46
|
+
hourly_stats: Array<{
|
|
47
|
+
hour: number;
|
|
48
|
+
total_seconds: number;
|
|
49
|
+
}>;
|
|
50
|
+
best_day: {
|
|
51
|
+
date: string;
|
|
52
|
+
total_seconds: number;
|
|
53
|
+
} | null;
|
|
54
|
+
start: string;
|
|
55
|
+
end: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ChronovaHeartbeat {
|
|
58
|
+
id: string;
|
|
59
|
+
time: string;
|
|
60
|
+
type: string;
|
|
61
|
+
project: string | null;
|
|
62
|
+
language: string | null;
|
|
63
|
+
editor: string | null;
|
|
64
|
+
operating_system: string | null;
|
|
65
|
+
machine: string | null;
|
|
66
|
+
branch: string | null;
|
|
67
|
+
created_at: string;
|
|
68
|
+
}
|
|
69
|
+
export interface ChronovaHeartbeatResponse {
|
|
70
|
+
heartbeats: ChronovaHeartbeat[];
|
|
71
|
+
total: number;
|
|
72
|
+
page: number;
|
|
73
|
+
per_page: number;
|
|
74
|
+
total_pages: number;
|
|
75
|
+
}
|
|
76
|
+
export interface ChronovaAiAnalytics {
|
|
77
|
+
adoptionTimeline: Array<{
|
|
78
|
+
date: string;
|
|
79
|
+
aiSeconds: number;
|
|
80
|
+
manualSeconds: number;
|
|
81
|
+
}>;
|
|
82
|
+
contributionShare: {
|
|
83
|
+
aiPercent: number;
|
|
84
|
+
manualPercent: number;
|
|
85
|
+
aiHours: number;
|
|
86
|
+
manualHours: number;
|
|
87
|
+
};
|
|
88
|
+
comparison: {
|
|
89
|
+
withAi: {
|
|
90
|
+
totalSeconds: number;
|
|
91
|
+
avgDaily: number;
|
|
92
|
+
};
|
|
93
|
+
withoutAi: {
|
|
94
|
+
totalSeconds: number;
|
|
95
|
+
avgDaily: number;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
languageMatrix: Array<{
|
|
99
|
+
language: string;
|
|
100
|
+
aiPercent: number;
|
|
101
|
+
manualPercent: number;
|
|
102
|
+
}>;
|
|
103
|
+
projectDependency: Array<{
|
|
104
|
+
project: string;
|
|
105
|
+
aiPercent: number;
|
|
106
|
+
manualPercent: number;
|
|
107
|
+
}>;
|
|
108
|
+
efficiencyTrend: Array<{
|
|
109
|
+
period: string;
|
|
110
|
+
productivity: number;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { type ChronovaConfig } from "./lib/config.js";
|
|
4
|
+
export declare function createApp(config?: ChronovaConfig): express.Express;
|
|
5
|
+
export declare function startServer(): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
6
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,OAAwC,MAAM,SAAS,CAAC;AAI/D,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAyBrE,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CA6DlE;AAED,wBAAgB,WAAW,8EA0B1B"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import cors from "cors";
|
|
3
|
+
import express from "express";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
6
|
+
import { ChronovaClient } from "./lib/chronova-client.js";
|
|
7
|
+
import { resolveConfig } from "./lib/config.js";
|
|
8
|
+
import { registerGetDeveloperContext } from "./tools/get-developer-context.js";
|
|
9
|
+
import { registerGetAiInsights } from "./tools/get-ai-insights.js";
|
|
10
|
+
import { registerGetProductivitySummary } from "./tools/get-productivity-summary.js";
|
|
11
|
+
import { registerGetRecentActivity } from "./tools/get-recent-activity.js";
|
|
12
|
+
const VERSION = "0.1.0";
|
|
13
|
+
function createMcpServer(config) {
|
|
14
|
+
const server = new McpServer({ name: "chronova-mcp", version: VERSION });
|
|
15
|
+
const chronova = new ChronovaClient(config.apiUrl, config.apiKey);
|
|
16
|
+
registerGetAiInsights(server, chronova);
|
|
17
|
+
registerGetDeveloperContext(server, chronova);
|
|
18
|
+
registerGetProductivitySummary(server, chronova);
|
|
19
|
+
registerGetRecentActivity(server, chronova);
|
|
20
|
+
return { server, chronova };
|
|
21
|
+
}
|
|
22
|
+
export function createApp(config) {
|
|
23
|
+
const resolvedConfig = config ?? resolveConfig();
|
|
24
|
+
const app = express();
|
|
25
|
+
app.use(cors());
|
|
26
|
+
app.use(express.json());
|
|
27
|
+
const sessions = new Map();
|
|
28
|
+
app.get("/health", (_req, res) => {
|
|
29
|
+
res.json({ status: "ok", version: VERSION });
|
|
30
|
+
});
|
|
31
|
+
async function handleMcpRequest(req, res) {
|
|
32
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
33
|
+
if (sessionId) {
|
|
34
|
+
const session = sessions.get(sessionId);
|
|
35
|
+
if (!session) {
|
|
36
|
+
res.status(400).json({
|
|
37
|
+
jsonrpc: "2.0",
|
|
38
|
+
error: { code: -32600, message: "Invalid or expired session ID" },
|
|
39
|
+
id: null,
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await session.transport.handleRequest(req, res, req.body);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const { server: mcpServer } = createMcpServer(resolvedConfig);
|
|
47
|
+
const transport = new StreamableHTTPServerTransport({
|
|
48
|
+
sessionIdGenerator: () => randomUUID(),
|
|
49
|
+
onsessioninitialized: (newSessionId) => {
|
|
50
|
+
sessions.set(newSessionId, { transport, server: mcpServer });
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
mcpServer.server.onclose = () => {
|
|
54
|
+
const sid = transport.sessionId;
|
|
55
|
+
if (sid && sessions.has(sid)) {
|
|
56
|
+
sessions.delete(sid);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
await mcpServer.connect(transport);
|
|
60
|
+
await transport.handleRequest(req, res, req.body);
|
|
61
|
+
}
|
|
62
|
+
app.post("/mcp", handleMcpRequest);
|
|
63
|
+
app.get("/mcp", handleMcpRequest);
|
|
64
|
+
app.delete("/mcp", handleMcpRequest);
|
|
65
|
+
return app;
|
|
66
|
+
}
|
|
67
|
+
export function startServer() {
|
|
68
|
+
const config = resolveConfig();
|
|
69
|
+
if (!config.apiKey) {
|
|
70
|
+
console.warn("Warning: No API key found. Set CHRONOVA_API_KEY env var, or add api_key to ~/.chronova.cfg or ~/.wakatime.cfg. API requests will fail.");
|
|
71
|
+
}
|
|
72
|
+
else if (config.configSource !== "env") {
|
|
73
|
+
console.log(`Using API key from ${config.configSource}`);
|
|
74
|
+
}
|
|
75
|
+
const app = createApp(config);
|
|
76
|
+
const httpServer = app.listen(config.port, () => {
|
|
77
|
+
console.log(`Chronova MCP server listening on port ${config.port}`);
|
|
78
|
+
});
|
|
79
|
+
async function shutdown() {
|
|
80
|
+
console.log("Shutting down...");
|
|
81
|
+
httpServer.close();
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
process.on("SIGTERM", shutdown);
|
|
85
|
+
process.on("SIGINT", shutdown);
|
|
86
|
+
return httpServer;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/stdio.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":""}
|
package/dist/stdio.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { ChronovaClient } from "./lib/chronova-client.js";
|
|
5
|
+
import { resolveConfig } from "./lib/config.js";
|
|
6
|
+
import { registerGetDeveloperContext } from "./tools/get-developer-context.js";
|
|
7
|
+
import { registerGetAiInsights } from "./tools/get-ai-insights.js";
|
|
8
|
+
import { registerGetProductivitySummary } from "./tools/get-productivity-summary.js";
|
|
9
|
+
import { registerGetRecentActivity } from "./tools/get-recent-activity.js";
|
|
10
|
+
const VERSION = "0.1.0";
|
|
11
|
+
async function main() {
|
|
12
|
+
const config = resolveConfig();
|
|
13
|
+
if (!config.apiKey) {
|
|
14
|
+
console.error("Error: No API key found. Set CHRONOVA_API_KEY env var, or add api_key to ~/.chronova.cfg or ~/.wakatime.cfg.");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const server = new McpServer({ name: "chronova-mcp", version: VERSION });
|
|
18
|
+
const chronova = new ChronovaClient(config.apiUrl, config.apiKey);
|
|
19
|
+
registerGetAiInsights(server, chronova);
|
|
20
|
+
registerGetDeveloperContext(server, chronova);
|
|
21
|
+
registerGetProductivitySummary(server, chronova);
|
|
22
|
+
registerGetRecentActivity(server, chronova);
|
|
23
|
+
const transport = new StdioServerTransport();
|
|
24
|
+
await server.connect(transport);
|
|
25
|
+
}
|
|
26
|
+
main().catch((error) => {
|
|
27
|
+
console.error("Fatal error:", error);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CACX,8GAA8G,CAC/G,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAElE,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,8BAA8B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjD,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ChronovaClient } from "../lib/chronova-client.js";
|
|
3
|
+
export declare function registerGetAiInsights(server: McpServer, chronova: ChronovaClient): void;
|
|
4
|
+
//# sourceMappingURL=get-ai-insights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-ai-insights.d.ts","sourceRoot":"","sources":["../../src/tools/get-ai-insights.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,cAAc,GACvB,IAAI,CAyDN"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChronovaApiError } from "../lib/errors.js";
|
|
3
|
+
export function registerGetAiInsights(server, chronova) {
|
|
4
|
+
server.registerTool("get_ai_insights", {
|
|
5
|
+
description: "Get AI-assisted coding analytics including adoption timeline (AI vs manual coding over time), contribution share (percentage of AI vs manual work), human vs AI comparison by language, project-level AI dependency, and efficiency trends.",
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
range: z
|
|
8
|
+
.enum([
|
|
9
|
+
"today",
|
|
10
|
+
"last_7_days",
|
|
11
|
+
"last_30_days",
|
|
12
|
+
"last_3_months",
|
|
13
|
+
"last_6_months",
|
|
14
|
+
"last_year",
|
|
15
|
+
"all_time",
|
|
16
|
+
])
|
|
17
|
+
.or(z.string().regex(/^\d{4}-\d{2}-\d{2}_to_\d{4}-\d{2}-\d{2}$/))
|
|
18
|
+
.describe('Time range for analytics. Named ranges (today, last_7_days, etc.) or custom date range (YYYY-MM-DD_to_YYYY-MM-DD).'),
|
|
19
|
+
}),
|
|
20
|
+
annotations: { readOnlyHint: true },
|
|
21
|
+
}, async ({ range }) => {
|
|
22
|
+
try {
|
|
23
|
+
const response = await chronova.get("users/current/analytics/ai", { range });
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{ type: "text", text: JSON.stringify(response.data, null, 2) },
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof ChronovaApiError) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text", text: error.message }],
|
|
34
|
+
isError: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
isError: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=get-ai-insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-ai-insights.js","sourceRoot":"","sources":["../../src/tools/get-ai-insights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,QAAwB;IAExB,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EACT,6OAA6O;QAC/O,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC;iBACL,IAAI,CAAC;gBACJ,OAAO;gBACP,aAAa;gBACb,cAAc;gBACd,eAAe;gBACf,eAAe;gBACf,WAAW;gBACX,UAAU;aACX,CAAC;iBACD,EAAE,CACD,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAC7D;iBACA,QAAQ,CACP,oHAAoH,CACrH;SACJ,CAAC;QACF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CACjC,4BAA4B,EAC5B,EAAE,KAAK,EAAE,CACV,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACxE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;gBACtC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBACzD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACpF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ChronovaClient } from "../lib/chronova-client.js";
|
|
3
|
+
export declare function registerGetDeveloperContext(server: McpServer, chronova: ChronovaClient): void;
|
|
4
|
+
//# sourceMappingURL=get-developer-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-developer-context.d.ts","sourceRoot":"","sources":["../../src/tools/get-developer-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,cAAc,GACvB,IAAI,CAsCN"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChronovaApiError } from "../lib/errors.js";
|
|
3
|
+
export function registerGetDeveloperContext(server, chronova) {
|
|
4
|
+
server.registerTool("get_developer_context", {
|
|
5
|
+
description: "Get the authenticated user's developer profile including coding statistics, subscription status, GitHub integration status, and organization memberships. No parameters required — uses the configured API key.",
|
|
6
|
+
inputSchema: z.object({}),
|
|
7
|
+
annotations: { readOnlyHint: true },
|
|
8
|
+
}, async () => {
|
|
9
|
+
try {
|
|
10
|
+
const response = await chronova.get("users/current");
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{ type: "text", text: JSON.stringify(response.data, null, 2) },
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof ChronovaApiError) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: "text", text: error.message }],
|
|
21
|
+
isError: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
isError: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=get-developer-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-developer-context.js","sourceRoot":"","sources":["../../src/tools/get-developer-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,UAAU,2BAA2B,CACzC,MAAiB,EACjB,QAAwB;IAExB,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,iNAAiN;QACnN,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CACjC,eAAe,CAChB,CAAC;YACF,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACxE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;gBACtC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBACzD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACpF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ChronovaClient } from "../lib/chronova-client.js";
|
|
3
|
+
export declare function registerGetProductivitySummary(server: McpServer, chronova: ChronovaClient): void;
|
|
4
|
+
//# sourceMappingURL=get-productivity-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-productivity-summary.d.ts","sourceRoot":"","sources":["../../src/tools/get-productivity-summary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,cAAc,GACvB,IAAI,CAgEN"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChronovaApiError } from "../lib/errors.js";
|
|
3
|
+
export function registerGetProductivitySummary(server, chronova) {
|
|
4
|
+
server.registerTool("get_productivity_summary", {
|
|
5
|
+
description: "Get aggregated coding productivity statistics for a time range. Returns total coding time, language breakdown, editor breakdown, and project breakdown.",
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
range: z
|
|
8
|
+
.enum([
|
|
9
|
+
"today",
|
|
10
|
+
"last_7_days",
|
|
11
|
+
"last_30_days",
|
|
12
|
+
"last_3_months",
|
|
13
|
+
"last_6_months",
|
|
14
|
+
"last_year",
|
|
15
|
+
"all_time",
|
|
16
|
+
])
|
|
17
|
+
.describe('Time range for statistics. Named ranges (today, last_7_days, etc.) or custom formats (YYYY for year, YYYY-MM for month, YYYY-MM-DD_to_YYYY-MM-DD for date range).'),
|
|
18
|
+
project: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Filter results to a specific project name"),
|
|
22
|
+
}),
|
|
23
|
+
annotations: { readOnlyHint: true },
|
|
24
|
+
}, async ({ range, project }) => {
|
|
25
|
+
try {
|
|
26
|
+
const path = `users/current/stats/${range}`;
|
|
27
|
+
const params = {};
|
|
28
|
+
if (project) {
|
|
29
|
+
params.project = project;
|
|
30
|
+
}
|
|
31
|
+
const response = await chronova.get(path, Object.keys(params).length > 0 ? params : undefined);
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{ type: "text", text: JSON.stringify(response.data, null, 2) },
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error instanceof ChronovaApiError) {
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: "text", text: error.message }],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
isError: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=get-productivity-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-productivity-summary.js","sourceRoot":"","sources":["../../src/tools/get-productivity-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,UAAU,8BAA8B,CAC5C,MAAiB,EACjB,QAAwB;IAExB,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,WAAW,EACT,yJAAyJ;QAC3J,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC;iBACL,IAAI,CAAC;gBACJ,OAAO;gBACP,aAAa;gBACb,cAAc;gBACd,eAAe;gBACf,eAAe;gBACf,WAAW;gBACX,UAAU;aACX,CAAC;iBACD,QAAQ,CACP,mKAAmK,CACpK;YACH,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,2CAA2C,CAAC;SACzD,CAAC;QACF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,uBAAuB,KAAK,EAAE,CAAC;YAC5C,MAAM,MAAM,GAA2B,EAAE,CAAC;YAC1C,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;YAC3B,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CACjC,IAAI,EACJ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CACpD,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACxE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;gBACtC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;oBACzD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACpF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ChronovaClient } from "../lib/chronova-client.js";
|
|
3
|
+
export declare function registerGetRecentActivity(server: McpServer, chronova: ChronovaClient): void;
|
|
4
|
+
//# sourceMappingURL=get-recent-activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-recent-activity.d.ts","sourceRoot":"","sources":["../../src/tools/get-recent-activity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,cAAc,GACvB,IAAI,CA0FN"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChronovaApiError } from "../lib/errors.js";
|
|
3
|
+
export function registerGetRecentActivity(server, chronova) {
|
|
4
|
+
server.registerTool("get_recent_activity", {
|
|
5
|
+
description: "Get recent coding heartbeats (activity events). Returns paginated results — use 'page' and 'per_page' parameters to navigate through large result sets. The response includes 'total' count and pagination metadata.",
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
date: z
|
|
8
|
+
.string()
|
|
9
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Filter by specific date (YYYY-MM-DD)"),
|
|
12
|
+
start: z
|
|
13
|
+
.string()
|
|
14
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Start date for range (YYYY-MM-DD)"),
|
|
17
|
+
end: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("End date for range (YYYY-MM-DD)"),
|
|
22
|
+
project: z
|
|
23
|
+
.string()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Filter by project name"),
|
|
26
|
+
language: z
|
|
27
|
+
.string()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Filter by programming language"),
|
|
30
|
+
editor: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Filter by editor/IDE name"),
|
|
34
|
+
page: z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.positive()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Page number for pagination (default: 1)"),
|
|
40
|
+
per_page: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.positive()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Results per page (default: 100, max: 100)"),
|
|
46
|
+
}),
|
|
47
|
+
annotations: { readOnlyHint: true },
|
|
48
|
+
}, async ({ date, start, end, project, language, editor, page, per_page }) => {
|
|
49
|
+
try {
|
|
50
|
+
const params = {};
|
|
51
|
+
if (date !== undefined)
|
|
52
|
+
params.date = date;
|
|
53
|
+
if (start !== undefined)
|
|
54
|
+
params.start = start;
|
|
55
|
+
if (end !== undefined)
|
|
56
|
+
params.end = end;
|
|
57
|
+
if (project !== undefined)
|
|
58
|
+
params.project = project;
|
|
59
|
+
if (language !== undefined)
|
|
60
|
+
params.language = language;
|
|
61
|
+
if (editor !== undefined)
|
|
62
|
+
params.editor = editor;
|
|
63
|
+
if (page !== undefined)
|
|
64
|
+
params.page = String(page);
|
|
65
|
+
if (per_page !== undefined)
|
|
66
|
+
params.per_page = String(per_page);
|
|
67
|
+
const response = await chronova.get("users/current/heartbeats", Object.keys(params).length > 0 ? params : undefined);
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{ type: "text", text: JSON.stringify(response, null, 2) },
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (error instanceof ChronovaApiError) {
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: "text", text: error.message }],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
isError: true,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=get-recent-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-recent-activity.js","sourceRoot":"","sources":["../../src/tools/get-recent-activity.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chronova/mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"private": false,
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc",
|
|
20
|
+
"prepublishOnly": "npm run build",
|
|
20
21
|
"start": "node dist/index.js",
|
|
21
22
|
"dev": "tsc --watch & node --watch dist/index.js",
|
|
22
23
|
"test": "vitest run",
|