@olivaresai/alma-mcp 1.3.1 → 1.3.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.js +637 -2
- package/package.json +26 -12
package/dist/index.js
CHANGED
|
@@ -328,6 +328,87 @@ var AlmaClient = class _AlmaClient {
|
|
|
328
328
|
async createProcedure(params) {
|
|
329
329
|
return this.request("POST", "/procedures", params);
|
|
330
330
|
}
|
|
331
|
+
// ─── Cowork (Collaborative Workspaces) ─────────────
|
|
332
|
+
async listWorkspaces() {
|
|
333
|
+
return this.request("GET", "/cowork/workspaces");
|
|
334
|
+
}
|
|
335
|
+
async createWorkspace(params) {
|
|
336
|
+
return this.request("POST", "/cowork/workspaces", params);
|
|
337
|
+
}
|
|
338
|
+
async listWorkspaceFiles(workspaceId) {
|
|
339
|
+
return this.request(
|
|
340
|
+
"GET",
|
|
341
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/files`
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
async readWorkspaceFile(workspaceId, filePath) {
|
|
345
|
+
const qs = new URLSearchParams({ path: filePath });
|
|
346
|
+
return this.request(
|
|
347
|
+
"GET",
|
|
348
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/files/read?${qs}`
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
async writeWorkspaceFile(workspaceId, filePath, content) {
|
|
352
|
+
return this.request(
|
|
353
|
+
"POST",
|
|
354
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/files/write`,
|
|
355
|
+
{ path: filePath, content }
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
async searchWorkspace(workspaceId, query) {
|
|
359
|
+
const qs = new URLSearchParams({ q: query });
|
|
360
|
+
return this.request(
|
|
361
|
+
"GET",
|
|
362
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/search?${qs}`
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
async executeSkill(workspaceId, params) {
|
|
366
|
+
return this.request(
|
|
367
|
+
"POST",
|
|
368
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/skills`,
|
|
369
|
+
params
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
async applyDiff(workspaceId, operationId) {
|
|
373
|
+
return this.request(
|
|
374
|
+
"POST",
|
|
375
|
+
`/cowork/workspaces/${encodeURIComponent(workspaceId)}/apply`,
|
|
376
|
+
{ operationId }
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
// ─── Video ────────────────────────────────────────
|
|
380
|
+
async generateVideo(params) {
|
|
381
|
+
return this.request("POST", "/video/generate", params);
|
|
382
|
+
}
|
|
383
|
+
async checkVideoJob(jobId) {
|
|
384
|
+
return this.request(
|
|
385
|
+
"GET",
|
|
386
|
+
`/video/jobs/${encodeURIComponent(jobId)}`
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
async listVideoProjects() {
|
|
390
|
+
return this.request("GET", "/video/projects");
|
|
391
|
+
}
|
|
392
|
+
async createVideoProject(params) {
|
|
393
|
+
return this.request("POST", "/video/projects", params);
|
|
394
|
+
}
|
|
395
|
+
async planVideoScenes(projectId, params) {
|
|
396
|
+
return this.request(
|
|
397
|
+
"POST",
|
|
398
|
+
`/video/projects/${encodeURIComponent(projectId)}/plan`,
|
|
399
|
+
params
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
async stitchVideo(projectId, jobIds) {
|
|
403
|
+
return this.request(
|
|
404
|
+
"POST",
|
|
405
|
+
`/video/projects/${encodeURIComponent(projectId)}/stitch`,
|
|
406
|
+
{ jobIds }
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
async getVideoBudget() {
|
|
410
|
+
return this.request("GET", "/video/budget");
|
|
411
|
+
}
|
|
331
412
|
};
|
|
332
413
|
|
|
333
414
|
// src/tools/assemble.ts
|
|
@@ -1232,12 +1313,470 @@ ${JSON.stringify(result.memory, null, 2)}`
|
|
|
1232
1313
|
);
|
|
1233
1314
|
}
|
|
1234
1315
|
|
|
1316
|
+
// src/tools/cowork.ts
|
|
1317
|
+
import { z as z18 } from "zod";
|
|
1318
|
+
function registerCoworkTools(server2, client2) {
|
|
1319
|
+
server2.registerTool(
|
|
1320
|
+
"cowork_list_workspaces",
|
|
1321
|
+
{
|
|
1322
|
+
title: "List Workspaces",
|
|
1323
|
+
description: "List all collaborative workspaces available to the user. Returns workspace IDs, names, and metadata.",
|
|
1324
|
+
inputSchema: {}
|
|
1325
|
+
},
|
|
1326
|
+
async () => {
|
|
1327
|
+
try {
|
|
1328
|
+
const result = await client2.listWorkspaces();
|
|
1329
|
+
if (result.workspaces.length === 0) {
|
|
1330
|
+
return {
|
|
1331
|
+
content: [{ type: "text", text: "No workspaces found." }]
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
return {
|
|
1335
|
+
content: [
|
|
1336
|
+
{
|
|
1337
|
+
type: "text",
|
|
1338
|
+
text: JSON.stringify(result, null, 2)
|
|
1339
|
+
}
|
|
1340
|
+
]
|
|
1341
|
+
};
|
|
1342
|
+
} catch (err) {
|
|
1343
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1344
|
+
return {
|
|
1345
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1346
|
+
isError: true
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
);
|
|
1351
|
+
server2.registerTool(
|
|
1352
|
+
"cowork_create_workspace",
|
|
1353
|
+
{
|
|
1354
|
+
title: "Create Workspace",
|
|
1355
|
+
description: "Create a new collaborative workspace. Workspaces hold files that Alma can read, write, and operate on.",
|
|
1356
|
+
inputSchema: {
|
|
1357
|
+
name: z18.string().min(1).max(200).describe("Name for the workspace"),
|
|
1358
|
+
description: z18.string().max(1e3).optional().describe("Optional description of the workspace purpose"),
|
|
1359
|
+
sourceType: z18.string().optional().describe('Source type for the workspace (e.g. "blank", "template", "import")')
|
|
1360
|
+
}
|
|
1361
|
+
},
|
|
1362
|
+
async ({ name, description, sourceType }) => {
|
|
1363
|
+
try {
|
|
1364
|
+
const result = await client2.createWorkspace({ name, description, sourceType });
|
|
1365
|
+
return {
|
|
1366
|
+
content: [
|
|
1367
|
+
{
|
|
1368
|
+
type: "text",
|
|
1369
|
+
text: `Workspace created successfully.
|
|
1370
|
+
${JSON.stringify(result.workspace, null, 2)}`
|
|
1371
|
+
}
|
|
1372
|
+
]
|
|
1373
|
+
};
|
|
1374
|
+
} catch (err) {
|
|
1375
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1376
|
+
return {
|
|
1377
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1378
|
+
isError: true
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
);
|
|
1383
|
+
server2.registerTool(
|
|
1384
|
+
"cowork_list_files",
|
|
1385
|
+
{
|
|
1386
|
+
title: "List Workspace Files",
|
|
1387
|
+
description: "List all files in a collaborative workspace. Returns file paths, sizes, and metadata.",
|
|
1388
|
+
inputSchema: {
|
|
1389
|
+
workspaceId: z18.string().min(1).describe("The workspace ID to list files from")
|
|
1390
|
+
}
|
|
1391
|
+
},
|
|
1392
|
+
async ({ workspaceId }) => {
|
|
1393
|
+
try {
|
|
1394
|
+
const result = await client2.listWorkspaceFiles(workspaceId);
|
|
1395
|
+
if (result.files.length === 0) {
|
|
1396
|
+
return {
|
|
1397
|
+
content: [{ type: "text", text: "No files found in this workspace." }]
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
return {
|
|
1401
|
+
content: [
|
|
1402
|
+
{
|
|
1403
|
+
type: "text",
|
|
1404
|
+
text: JSON.stringify(result, null, 2)
|
|
1405
|
+
}
|
|
1406
|
+
]
|
|
1407
|
+
};
|
|
1408
|
+
} catch (err) {
|
|
1409
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1410
|
+
return {
|
|
1411
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1412
|
+
isError: true
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
);
|
|
1417
|
+
server2.registerTool(
|
|
1418
|
+
"cowork_read_file",
|
|
1419
|
+
{
|
|
1420
|
+
title: "Read Workspace File",
|
|
1421
|
+
description: "Read the content of a file in a collaborative workspace. Returns the file content and metadata.",
|
|
1422
|
+
inputSchema: {
|
|
1423
|
+
workspaceId: z18.string().min(1).describe("The workspace ID containing the file"),
|
|
1424
|
+
filePath: z18.string().min(1).describe("Path of the file within the workspace")
|
|
1425
|
+
}
|
|
1426
|
+
},
|
|
1427
|
+
async ({ workspaceId, filePath }) => {
|
|
1428
|
+
try {
|
|
1429
|
+
const result = await client2.readWorkspaceFile(workspaceId, filePath);
|
|
1430
|
+
return {
|
|
1431
|
+
content: [
|
|
1432
|
+
{
|
|
1433
|
+
type: "text",
|
|
1434
|
+
text: JSON.stringify(result.file, null, 2)
|
|
1435
|
+
}
|
|
1436
|
+
]
|
|
1437
|
+
};
|
|
1438
|
+
} catch (err) {
|
|
1439
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1440
|
+
return {
|
|
1441
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1442
|
+
isError: true
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
);
|
|
1447
|
+
server2.registerTool(
|
|
1448
|
+
"cowork_write_file",
|
|
1449
|
+
{
|
|
1450
|
+
title: "Write Workspace File",
|
|
1451
|
+
description: "Write or update a file in a collaborative workspace. Creates the file if it does not exist.",
|
|
1452
|
+
inputSchema: {
|
|
1453
|
+
workspaceId: z18.string().min(1).describe("The workspace ID to write the file in"),
|
|
1454
|
+
filePath: z18.string().min(1).describe("Path of the file within the workspace"),
|
|
1455
|
+
content: z18.string().describe("The content to write to the file")
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
async ({ workspaceId, filePath, content }) => {
|
|
1459
|
+
try {
|
|
1460
|
+
const result = await client2.writeWorkspaceFile(workspaceId, filePath, content);
|
|
1461
|
+
return {
|
|
1462
|
+
content: [
|
|
1463
|
+
{
|
|
1464
|
+
type: "text",
|
|
1465
|
+
text: `File written successfully.
|
|
1466
|
+
${JSON.stringify(result.file, null, 2)}`
|
|
1467
|
+
}
|
|
1468
|
+
]
|
|
1469
|
+
};
|
|
1470
|
+
} catch (err) {
|
|
1471
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1472
|
+
return {
|
|
1473
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1474
|
+
isError: true
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
);
|
|
1479
|
+
server2.registerTool(
|
|
1480
|
+
"cowork_search",
|
|
1481
|
+
{
|
|
1482
|
+
title: "Search Workspace",
|
|
1483
|
+
description: "Search across all files in a collaborative workspace. Returns matching files and content snippets.",
|
|
1484
|
+
inputSchema: {
|
|
1485
|
+
workspaceId: z18.string().min(1).describe("The workspace ID to search in"),
|
|
1486
|
+
query: z18.string().min(1).describe("Search query string")
|
|
1487
|
+
}
|
|
1488
|
+
},
|
|
1489
|
+
async ({ workspaceId, query }) => {
|
|
1490
|
+
try {
|
|
1491
|
+
const result = await client2.searchWorkspace(workspaceId, query);
|
|
1492
|
+
if (result.results.length === 0) {
|
|
1493
|
+
return {
|
|
1494
|
+
content: [{ type: "text", text: `No results found for: ${query}` }]
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
return {
|
|
1498
|
+
content: [
|
|
1499
|
+
{
|
|
1500
|
+
type: "text",
|
|
1501
|
+
text: JSON.stringify(result, null, 2)
|
|
1502
|
+
}
|
|
1503
|
+
]
|
|
1504
|
+
};
|
|
1505
|
+
} catch (err) {
|
|
1506
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1507
|
+
return {
|
|
1508
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1509
|
+
isError: true
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
);
|
|
1514
|
+
server2.registerTool(
|
|
1515
|
+
"cowork_execute_skill",
|
|
1516
|
+
{
|
|
1517
|
+
title: "Execute Skill",
|
|
1518
|
+
description: "Run an AI skill on a file or input within a collaborative workspace. Available skills: explain, refactor, review, test, fix, document, search, commit.",
|
|
1519
|
+
inputSchema: {
|
|
1520
|
+
workspaceId: z18.string().min(1).describe("The workspace ID to execute the skill in"),
|
|
1521
|
+
skill: z18.enum(["explain", "refactor", "review", "test", "fix", "document", "search", "commit"]).describe("The skill to execute"),
|
|
1522
|
+
targetPath: z18.string().optional().describe("Optional file path to target with the skill"),
|
|
1523
|
+
input: z18.string().min(1).describe("Input or instructions for the skill execution")
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
async ({ workspaceId, skill, targetPath, input }) => {
|
|
1527
|
+
try {
|
|
1528
|
+
const result = await client2.executeSkill(workspaceId, { skill, targetPath, input });
|
|
1529
|
+
return {
|
|
1530
|
+
content: [
|
|
1531
|
+
{
|
|
1532
|
+
type: "text",
|
|
1533
|
+
text: `Skill "${skill}" executed successfully.
|
|
1534
|
+
${JSON.stringify(result.result, null, 2)}`
|
|
1535
|
+
}
|
|
1536
|
+
]
|
|
1537
|
+
};
|
|
1538
|
+
} catch (err) {
|
|
1539
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1540
|
+
return {
|
|
1541
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1542
|
+
isError: true
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
);
|
|
1547
|
+
server2.registerTool(
|
|
1548
|
+
"cowork_apply_diff",
|
|
1549
|
+
{
|
|
1550
|
+
title: "Apply Operation Diff",
|
|
1551
|
+
description: "Apply a pending operation diff to a workspace file. Use after executing a skill that produces changes.",
|
|
1552
|
+
inputSchema: {
|
|
1553
|
+
workspaceId: z18.string().min(1).describe("The workspace ID containing the operation"),
|
|
1554
|
+
operationId: z18.string().min(1).describe("The operation ID whose diff should be applied")
|
|
1555
|
+
}
|
|
1556
|
+
},
|
|
1557
|
+
async ({ workspaceId, operationId }) => {
|
|
1558
|
+
try {
|
|
1559
|
+
const result = await client2.applyDiff(workspaceId, operationId);
|
|
1560
|
+
return {
|
|
1561
|
+
content: [
|
|
1562
|
+
{
|
|
1563
|
+
type: "text",
|
|
1564
|
+
text: result.applied ? `Diff applied successfully.
|
|
1565
|
+
${JSON.stringify(result.result, null, 2)}` : "Diff could not be applied. The operation may have already been applied or expired."
|
|
1566
|
+
}
|
|
1567
|
+
]
|
|
1568
|
+
};
|
|
1569
|
+
} catch (err) {
|
|
1570
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1571
|
+
return {
|
|
1572
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1573
|
+
isError: true
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
// src/tools/video.ts
|
|
1581
|
+
import { z as z19 } from "zod";
|
|
1582
|
+
function registerVideoTools(server2, client2) {
|
|
1583
|
+
server2.registerTool(
|
|
1584
|
+
"video_generate",
|
|
1585
|
+
{
|
|
1586
|
+
title: "Generate Video",
|
|
1587
|
+
description: "Start an AI video generation job. Returns a job ID to track progress. Requires a paid plan with video credits.",
|
|
1588
|
+
inputSchema: {
|
|
1589
|
+
prompt: z19.string().min(1).max(2e3).describe("Text description of the video to generate"),
|
|
1590
|
+
model: z19.string().min(1).describe('Video generation model to use (e.g. "runway-gen3", "kling-v1", "pika-v2")'),
|
|
1591
|
+
durationSeconds: z19.number().int().min(1).max(60).describe("Duration of the video in seconds (1-60)"),
|
|
1592
|
+
aspectRatio: z19.enum(["16:9", "9:16", "1:1", "4:3", "3:4"]).optional().describe("Aspect ratio of the video (default: 16:9)"),
|
|
1593
|
+
style: z19.string().max(200).optional().describe('Optional style modifier (e.g. "cinematic", "anime", "documentary")')
|
|
1594
|
+
}
|
|
1595
|
+
},
|
|
1596
|
+
async ({ prompt, model, durationSeconds, aspectRatio, style }) => {
|
|
1597
|
+
try {
|
|
1598
|
+
const result = await client2.generateVideo({ prompt, model, durationSeconds, aspectRatio, style });
|
|
1599
|
+
return {
|
|
1600
|
+
content: [
|
|
1601
|
+
{
|
|
1602
|
+
type: "text",
|
|
1603
|
+
text: `Video generation started.
|
|
1604
|
+
${JSON.stringify(result.job, null, 2)}`
|
|
1605
|
+
}
|
|
1606
|
+
]
|
|
1607
|
+
};
|
|
1608
|
+
} catch (err) {
|
|
1609
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1610
|
+
return {
|
|
1611
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1612
|
+
isError: true
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
);
|
|
1617
|
+
server2.registerTool(
|
|
1618
|
+
"video_check_job",
|
|
1619
|
+
{
|
|
1620
|
+
title: "Check Video Job",
|
|
1621
|
+
description: "Check the status of a video generation job. Returns status, progress percentage, and result URL when complete.",
|
|
1622
|
+
inputSchema: {
|
|
1623
|
+
jobId: z19.string().min(1).describe("The video generation job ID to check")
|
|
1624
|
+
}
|
|
1625
|
+
},
|
|
1626
|
+
async ({ jobId }) => {
|
|
1627
|
+
try {
|
|
1628
|
+
const result = await client2.checkVideoJob(jobId);
|
|
1629
|
+
return {
|
|
1630
|
+
content: [
|
|
1631
|
+
{
|
|
1632
|
+
type: "text",
|
|
1633
|
+
text: JSON.stringify(result.job, null, 2)
|
|
1634
|
+
}
|
|
1635
|
+
]
|
|
1636
|
+
};
|
|
1637
|
+
} catch (err) {
|
|
1638
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1639
|
+
return {
|
|
1640
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1641
|
+
isError: true
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
);
|
|
1646
|
+
server2.registerTool(
|
|
1647
|
+
"video_list_projects",
|
|
1648
|
+
{
|
|
1649
|
+
title: "List Video Projects",
|
|
1650
|
+
description: "List all video projects for the user. Projects organize multiple video scenes into a cohesive production.",
|
|
1651
|
+
inputSchema: {}
|
|
1652
|
+
},
|
|
1653
|
+
async () => {
|
|
1654
|
+
try {
|
|
1655
|
+
const result = await client2.listVideoProjects();
|
|
1656
|
+
if (result.projects.length === 0) {
|
|
1657
|
+
return {
|
|
1658
|
+
content: [{ type: "text", text: "No video projects found." }]
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
return {
|
|
1662
|
+
content: [
|
|
1663
|
+
{
|
|
1664
|
+
type: "text",
|
|
1665
|
+
text: JSON.stringify(result, null, 2)
|
|
1666
|
+
}
|
|
1667
|
+
]
|
|
1668
|
+
};
|
|
1669
|
+
} catch (err) {
|
|
1670
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1671
|
+
return {
|
|
1672
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1673
|
+
isError: true
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1678
|
+
server2.registerTool(
|
|
1679
|
+
"video_create_project",
|
|
1680
|
+
{
|
|
1681
|
+
title: "Create Video Project",
|
|
1682
|
+
description: "Create a new video project. Projects let you plan scenes, generate clips, and stitch them into a final video.",
|
|
1683
|
+
inputSchema: {
|
|
1684
|
+
name: z19.string().min(1).max(200).describe("Name for the video project"),
|
|
1685
|
+
description: z19.string().max(1e3).optional().describe("Optional description of the video project")
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1688
|
+
async ({ name, description }) => {
|
|
1689
|
+
try {
|
|
1690
|
+
const result = await client2.createVideoProject({ name, description });
|
|
1691
|
+
return {
|
|
1692
|
+
content: [
|
|
1693
|
+
{
|
|
1694
|
+
type: "text",
|
|
1695
|
+
text: `Video project created successfully.
|
|
1696
|
+
${JSON.stringify(result.project, null, 2)}`
|
|
1697
|
+
}
|
|
1698
|
+
]
|
|
1699
|
+
};
|
|
1700
|
+
} catch (err) {
|
|
1701
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1702
|
+
return {
|
|
1703
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1704
|
+
isError: true
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
);
|
|
1709
|
+
server2.registerTool(
|
|
1710
|
+
"video_plan_scenes",
|
|
1711
|
+
{
|
|
1712
|
+
title: "Plan Video Scenes",
|
|
1713
|
+
description: "Use AI to plan scenes for a video project. Breaks a description into individual scene prompts with timing and transitions.",
|
|
1714
|
+
inputSchema: {
|
|
1715
|
+
projectId: z19.string().min(1).describe("The video project ID to plan scenes for"),
|
|
1716
|
+
description: z19.string().min(1).max(5e3).describe("Description of the video to plan (story, concept, or script)"),
|
|
1717
|
+
sceneCount: z19.number().int().min(1).max(20).optional().describe("Number of scenes to plan (default: auto-determined by AI)")
|
|
1718
|
+
}
|
|
1719
|
+
},
|
|
1720
|
+
async ({ projectId, description, sceneCount }) => {
|
|
1721
|
+
try {
|
|
1722
|
+
const result = await client2.planVideoScenes(projectId, { description, sceneCount });
|
|
1723
|
+
return {
|
|
1724
|
+
content: [
|
|
1725
|
+
{
|
|
1726
|
+
type: "text",
|
|
1727
|
+
text: `Scene plan created (${result.scenes.length} scenes).
|
|
1728
|
+
${JSON.stringify(result.scenes, null, 2)}`
|
|
1729
|
+
}
|
|
1730
|
+
]
|
|
1731
|
+
};
|
|
1732
|
+
} catch (err) {
|
|
1733
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1734
|
+
return {
|
|
1735
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1736
|
+
isError: true
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
);
|
|
1741
|
+
server2.registerTool(
|
|
1742
|
+
"video_stitch",
|
|
1743
|
+
{
|
|
1744
|
+
title: "Stitch Video",
|
|
1745
|
+
description: "Stitch multiple generated video scenes into a single final video. All referenced jobs must be complete.",
|
|
1746
|
+
inputSchema: {
|
|
1747
|
+
projectId: z19.string().min(1).describe("The video project ID"),
|
|
1748
|
+
jobIds: z19.array(z19.string().min(1)).min(1).max(20).describe("Ordered list of completed video job IDs to stitch together")
|
|
1749
|
+
}
|
|
1750
|
+
},
|
|
1751
|
+
async ({ projectId, jobIds }) => {
|
|
1752
|
+
try {
|
|
1753
|
+
const result = await client2.stitchVideo(projectId, jobIds);
|
|
1754
|
+
return {
|
|
1755
|
+
content: [
|
|
1756
|
+
{
|
|
1757
|
+
type: "text",
|
|
1758
|
+
text: `Video stitch job started.
|
|
1759
|
+
${JSON.stringify(result.job, null, 2)}`
|
|
1760
|
+
}
|
|
1761
|
+
]
|
|
1762
|
+
};
|
|
1763
|
+
} catch (err) {
|
|
1764
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1765
|
+
return {
|
|
1766
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1767
|
+
isError: true
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1235
1774
|
// src/index.ts
|
|
1236
1775
|
var config = loadConfig();
|
|
1237
1776
|
var client = new AlmaClient(config);
|
|
1238
1777
|
var server = new McpServer({
|
|
1239
1778
|
name: "alma-mcp",
|
|
1240
|
-
version: "1.3.
|
|
1779
|
+
version: "1.3.2"
|
|
1241
1780
|
});
|
|
1242
1781
|
registerAssembleTool(server, client);
|
|
1243
1782
|
registerRememberTool(server, client);
|
|
@@ -1260,6 +1799,8 @@ registerListProceduresTool(server, client);
|
|
|
1260
1799
|
registerCreateProcedureTool(server, client);
|
|
1261
1800
|
registerPreviewContextTool(server, client);
|
|
1262
1801
|
registerUpdateMemoryTool(server, client);
|
|
1802
|
+
registerCoworkTools(server, client);
|
|
1803
|
+
registerVideoTools(server, client);
|
|
1263
1804
|
server.registerResource(
|
|
1264
1805
|
"soul",
|
|
1265
1806
|
"alma://soul",
|
|
@@ -1400,6 +1941,34 @@ server.registerResource(
|
|
|
1400
1941
|
}
|
|
1401
1942
|
}
|
|
1402
1943
|
);
|
|
1944
|
+
server.registerResource(
|
|
1945
|
+
"video-budget",
|
|
1946
|
+
"alma://video-budget",
|
|
1947
|
+
{
|
|
1948
|
+
title: "Video Budget",
|
|
1949
|
+
description: "Current video generation credits, usage, and remaining quota",
|
|
1950
|
+
mimeType: "application/json"
|
|
1951
|
+
},
|
|
1952
|
+
async (uri) => {
|
|
1953
|
+
try {
|
|
1954
|
+
const result = await client.getVideoBudget();
|
|
1955
|
+
return {
|
|
1956
|
+
contents: [
|
|
1957
|
+
{
|
|
1958
|
+
uri: uri.href,
|
|
1959
|
+
mimeType: "application/json",
|
|
1960
|
+
text: JSON.stringify(result, null, 2)
|
|
1961
|
+
}
|
|
1962
|
+
]
|
|
1963
|
+
};
|
|
1964
|
+
} catch (err) {
|
|
1965
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
1966
|
+
return {
|
|
1967
|
+
contents: [{ uri: uri.href, mimeType: "text/plain", text: `Error loading resource: ${message}` }]
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
);
|
|
1403
1972
|
server.registerResource(
|
|
1404
1973
|
"memories-by-category",
|
|
1405
1974
|
new ResourceTemplate("alma://memories/{category}", {
|
|
@@ -1523,10 +2092,76 @@ server.registerResource(
|
|
|
1523
2092
|
}
|
|
1524
2093
|
}
|
|
1525
2094
|
);
|
|
2095
|
+
server.prompt(
|
|
2096
|
+
"alma-context",
|
|
2097
|
+
"Assemble Alma's full context: soul identity, relevant memories, recent episodes, and procedures. Use this to give the AI persistent memory about the user.",
|
|
2098
|
+
{},
|
|
2099
|
+
async () => {
|
|
2100
|
+
try {
|
|
2101
|
+
const result = await client.assembleContext({ message: "general conversation" });
|
|
2102
|
+
return {
|
|
2103
|
+
messages: [
|
|
2104
|
+
{
|
|
2105
|
+
role: "user",
|
|
2106
|
+
content: {
|
|
2107
|
+
type: "text",
|
|
2108
|
+
text: `The following is your persistent memory and identity context from Alma. Use it to personalize your responses:
|
|
2109
|
+
|
|
2110
|
+
${result.system_prompt}`
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
]
|
|
2114
|
+
};
|
|
2115
|
+
} catch (err) {
|
|
2116
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
2117
|
+
return {
|
|
2118
|
+
messages: [
|
|
2119
|
+
{
|
|
2120
|
+
role: "user",
|
|
2121
|
+
content: {
|
|
2122
|
+
type: "text",
|
|
2123
|
+
text: `[Alma context unavailable: ${message}]`
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
]
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
);
|
|
2131
|
+
server.prompt(
|
|
2132
|
+
"alma-recall",
|
|
2133
|
+
"Search Alma's memory for information about a specific topic.",
|
|
2134
|
+
{ topic: { description: "The topic to recall memories about", required: true } },
|
|
2135
|
+
async (args) => {
|
|
2136
|
+
try {
|
|
2137
|
+
const result = await client.searchMemories({ q: args.topic ?? "", limit: 10 });
|
|
2138
|
+
const memoryText = result.memories.length > 0 ? result.memories.map((m) => `- ${m.content} (${m.category}, importance: ${m.importance})`).join("\n") : "No memories found for this topic.";
|
|
2139
|
+
return {
|
|
2140
|
+
messages: [
|
|
2141
|
+
{
|
|
2142
|
+
role: "user",
|
|
2143
|
+
content: {
|
|
2144
|
+
type: "text",
|
|
2145
|
+
text: `Here is what Alma remembers about "${args.topic}":
|
|
2146
|
+
|
|
2147
|
+
${memoryText}`
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
]
|
|
2151
|
+
};
|
|
2152
|
+
} catch {
|
|
2153
|
+
return {
|
|
2154
|
+
messages: [
|
|
2155
|
+
{ role: "user", content: { type: "text", text: `[Could not recall memories for "${args.topic}"]` } }
|
|
2156
|
+
]
|
|
2157
|
+
};
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
);
|
|
1526
2161
|
async function main() {
|
|
1527
2162
|
const transport = new StdioServerTransport();
|
|
1528
2163
|
await server.connect(transport);
|
|
1529
|
-
console.error("[alma-mcp] Server started on stdio (v1.3.
|
|
2164
|
+
console.error("[alma-mcp] Server started on stdio (v1.3.2, 35 tools, 10 resources, 2 prompts)");
|
|
1530
2165
|
if (process.env.ALMA_DEBUG) {
|
|
1531
2166
|
console.error(`[alma-mcp] API: ${config.baseUrl}`);
|
|
1532
2167
|
if (config.environmentId) {
|
package/package.json
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olivaresai/alma-mcp",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "MCP Server for Alma — persistent memory for AI agents",
|
|
3
|
+
"version": "1.3.2",
|
|
4
|
+
"description": "MCP Server for Alma by OlivaresAI — persistent memory for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"alma-mcp": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "dist/index.js",
|
|
10
|
-
"files": [
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"alma",
|
|
18
|
+
"ai",
|
|
19
|
+
"memory",
|
|
20
|
+
"persistent-memory",
|
|
21
|
+
"ai-agent",
|
|
22
|
+
"model-context-protocol",
|
|
23
|
+
"claude",
|
|
24
|
+
"cursor",
|
|
25
|
+
"windsurf",
|
|
26
|
+
"llm"
|
|
27
|
+
],
|
|
18
28
|
"dependencies": {
|
|
19
29
|
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
20
30
|
"zod": "^3.24.0"
|
|
@@ -35,5 +45,9 @@
|
|
|
35
45
|
},
|
|
36
46
|
"author": "OlivaresAI",
|
|
37
47
|
"license": "SEE LICENSE IN LICENSE",
|
|
38
|
-
"
|
|
39
|
-
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"dev": "tsx src/index.ts",
|
|
51
|
+
"typecheck": "tsc --noEmit"
|
|
52
|
+
}
|
|
53
|
+
}
|