@artyfacts/claude 1.3.8 → 1.3.10
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/chunk-3SYZHE4Q.mjs +979 -0
- package/dist/chunk-CB7WCSN4.mjs +808 -0
- package/dist/chunk-NGZ6RZMV.mjs +999 -0
- package/dist/chunk-U7NYTXMZ.mjs +950 -0
- package/dist/chunk-VGAUMCRW.mjs +998 -0
- package/dist/cli.js +251 -22
- package/dist/cli.mjs +56 -16
- package/dist/index.d.mts +77 -2
- package/dist/index.d.ts +77 -2
- package/dist/index.js +195 -1
- package/dist/index.mjs +5 -1
- package/package.json +1 -1
- package/src/cli.ts +62 -16
- package/src/index.ts +14 -0
- package/src/listener.ts +18 -1
- package/src/mcp.ts +314 -0
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_commander = require("commander");
|
|
28
|
-
var
|
|
28
|
+
var import_child_process3 = require("child_process");
|
|
29
29
|
|
|
30
30
|
// src/auth.ts
|
|
31
31
|
var fs = __toESM(require("fs"));
|
|
@@ -621,7 +621,9 @@ var EVENT_TYPES = [
|
|
|
621
621
|
"task_assigned",
|
|
622
622
|
"task_unblocked",
|
|
623
623
|
"blocker_resolved",
|
|
624
|
-
"notification"
|
|
624
|
+
"notification",
|
|
625
|
+
"mcp_connect_request",
|
|
626
|
+
"connection_status"
|
|
625
627
|
];
|
|
626
628
|
var ArtyfactsListener = class {
|
|
627
629
|
config;
|
|
@@ -820,12 +822,200 @@ function createListener(config) {
|
|
|
820
822
|
return new ArtyfactsListener(config);
|
|
821
823
|
}
|
|
822
824
|
|
|
825
|
+
// src/mcp.ts
|
|
826
|
+
var import_child_process2 = require("child_process");
|
|
827
|
+
var DEFAULT_BASE_URL3 = "https://artyfacts.dev/api/v1";
|
|
828
|
+
var OAUTH_MCP_SERVERS = {
|
|
829
|
+
supabase: {
|
|
830
|
+
url: "https://mcp.supabase.com/mcp",
|
|
831
|
+
name: "supabase"
|
|
832
|
+
},
|
|
833
|
+
figma: {
|
|
834
|
+
url: "https://mcp.figma.com/mcp",
|
|
835
|
+
name: "figma"
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
var CREDENTIAL_MCP_CONFIGS = {
|
|
839
|
+
postgres: (config) => ({
|
|
840
|
+
command: "npx",
|
|
841
|
+
args: ["-y", "@modelcontextprotocol/server-postgres", config.connection_string]
|
|
842
|
+
}),
|
|
843
|
+
github: (config) => ({
|
|
844
|
+
command: "npx",
|
|
845
|
+
args: ["-y", "@modelcontextprotocol/server-github"],
|
|
846
|
+
env: {
|
|
847
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: config.api_key
|
|
848
|
+
}
|
|
849
|
+
}),
|
|
850
|
+
filesystem: (config) => ({
|
|
851
|
+
command: "npx",
|
|
852
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", ...config.paths || []]
|
|
853
|
+
})
|
|
854
|
+
};
|
|
855
|
+
function addMcpServer(options) {
|
|
856
|
+
const { name, transport, url, command, args = [], env = {}, scope = "user" } = options;
|
|
857
|
+
const cliArgs = ["mcp", "add", "-s", scope, "-t", transport];
|
|
858
|
+
for (const [key, value] of Object.entries(env)) {
|
|
859
|
+
cliArgs.push("-e", `${key}=${value}`);
|
|
860
|
+
}
|
|
861
|
+
cliArgs.push(name);
|
|
862
|
+
if (transport === "http" && url) {
|
|
863
|
+
cliArgs.push(url);
|
|
864
|
+
} else if (transport === "stdio" && command) {
|
|
865
|
+
cliArgs.push("--", command, ...args);
|
|
866
|
+
} else {
|
|
867
|
+
return { success: false, error: "Invalid configuration: missing url or command" };
|
|
868
|
+
}
|
|
869
|
+
console.log(`[MCP] Running: claude ${cliArgs.join(" ")}`);
|
|
870
|
+
const result = (0, import_child_process2.spawnSync)("claude", cliArgs, {
|
|
871
|
+
encoding: "utf-8",
|
|
872
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
873
|
+
});
|
|
874
|
+
if (result.status === 0) {
|
|
875
|
+
return { success: true };
|
|
876
|
+
} else {
|
|
877
|
+
return {
|
|
878
|
+
success: false,
|
|
879
|
+
error: result.stderr || result.stdout || `Exit code ${result.status}`
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
var McpHandler = class {
|
|
884
|
+
config;
|
|
885
|
+
constructor(config) {
|
|
886
|
+
this.config = {
|
|
887
|
+
...config,
|
|
888
|
+
baseUrl: config.baseUrl || DEFAULT_BASE_URL3
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Handle an MCP connect request event
|
|
893
|
+
* Uses `claude mcp add` to configure the server dynamically
|
|
894
|
+
*/
|
|
895
|
+
async handleConnectRequest(event) {
|
|
896
|
+
const { connection_id, platform, config: mcpConfig } = event.data;
|
|
897
|
+
try {
|
|
898
|
+
const serverName = mcpConfig?.server_name || platform;
|
|
899
|
+
const oauthServer = OAUTH_MCP_SERVERS[platform];
|
|
900
|
+
if (oauthServer) {
|
|
901
|
+
const result = addMcpServer({
|
|
902
|
+
name: serverName,
|
|
903
|
+
transport: "http",
|
|
904
|
+
url: oauthServer.url
|
|
905
|
+
});
|
|
906
|
+
if (!result.success) {
|
|
907
|
+
throw new Error(`Failed to add ${platform} MCP: ${result.error}`);
|
|
908
|
+
}
|
|
909
|
+
console.log(`[MCP] Added ${serverName} \u2192 ${oauthServer.url}`);
|
|
910
|
+
console.log(`[MCP] OAuth will prompt when you use ${platform} tools`);
|
|
911
|
+
} else {
|
|
912
|
+
const configBuilder = CREDENTIAL_MCP_CONFIGS[platform];
|
|
913
|
+
if (!configBuilder) {
|
|
914
|
+
throw new Error(`Unsupported MCP platform: ${platform}. Supported: ${[...Object.keys(OAUTH_MCP_SERVERS), ...Object.keys(CREDENTIAL_MCP_CONFIGS)].join(", ")}`);
|
|
915
|
+
}
|
|
916
|
+
if (!mcpConfig) {
|
|
917
|
+
throw new Error(`Platform ${platform} requires configuration (connection_string or api_key)`);
|
|
918
|
+
}
|
|
919
|
+
const serverConfig = configBuilder(mcpConfig);
|
|
920
|
+
const result = addMcpServer({
|
|
921
|
+
name: serverName,
|
|
922
|
+
transport: "stdio",
|
|
923
|
+
command: serverConfig.command,
|
|
924
|
+
args: serverConfig.args,
|
|
925
|
+
env: serverConfig.env
|
|
926
|
+
});
|
|
927
|
+
if (!result.success) {
|
|
928
|
+
throw new Error(`Failed to add ${platform} MCP: ${result.error}`);
|
|
929
|
+
}
|
|
930
|
+
console.log(`[MCP] Added ${serverName} for ${platform}`);
|
|
931
|
+
}
|
|
932
|
+
await this.updateConnectionStatus(connection_id, {
|
|
933
|
+
status: "active",
|
|
934
|
+
mcp_configured: true
|
|
935
|
+
});
|
|
936
|
+
this.config.onConfigured?.(connection_id, platform);
|
|
937
|
+
} catch (err) {
|
|
938
|
+
console.error(`[MCP] Failed to configure ${platform}:`, err);
|
|
939
|
+
await this.updateConnectionStatus(connection_id, {
|
|
940
|
+
status: "error",
|
|
941
|
+
mcp_configured: false,
|
|
942
|
+
error_message: err.message
|
|
943
|
+
});
|
|
944
|
+
this.config.onError?.(err, connection_id);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Check if a platform supports OAuth (no credentials needed)
|
|
949
|
+
*/
|
|
950
|
+
static supportsOAuth(platform) {
|
|
951
|
+
return platform in OAUTH_MCP_SERVERS;
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Get list of platforms with OAuth support
|
|
955
|
+
*/
|
|
956
|
+
static getOAuthPlatforms() {
|
|
957
|
+
return Object.keys(OAUTH_MCP_SERVERS);
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Update connection status in Artyfacts
|
|
961
|
+
*/
|
|
962
|
+
async updateConnectionStatus(connectionId, update) {
|
|
963
|
+
try {
|
|
964
|
+
const response = await fetch(`${this.config.baseUrl}/connections/${connectionId}`, {
|
|
965
|
+
method: "PATCH",
|
|
966
|
+
headers: {
|
|
967
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
968
|
+
"Content-Type": "application/json"
|
|
969
|
+
},
|
|
970
|
+
body: JSON.stringify(update)
|
|
971
|
+
});
|
|
972
|
+
if (!response.ok) {
|
|
973
|
+
console.error(`[MCP] Failed to update connection status: ${response.status}`);
|
|
974
|
+
}
|
|
975
|
+
} catch (err) {
|
|
976
|
+
console.error("[MCP] Failed to update connection status:", err);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* List configured MCP servers using `claude mcp list`
|
|
981
|
+
*/
|
|
982
|
+
listServers() {
|
|
983
|
+
const result = (0, import_child_process2.spawnSync)("claude", ["mcp", "list"], {
|
|
984
|
+
encoding: "utf-8",
|
|
985
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
986
|
+
});
|
|
987
|
+
if (result.status === 0 && result.stdout) {
|
|
988
|
+
return result.stdout.trim().split("\n").filter(Boolean);
|
|
989
|
+
}
|
|
990
|
+
return [];
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Remove an MCP server using `claude mcp remove`
|
|
994
|
+
*/
|
|
995
|
+
removeServer(serverName) {
|
|
996
|
+
const result = (0, import_child_process2.spawnSync)("claude", ["mcp", "remove", serverName], {
|
|
997
|
+
encoding: "utf-8",
|
|
998
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
999
|
+
});
|
|
1000
|
+
if (result.status === 0) {
|
|
1001
|
+
console.log(`[MCP] Removed server: ${serverName}`);
|
|
1002
|
+
return true;
|
|
1003
|
+
} else {
|
|
1004
|
+
console.error(`[MCP] Failed to remove ${serverName}: ${result.stderr || result.stdout}`);
|
|
1005
|
+
return false;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
function createMcpHandler(config) {
|
|
1010
|
+
return new McpHandler(config);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
823
1013
|
// src/cli.ts
|
|
824
1014
|
var VERSION = "0.1.0";
|
|
825
|
-
var
|
|
1015
|
+
var DEFAULT_BASE_URL4 = "https://artyfacts.dev/api/v1";
|
|
826
1016
|
function isMcpConfigured() {
|
|
827
1017
|
try {
|
|
828
|
-
const result = (0,
|
|
1018
|
+
const result = (0, import_child_process3.spawnSync)("claude", ["mcp", "get", "artyfacts"], {
|
|
829
1019
|
encoding: "utf-8",
|
|
830
1020
|
stdio: ["pipe", "pipe", "pipe"]
|
|
831
1021
|
});
|
|
@@ -837,7 +1027,7 @@ function isMcpConfigured() {
|
|
|
837
1027
|
function configureMcp(apiKey, baseUrl) {
|
|
838
1028
|
console.log("\u{1F527} Configuring Artyfacts tools for Claude Code...");
|
|
839
1029
|
try {
|
|
840
|
-
const result = (0,
|
|
1030
|
+
const result = (0, import_child_process3.spawnSync)("claude", [
|
|
841
1031
|
"mcp",
|
|
842
1032
|
"add",
|
|
843
1033
|
"artyfacts",
|
|
@@ -878,10 +1068,10 @@ function ensureMcpConfigured(apiKey, baseUrl) {
|
|
|
878
1068
|
}
|
|
879
1069
|
var program = new import_commander.Command();
|
|
880
1070
|
program.name("artyfacts-claude").description("Claude adapter for Artyfacts - Execute tasks using Claude API").version(VERSION);
|
|
881
|
-
program.command("run", { isDefault: true }).description("Start listening for and executing tasks").option("--base-url <url>", "Artyfacts API base URL",
|
|
1071
|
+
program.command("run", { isDefault: true }).description("Start listening for and executing tasks").option("--base-url <url>", "Artyfacts API base URL", DEFAULT_BASE_URL4).option("--dry-run", "Print tasks but do not execute", false).action(async (options) => {
|
|
882
1072
|
await runAgent(options);
|
|
883
1073
|
});
|
|
884
|
-
program.command("login").description("Authenticate with Artyfacts").option("--manual", "Enter credentials manually instead of device auth").option("--base-url <url>", "Artyfacts API base URL",
|
|
1074
|
+
program.command("login").description("Authenticate with Artyfacts").option("--manual", "Enter credentials manually instead of device auth").option("--base-url <url>", "Artyfacts API base URL", DEFAULT_BASE_URL4).action(async (options) => {
|
|
885
1075
|
try {
|
|
886
1076
|
if (options.manual) {
|
|
887
1077
|
await promptForApiKey();
|
|
@@ -990,14 +1180,21 @@ async function checkAndClaimTasks(baseUrl, apiKey, agentId, activeTasks, executo
|
|
|
990
1180
|
priority: task.priority
|
|
991
1181
|
});
|
|
992
1182
|
if (result.success) {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1183
|
+
try {
|
|
1184
|
+
await completeTask({
|
|
1185
|
+
baseUrl,
|
|
1186
|
+
apiKey,
|
|
1187
|
+
taskId: taskUuid,
|
|
1188
|
+
// Use UUID instead of section_id
|
|
1189
|
+
output: result.output,
|
|
1190
|
+
summary: result.summary
|
|
1191
|
+
});
|
|
1192
|
+
} catch (err) {
|
|
1193
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1194
|
+
if (!errMsg.includes("already complete")) {
|
|
1195
|
+
throw err;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1001
1198
|
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
1002
1199
|
} else {
|
|
1003
1200
|
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
@@ -1083,6 +1280,24 @@ async function runAgent(options) {
|
|
|
1083
1280
|
}
|
|
1084
1281
|
});
|
|
1085
1282
|
const activeTasks = /* @__PURE__ */ new Set();
|
|
1283
|
+
const mcpHandler = createMcpHandler({
|
|
1284
|
+
apiKey: credentials.apiKey,
|
|
1285
|
+
baseUrl: options.baseUrl,
|
|
1286
|
+
onConfigured: (connectionId, platform) => {
|
|
1287
|
+
console.log(`
|
|
1288
|
+
\u{1F527} [MCP] Configured ${platform} connection: ${connectionId}`);
|
|
1289
|
+
console.log(" \u26A0\uFE0F Restart Claude Desktop to use the new MCP server");
|
|
1290
|
+
},
|
|
1291
|
+
onError: (error, connectionId) => {
|
|
1292
|
+
console.error(`
|
|
1293
|
+
\u274C [MCP] Failed to configure connection ${connectionId}:`, error.message);
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
listener.on("mcp_connect_request", async (event) => {
|
|
1297
|
+
console.log(`
|
|
1298
|
+
\u{1F517} [MCP] Connection request for ${event.data.platform}`);
|
|
1299
|
+
await mcpHandler.handleConnectRequest(event);
|
|
1300
|
+
});
|
|
1086
1301
|
listener.on("task_assigned", async (event) => {
|
|
1087
1302
|
const task = event.data;
|
|
1088
1303
|
if (activeTasks.has(task.taskId)) {
|
|
@@ -1110,13 +1325,20 @@ async function runAgent(options) {
|
|
|
1110
1325
|
};
|
|
1111
1326
|
const result = await executor.execute(taskContext);
|
|
1112
1327
|
if (result.success) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1328
|
+
try {
|
|
1329
|
+
await completeTask({
|
|
1330
|
+
baseUrl: options.baseUrl,
|
|
1331
|
+
apiKey: credentials.apiKey,
|
|
1332
|
+
taskId: task.taskId,
|
|
1333
|
+
output: result.output,
|
|
1334
|
+
summary: result.summary
|
|
1335
|
+
});
|
|
1336
|
+
} catch (err) {
|
|
1337
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1338
|
+
if (!errMsg.includes("already complete")) {
|
|
1339
|
+
throw err;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1120
1342
|
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
1121
1343
|
} else {
|
|
1122
1344
|
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
@@ -1134,8 +1356,15 @@ async function runAgent(options) {
|
|
|
1134
1356
|
}
|
|
1135
1357
|
});
|
|
1136
1358
|
listener.connect();
|
|
1359
|
+
const POLL_INTERVAL_MS = 3e4;
|
|
1360
|
+
const pollInterval = setInterval(() => {
|
|
1361
|
+
if (!options.dryRun) {
|
|
1362
|
+
checkAndClaimTasks(options.baseUrl, credentials.apiKey, credentials.agentId, activeTasks, executor, options.dryRun);
|
|
1363
|
+
}
|
|
1364
|
+
}, POLL_INTERVAL_MS);
|
|
1137
1365
|
const shutdown = () => {
|
|
1138
1366
|
console.log("\n\u{1F44B} Disconnecting...");
|
|
1367
|
+
clearInterval(pollInterval);
|
|
1139
1368
|
listener.disconnect();
|
|
1140
1369
|
process.exit(0);
|
|
1141
1370
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -3,10 +3,11 @@ import {
|
|
|
3
3
|
clearCredentials,
|
|
4
4
|
createExecutor,
|
|
5
5
|
createListener,
|
|
6
|
+
createMcpHandler,
|
|
6
7
|
getCredentials,
|
|
7
8
|
loadCredentials,
|
|
8
9
|
promptForApiKey
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-VGAUMCRW.mjs";
|
|
10
11
|
|
|
11
12
|
// src/cli.ts
|
|
12
13
|
import { Command } from "commander";
|
|
@@ -180,14 +181,21 @@ async function checkAndClaimTasks(baseUrl, apiKey, agentId, activeTasks, executo
|
|
|
180
181
|
priority: task.priority
|
|
181
182
|
});
|
|
182
183
|
if (result.success) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
try {
|
|
185
|
+
await completeTask({
|
|
186
|
+
baseUrl,
|
|
187
|
+
apiKey,
|
|
188
|
+
taskId: taskUuid,
|
|
189
|
+
// Use UUID instead of section_id
|
|
190
|
+
output: result.output,
|
|
191
|
+
summary: result.summary
|
|
192
|
+
});
|
|
193
|
+
} catch (err) {
|
|
194
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
195
|
+
if (!errMsg.includes("already complete")) {
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
191
199
|
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
192
200
|
} else {
|
|
193
201
|
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
@@ -273,6 +281,24 @@ async function runAgent(options) {
|
|
|
273
281
|
}
|
|
274
282
|
});
|
|
275
283
|
const activeTasks = /* @__PURE__ */ new Set();
|
|
284
|
+
const mcpHandler = createMcpHandler({
|
|
285
|
+
apiKey: credentials.apiKey,
|
|
286
|
+
baseUrl: options.baseUrl,
|
|
287
|
+
onConfigured: (connectionId, platform) => {
|
|
288
|
+
console.log(`
|
|
289
|
+
\u{1F527} [MCP] Configured ${platform} connection: ${connectionId}`);
|
|
290
|
+
console.log(" \u26A0\uFE0F Restart Claude Desktop to use the new MCP server");
|
|
291
|
+
},
|
|
292
|
+
onError: (error, connectionId) => {
|
|
293
|
+
console.error(`
|
|
294
|
+
\u274C [MCP] Failed to configure connection ${connectionId}:`, error.message);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
listener.on("mcp_connect_request", async (event) => {
|
|
298
|
+
console.log(`
|
|
299
|
+
\u{1F517} [MCP] Connection request for ${event.data.platform}`);
|
|
300
|
+
await mcpHandler.handleConnectRequest(event);
|
|
301
|
+
});
|
|
276
302
|
listener.on("task_assigned", async (event) => {
|
|
277
303
|
const task = event.data;
|
|
278
304
|
if (activeTasks.has(task.taskId)) {
|
|
@@ -300,13 +326,20 @@ async function runAgent(options) {
|
|
|
300
326
|
};
|
|
301
327
|
const result = await executor.execute(taskContext);
|
|
302
328
|
if (result.success) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
329
|
+
try {
|
|
330
|
+
await completeTask({
|
|
331
|
+
baseUrl: options.baseUrl,
|
|
332
|
+
apiKey: credentials.apiKey,
|
|
333
|
+
taskId: task.taskId,
|
|
334
|
+
output: result.output,
|
|
335
|
+
summary: result.summary
|
|
336
|
+
});
|
|
337
|
+
} catch (err) {
|
|
338
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
339
|
+
if (!errMsg.includes("already complete")) {
|
|
340
|
+
throw err;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
310
343
|
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
311
344
|
} else {
|
|
312
345
|
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
@@ -324,8 +357,15 @@ async function runAgent(options) {
|
|
|
324
357
|
}
|
|
325
358
|
});
|
|
326
359
|
listener.connect();
|
|
360
|
+
const POLL_INTERVAL_MS = 3e4;
|
|
361
|
+
const pollInterval = setInterval(() => {
|
|
362
|
+
if (!options.dryRun) {
|
|
363
|
+
checkAndClaimTasks(options.baseUrl, credentials.apiKey, credentials.agentId, activeTasks, executor, options.dryRun);
|
|
364
|
+
}
|
|
365
|
+
}, POLL_INTERVAL_MS);
|
|
327
366
|
const shutdown = () => {
|
|
328
367
|
console.log("\n\u{1F44B} Disconnecting...");
|
|
368
|
+
clearInterval(pollInterval);
|
|
329
369
|
listener.disconnect();
|
|
330
370
|
process.exit(0);
|
|
331
371
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -163,6 +163,20 @@ interface TaskAssignedEvent {
|
|
|
163
163
|
assignedAt: string;
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
|
+
interface McpConnectRequestEvent {
|
|
167
|
+
type: 'mcp_connect_request';
|
|
168
|
+
timestamp: string;
|
|
169
|
+
data: {
|
|
170
|
+
connection_id: string;
|
|
171
|
+
platform: string;
|
|
172
|
+
config: {
|
|
173
|
+
server_name?: string;
|
|
174
|
+
connection_string?: string;
|
|
175
|
+
api_key?: string;
|
|
176
|
+
[key: string]: unknown;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
|
166
180
|
interface HeartbeatEvent {
|
|
167
181
|
type: 'heartbeat';
|
|
168
182
|
timestamp: string;
|
|
@@ -174,7 +188,7 @@ interface ConnectedEvent {
|
|
|
174
188
|
agentId: string;
|
|
175
189
|
};
|
|
176
190
|
}
|
|
177
|
-
type ArtyfactsEvent = TaskAssignedEvent | HeartbeatEvent | ConnectedEvent | {
|
|
191
|
+
type ArtyfactsEvent = TaskAssignedEvent | HeartbeatEvent | ConnectedEvent | McpConnectRequestEvent | {
|
|
178
192
|
type: string;
|
|
179
193
|
timestamp: string;
|
|
180
194
|
data?: Record<string, unknown>;
|
|
@@ -534,4 +548,65 @@ declare class ClaudeExecutorWithTools {
|
|
|
534
548
|
*/
|
|
535
549
|
declare function createExecutorWithTools(config: ExecutorConfig): ClaudeExecutorWithTools;
|
|
536
550
|
|
|
537
|
-
|
|
551
|
+
/**
|
|
552
|
+
* MCP Connection Handler
|
|
553
|
+
*
|
|
554
|
+
* Handles mcp_connect_request events from Artyfacts and configures
|
|
555
|
+
* MCP servers for the Claude adapter using `claude mcp add`.
|
|
556
|
+
*
|
|
557
|
+
* @module mcp
|
|
558
|
+
*/
|
|
559
|
+
|
|
560
|
+
interface McpServerConfig {
|
|
561
|
+
command: string;
|
|
562
|
+
args?: string[];
|
|
563
|
+
env?: Record<string, string>;
|
|
564
|
+
}
|
|
565
|
+
interface ClaudeSettingsJson {
|
|
566
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
567
|
+
}
|
|
568
|
+
interface McpHandlerConfig {
|
|
569
|
+
/** Artyfacts API key for status updates */
|
|
570
|
+
apiKey: string;
|
|
571
|
+
/** Base URL for Artyfacts API */
|
|
572
|
+
baseUrl?: string;
|
|
573
|
+
/** Callback when MCP server is configured */
|
|
574
|
+
onConfigured?: (connectionId: string, platform: string) => void;
|
|
575
|
+
/** Callback on error */
|
|
576
|
+
onError?: (error: Error, connectionId: string) => void;
|
|
577
|
+
}
|
|
578
|
+
declare class McpHandler {
|
|
579
|
+
private config;
|
|
580
|
+
constructor(config: McpHandlerConfig);
|
|
581
|
+
/**
|
|
582
|
+
* Handle an MCP connect request event
|
|
583
|
+
* Uses `claude mcp add` to configure the server dynamically
|
|
584
|
+
*/
|
|
585
|
+
handleConnectRequest(event: McpConnectRequestEvent): Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Check if a platform supports OAuth (no credentials needed)
|
|
588
|
+
*/
|
|
589
|
+
static supportsOAuth(platform: string): boolean;
|
|
590
|
+
/**
|
|
591
|
+
* Get list of platforms with OAuth support
|
|
592
|
+
*/
|
|
593
|
+
static getOAuthPlatforms(): string[];
|
|
594
|
+
/**
|
|
595
|
+
* Update connection status in Artyfacts
|
|
596
|
+
*/
|
|
597
|
+
private updateConnectionStatus;
|
|
598
|
+
/**
|
|
599
|
+
* List configured MCP servers using `claude mcp list`
|
|
600
|
+
*/
|
|
601
|
+
listServers(): string[];
|
|
602
|
+
/**
|
|
603
|
+
* Remove an MCP server using `claude mcp remove`
|
|
604
|
+
*/
|
|
605
|
+
removeServer(serverName: string): boolean;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Create an MCP handler instance
|
|
609
|
+
*/
|
|
610
|
+
declare function createMcpHandler(config: McpHandlerConfig): McpHandler;
|
|
611
|
+
|
|
612
|
+
export { type ApiClient, type ArtifactContext, type ArtyfactsEvent, ArtyfactsListener, ClaudeExecutor, ClaudeExecutorWithTools, type ClaudeSettingsJson, type ConnectedEvent, type ConnectionState, ContextFetcher, type ContextFetcherConfig, type Credentials, type DeviceAuthResponse, type EventCallback, type ExecutionResult$1 as ExecutionResult, type ExecutorConfig$1 as ExecutorConfig, type ExecutorConfig as ExecutorWithToolsConfig, type HeartbeatEvent, type ListenerConfig, type McpConnectRequestEvent, McpHandler, type McpHandlerConfig, type McpServerConfig, type OrganizationContext, type ProjectContext, type SectionContext, type TaskAssignedEvent, type TaskContext$1 as TaskContext, type TaskFullContext, type TokenResponse, type ToolCall, type ToolCallResult, type ToolHandler, type ToolResult, type ToolSchema, buildPromptWithContext, clearCredentials, createApiClient, createContextFetcher, createExecutor, createExecutorWithTools, createListener, createMcpHandler, executeTool, getAllToolSchemas, getCredentials, getRequiredPermission, getToolSchema, getToolsForPermissions, isToolAllowed, loadCredentials, permissionToTools, promptForApiKey, runDeviceAuth, saveCredentials, handlers as toolHandlers };
|
package/dist/index.d.ts
CHANGED
|
@@ -163,6 +163,20 @@ interface TaskAssignedEvent {
|
|
|
163
163
|
assignedAt: string;
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
|
+
interface McpConnectRequestEvent {
|
|
167
|
+
type: 'mcp_connect_request';
|
|
168
|
+
timestamp: string;
|
|
169
|
+
data: {
|
|
170
|
+
connection_id: string;
|
|
171
|
+
platform: string;
|
|
172
|
+
config: {
|
|
173
|
+
server_name?: string;
|
|
174
|
+
connection_string?: string;
|
|
175
|
+
api_key?: string;
|
|
176
|
+
[key: string]: unknown;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
|
166
180
|
interface HeartbeatEvent {
|
|
167
181
|
type: 'heartbeat';
|
|
168
182
|
timestamp: string;
|
|
@@ -174,7 +188,7 @@ interface ConnectedEvent {
|
|
|
174
188
|
agentId: string;
|
|
175
189
|
};
|
|
176
190
|
}
|
|
177
|
-
type ArtyfactsEvent = TaskAssignedEvent | HeartbeatEvent | ConnectedEvent | {
|
|
191
|
+
type ArtyfactsEvent = TaskAssignedEvent | HeartbeatEvent | ConnectedEvent | McpConnectRequestEvent | {
|
|
178
192
|
type: string;
|
|
179
193
|
timestamp: string;
|
|
180
194
|
data?: Record<string, unknown>;
|
|
@@ -534,4 +548,65 @@ declare class ClaudeExecutorWithTools {
|
|
|
534
548
|
*/
|
|
535
549
|
declare function createExecutorWithTools(config: ExecutorConfig): ClaudeExecutorWithTools;
|
|
536
550
|
|
|
537
|
-
|
|
551
|
+
/**
|
|
552
|
+
* MCP Connection Handler
|
|
553
|
+
*
|
|
554
|
+
* Handles mcp_connect_request events from Artyfacts and configures
|
|
555
|
+
* MCP servers for the Claude adapter using `claude mcp add`.
|
|
556
|
+
*
|
|
557
|
+
* @module mcp
|
|
558
|
+
*/
|
|
559
|
+
|
|
560
|
+
interface McpServerConfig {
|
|
561
|
+
command: string;
|
|
562
|
+
args?: string[];
|
|
563
|
+
env?: Record<string, string>;
|
|
564
|
+
}
|
|
565
|
+
interface ClaudeSettingsJson {
|
|
566
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
567
|
+
}
|
|
568
|
+
interface McpHandlerConfig {
|
|
569
|
+
/** Artyfacts API key for status updates */
|
|
570
|
+
apiKey: string;
|
|
571
|
+
/** Base URL for Artyfacts API */
|
|
572
|
+
baseUrl?: string;
|
|
573
|
+
/** Callback when MCP server is configured */
|
|
574
|
+
onConfigured?: (connectionId: string, platform: string) => void;
|
|
575
|
+
/** Callback on error */
|
|
576
|
+
onError?: (error: Error, connectionId: string) => void;
|
|
577
|
+
}
|
|
578
|
+
declare class McpHandler {
|
|
579
|
+
private config;
|
|
580
|
+
constructor(config: McpHandlerConfig);
|
|
581
|
+
/**
|
|
582
|
+
* Handle an MCP connect request event
|
|
583
|
+
* Uses `claude mcp add` to configure the server dynamically
|
|
584
|
+
*/
|
|
585
|
+
handleConnectRequest(event: McpConnectRequestEvent): Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Check if a platform supports OAuth (no credentials needed)
|
|
588
|
+
*/
|
|
589
|
+
static supportsOAuth(platform: string): boolean;
|
|
590
|
+
/**
|
|
591
|
+
* Get list of platforms with OAuth support
|
|
592
|
+
*/
|
|
593
|
+
static getOAuthPlatforms(): string[];
|
|
594
|
+
/**
|
|
595
|
+
* Update connection status in Artyfacts
|
|
596
|
+
*/
|
|
597
|
+
private updateConnectionStatus;
|
|
598
|
+
/**
|
|
599
|
+
* List configured MCP servers using `claude mcp list`
|
|
600
|
+
*/
|
|
601
|
+
listServers(): string[];
|
|
602
|
+
/**
|
|
603
|
+
* Remove an MCP server using `claude mcp remove`
|
|
604
|
+
*/
|
|
605
|
+
removeServer(serverName: string): boolean;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Create an MCP handler instance
|
|
609
|
+
*/
|
|
610
|
+
declare function createMcpHandler(config: McpHandlerConfig): McpHandler;
|
|
611
|
+
|
|
612
|
+
export { type ApiClient, type ArtifactContext, type ArtyfactsEvent, ArtyfactsListener, ClaudeExecutor, ClaudeExecutorWithTools, type ClaudeSettingsJson, type ConnectedEvent, type ConnectionState, ContextFetcher, type ContextFetcherConfig, type Credentials, type DeviceAuthResponse, type EventCallback, type ExecutionResult$1 as ExecutionResult, type ExecutorConfig$1 as ExecutorConfig, type ExecutorConfig as ExecutorWithToolsConfig, type HeartbeatEvent, type ListenerConfig, type McpConnectRequestEvent, McpHandler, type McpHandlerConfig, type McpServerConfig, type OrganizationContext, type ProjectContext, type SectionContext, type TaskAssignedEvent, type TaskContext$1 as TaskContext, type TaskFullContext, type TokenResponse, type ToolCall, type ToolCallResult, type ToolHandler, type ToolResult, type ToolSchema, buildPromptWithContext, clearCredentials, createApiClient, createContextFetcher, createExecutor, createExecutorWithTools, createListener, createMcpHandler, executeTool, getAllToolSchemas, getCredentials, getRequiredPermission, getToolSchema, getToolsForPermissions, isToolAllowed, loadCredentials, permissionToTools, promptForApiKey, runDeviceAuth, saveCredentials, handlers as toolHandlers };
|