@olivaresai/alma-mcp 1.3.2 → 1.3.3

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.
Files changed (3) hide show
  1. package/README.md +28 -3
  2. package/dist/index.js +42 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -47,11 +47,11 @@ Then use `"command": "alma-mcp"` instead of `npx`.
47
47
  | Variable | Required | Description |
48
48
  |----------|----------|-------------|
49
49
  | `ALMA_API_KEY` | Yes | Your Alma API key ([get one here](https://alma.olivares.ai/settings)) |
50
- | `ALMA_BASE_URL` | No | API base URL (default: `https://alma.olivares.ai/api/v1`) |
50
+ | `ALMA_API_URL` | No | API base URL (default: `https://alma.olivares.ai/api/v1`). `ALMA_BASE_URL` is accepted as an alias. |
51
51
  | `ALMA_ENVIRONMENT_ID` | No | Default environment ID |
52
52
  | `ALMA_DEBUG` | No | Enable debug logging |
53
53
 
54
- ## Tools (21)
54
+ ## Tools (35)
55
55
 
56
56
  ### Context
57
57
 
@@ -94,7 +94,31 @@ Then use `"command": "alma-mcp"` instead of `npx`.
94
94
  | `alma_list_environments` | List all environments |
95
95
  | `alma_create_environment` | Create a new environment |
96
96
 
97
- ## Resources (9)
97
+ ### Cowork (Collaborative Workspaces)
98
+
99
+ | Tool | Description |
100
+ |------|-------------|
101
+ | `cowork_list_workspaces` | List all collaborative workspaces |
102
+ | `cowork_create_workspace` | Create a new collaborative workspace |
103
+ | `cowork_list_files` | List all files in a workspace |
104
+ | `cowork_read_file` | Read the content of a workspace file |
105
+ | `cowork_write_file` | Write or update a file in a workspace |
106
+ | `cowork_search` | Search across all files in a workspace |
107
+ | `cowork_execute_skill` | Run an AI skill on a file (explain, refactor, review, test, fix, document, search, commit) |
108
+ | `cowork_apply_diff` | Apply a pending operation diff to a workspace file |
109
+
110
+ ### Video
111
+
112
+ | Tool | Description |
113
+ |------|-------------|
114
+ | `video_generate` | Start an AI video generation job |
115
+ | `video_check_job` | Check the status of a video generation job |
116
+ | `video_list_projects` | List all video projects |
117
+ | `video_create_project` | Create a new video project |
118
+ | `video_plan_scenes` | Use AI to plan scenes for a video project |
119
+ | `video_stitch` | Stitch multiple video scenes into a single final video |
120
+
121
+ ## Resources (10)
98
122
 
99
123
  | Resource URI | Description |
100
124
  |-------------|-------------|
@@ -104,6 +128,7 @@ Then use `"command": "alma-mcp"` instead of `npx`.
104
128
  | `alma://environments` | All available environments |
105
129
  | `alma://conversations` | Recent conversations (last 20) |
106
130
  | `alma://budget` | Token budget status |
131
+ | `alma://video-budget` | Video generation credits and usage |
107
132
  | `alma://blocks` | All soul memory blocks |
108
133
  | `alma://episodes` | Recent episodes (last 20) |
109
134
  | `alma://procedures` | All stored procedures (limit 50) |
package/dist/index.js CHANGED
@@ -18,10 +18,40 @@ function loadConfig() {
18
18
  console.error("[alma-mcp] ALMA_API_URL must use HTTPS for non-localhost connections. Got:", cleanUrl);
19
19
  process.exit(1);
20
20
  }
21
+ if (!cleanUrl.startsWith("https://") && process.env.NODE_ENV !== "development" && process.env.ALMA_DEV !== "1") {
22
+ console.error(
23
+ `[alma-mcp] WARNING: ALMA_API_URL points at ${cleanUrl}. This is only correct for local development. For Alma cloud use https://alma.olivares.ai/api/v1 (or set NODE_ENV=development to silence this warning).`
24
+ );
25
+ }
21
26
  return { baseUrl: cleanUrl, apiKey, environmentId };
22
27
  }
23
28
 
24
29
  // src/client.ts
30
+ function formatApiError(method, path, status, detail, code) {
31
+ const tail = detail ? ` ${detail}` : "";
32
+ if (status === 401) {
33
+ return `Alma rejected the API key. Generate a new one at https://alma.olivares.ai/settings (API Keys) and set ALMA_API_KEY in your MCP config.${tail}`;
34
+ }
35
+ if (status === 402) {
36
+ if (code === "BUDGET_EXHAUSTED" || /budget/i.test(detail)) {
37
+ return `Your Alma weekly AI budget is exhausted. Top up at https://alma.olivares.ai/settings/billing or wait until Monday 00:00 UTC for the budget to reset.${tail}`;
38
+ }
39
+ return `This action requires an active Alma plan or additional credits. Manage your subscription at https://alma.olivares.ai/settings/billing.${tail}`;
40
+ }
41
+ if (status === 403) {
42
+ if (code === "PLAN_API_RESTRICTED" || /api/i.test(detail)) {
43
+ return `The Alma API is available on the Max plan. Upgrade at https://alma.olivares.ai/settings/billing.${tail}`;
44
+ }
45
+ if (code === "BYOK_REQUIRED_PLAN") {
46
+ return `BYOK (bring your own keys) is available on the Max plan. Upgrade at https://alma.olivares.ai/settings/billing.${tail}`;
47
+ }
48
+ return `Forbidden \u2014 your plan does not include this feature. See https://alma.olivares.ai/settings/billing.${tail}`;
49
+ }
50
+ if (status === 429) {
51
+ return `Alma rate limit hit. Slow down and retry in a minute.${tail}`;
52
+ }
53
+ return `Alma API ${method} ${path} failed (${status}):${tail}`;
54
+ }
25
55
  var AlmaClient = class _AlmaClient {
26
56
  constructor(config2) {
27
57
  this.config = config2;
@@ -83,12 +113,14 @@ var AlmaClient = class _AlmaClient {
83
113
  if (!res.ok) {
84
114
  const text = await res.text().catch(() => "");
85
115
  let detail = text;
116
+ let code;
86
117
  try {
87
118
  const json = JSON.parse(text);
88
119
  detail = json.error?.message ?? json.message ?? text;
120
+ code = json.error?.code ?? json.code;
89
121
  } catch {
90
122
  }
91
- throw new Error(`Alma API ${method} ${path} failed (${res.status}): ${detail}`);
123
+ throw new Error(formatApiError(method, path, res.status, detail, code));
92
124
  }
93
125
  return res.json();
94
126
  }
@@ -185,7 +217,15 @@ var AlmaClient = class _AlmaClient {
185
217
  );
186
218
  if (!res.ok) {
187
219
  const text2 = await res.text().catch(() => "");
188
- throw new Error(`Chat send failed (${res.status}): ${text2}`);
220
+ let detail = text2;
221
+ let code;
222
+ try {
223
+ const json = JSON.parse(text2);
224
+ detail = json.error?.message ?? json.message ?? text2;
225
+ code = json.error?.code ?? json.code;
226
+ } catch {
227
+ }
228
+ throw new Error(formatApiError("POST", `/chat/conversations/${conversationId}/messages`, res.status, detail, code));
189
229
  }
190
230
  const text = await res.text();
191
231
  const rawEvents = text.split("\n\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olivaresai/alma-mcp",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "MCP Server for Alma by OlivaresAI — persistent memory for AI agents",
5
5
  "type": "module",
6
6
  "bin": {