@floomhq/floom-mcp-sync 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -6,7 +6,13 @@ Tiny MCP server for Floom skills. This package is part of the Floom Version 1 sy
6
6
  npx -y @floomhq/floom-mcp-sync
7
7
  ```
8
8
 
9
- On startup it reads `~/.floom/config.json`, fetches published, saved, and subscribed library skills, and writes missing files to `~/.claude/skills/`. The background sync behavior is a Version 1 preview path.
9
+ On startup it reads `~/.floom/config.json`, fetches published, saved, and followed library skills, and writes missing files to the configured local skills directory. Account-backed sync requires `npx -y @floomhq/floom login`. Public and unlisted shared-link installs still work through `floom_install_skill` without an account. The background sync behavior is a Version 1 preview path.
10
+
11
+ Targets:
12
+
13
+ - default: Claude Code, `~/.claude/skills/`
14
+ - Codex: `FLOOM_TARGET=codex npx -y @floomhq/floom-mcp-sync`, `~/.codex/skills/`
15
+ - direct override: `FLOOM_SKILLS_DIR=/path/to/skills npx -y @floomhq/floom-mcp-sync`
10
16
 
11
17
  Sync stores a machine-local manifest next to the Floom CLI config at `~/.floom/sync-manifest.json`.
12
18
  Version 1 sync does not replace existing local Markdown files. Remote updates, existing untracked
@@ -22,15 +28,15 @@ Tools:
22
28
  - `floom_search_skills(query, library?, type?, limit?)` searches `/api/v1/search` and returns compact skill hits with slug, title, description, library placement, folder, and install URL.
23
29
  - `type`: `knowledge`, `instruction`, `workflow`, or `skill`
24
30
  - `limit`: 1-50
25
- - `floom_install_skill(slug)` fetches `/s/<slug>.md` and writes it locally.
26
- - `floom_publish_skill(name, content, description?, visibility?, asset_type?, installs_as?, version?)` publishes Markdown through `/api/skills`.
31
+ - `floom_install_skill(slug)` fetches `/s/<slug>.md` and writes it locally. Public and unlisted skills do not require an account.
32
+ - `floom_publish_skill(name, content, description?, visibility?, asset_type?, installs_as?, version?)` publishes Markdown through `/api/skills` for the signed-in Floom account.
27
33
  - `asset_type`: `knowledge`, `instruction`, `workflow`, or `skill` (default `skill`)
28
34
  - `installs_as`: `claude_skill`, `memory`, `rule`, `codex_instruction`, `opencode_instruction`, `cursor_rule`, or `other` (default `claude_skill`)
29
35
  - `version`: optional label like `1.0.0` or `v1-preview`
30
36
 
31
37
  - `floom_list_libraries()` lists public Floom libraries.
32
- - `floom_subscribe_library(slug)` subscribes the signed-in user so the library syncs locally.
33
- - `floom_unsubscribe_library(slug)` removes that subscription.
38
+ - `floom_subscribe_library(slug)` follows a library for the signed-in user so the library syncs locally.
39
+ - `floom_unsubscribe_library(slug)` unfollows that library.
34
40
  - `floom_move_skill(slug, folder, tags?)` sets the signed-in user's local folder/tags override.
35
41
 
36
42
  Team workspaces, share invites, and role-based library access are planned for a later Floom version.
package/dist/lib/paths.js CHANGED
@@ -4,7 +4,21 @@ import { assertValidSlug } from "./slug.js";
4
4
  export function configPath() {
5
5
  return process.env.FLOOM_CONFIG_PATH ?? join(homedir(), ".floom", "config.json");
6
6
  }
7
+ export function agentTarget() {
8
+ const raw = (process.env.FLOOM_TARGET ?? process.env.FLOOM_AGENT_TARGET ?? "claude").toLowerCase();
9
+ if (raw === "codex")
10
+ return "codex";
11
+ if (raw === "claude")
12
+ return "claude";
13
+ throw new Error("Invalid FLOOM_TARGET. Use claude or codex.");
14
+ }
7
15
  export function skillsDir() {
16
+ if (process.env.FLOOM_SKILLS_DIR)
17
+ return process.env.FLOOM_SKILLS_DIR;
18
+ if (agentTarget() === "codex") {
19
+ const codexHome = process.env.CODEX_HOME ?? join(homedir(), ".codex");
20
+ return process.env.CODEX_SKILLS_DIR ?? join(codexHome, "skills");
21
+ }
8
22
  return process.env.CLAUDE_SKILLS_DIR ?? join(homedir(), ".claude", "skills");
9
23
  }
10
24
  export function skillPath(slug) {
package/dist/server.js CHANGED
@@ -6,7 +6,8 @@ import { installSkill } from "./tools/install.js";
6
6
  import { publishSkill } from "./tools/publish.js";
7
7
  import { listLibraries, moveSkill, subscribeLibrary, unsubscribeLibrary, } from "./tools/libraries.js";
8
8
  import { searchSkills } from "./tools/search.js";
9
- const SERVER_VERSION = "1.0.4";
9
+ import { agentTarget, skillsDir } from "./lib/paths.js";
10
+ const SERVER_VERSION = "1.0.6";
10
11
  const DEFAULT_INTERVAL_MS = 60_000;
11
12
  const MIN_INTERVAL_MS = 10_000;
12
13
  const VERSION_RE = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;
@@ -33,7 +34,9 @@ Usage
33
34
 
34
35
  Behavior
35
36
  Starts a stdio MCP server.
36
- Syncs published, saved, and subscribed library skills into ~/.claude/skills/.
37
+ Syncs published, saved, and followed library skills into the configured local skills directory.
38
+ Requires a signed-in Floom CLI account for account-backed sync.
39
+ Public and unlisted shared-link installs still work through floom_install_skill without an account.
37
40
  Polls for updates while the MCP process is running.
38
41
 
39
42
  Options
@@ -42,6 +45,10 @@ Options
42
45
 
43
46
  Env
44
47
  FLOOM_API_URL Override the API host.
48
+ FLOOM_TARGET claude or codex. Default: claude.
49
+ FLOOM_SKILLS_DIR Override the local skills directory directly.
50
+ CLAUDE_SKILLS_DIR Override Claude's skills directory.
51
+ CODEX_SKILLS_DIR Override Codex's skills directory.
45
52
  FLOOM_SYNC_INTERVAL_MS Poll interval in milliseconds. Minimum: 10000.
46
53
  `.trimStart();
47
54
  }
@@ -96,7 +103,7 @@ function toolList() {
96
103
  tools: [
97
104
  {
98
105
  name: "floom_search_skills",
99
- description: "Search public Floom skills through the live API.",
106
+ description: "Search public Floom skills before recreating reusable behavior from scratch.",
100
107
  inputSchema: {
101
108
  type: "object",
102
109
  properties: {
@@ -111,7 +118,7 @@ function toolList() {
111
118
  },
112
119
  {
113
120
  name: "floom_install_skill",
114
- description: "Fetch a Floom skill by slug and install it into ~/.claude/skills/.",
121
+ description: "Fetch a Floom skill by slug and install it into the configured local skills directory. Public and unlisted links do not require an account.",
115
122
  inputSchema: {
116
123
  type: "object",
117
124
  properties: {
@@ -123,7 +130,7 @@ function toolList() {
123
130
  },
124
131
  {
125
132
  name: "floom_publish_skill",
126
- description: "Publish Markdown content to Floom as a skill.",
133
+ description: "Publish Markdown content to the signed-in Floom account as a skill. Requires CLI login/config.",
127
134
  inputSchema: {
128
135
  type: "object",
129
136
  properties: {
@@ -150,7 +157,7 @@ function toolList() {
150
157
  },
151
158
  {
152
159
  name: "floom_subscribe_library",
153
- description: "Subscribe the signed-in user to a Floom library so it syncs locally.",
160
+ description: "Follow a Floom library for the signed-in user so its skills sync locally.",
154
161
  inputSchema: {
155
162
  type: "object",
156
163
  properties: {
@@ -162,7 +169,7 @@ function toolList() {
162
169
  },
163
170
  {
164
171
  name: "floom_unsubscribe_library",
165
- description: "Unsubscribe the signed-in user from a Floom library.",
172
+ description: "Unfollow a Floom library for the signed-in user.",
166
173
  inputSchema: {
167
174
  type: "object",
168
175
  properties: {
@@ -319,7 +326,12 @@ async function handleRequest(message) {
319
326
  stdout.write(response(id, {
320
327
  protocolVersion: "2025-06-18",
321
328
  capabilities: { tools: {} },
322
- serverInfo: { name: "floom-mcp-sync", version: SERVER_VERSION },
329
+ serverInfo: {
330
+ name: "floom-mcp-sync",
331
+ version: SERVER_VERSION,
332
+ target: agentTarget(),
333
+ skillsDir: skillsDir(),
334
+ },
323
335
  }));
324
336
  return;
325
337
  }
@@ -345,7 +357,7 @@ async function main() {
345
357
  if (handleCliArgs(process.argv.slice(2)))
346
358
  return;
347
359
  const intervalMs = resolvePollIntervalMs();
348
- process.stderr.write(`[floom] starting sync poller (interval ${intervalMs}ms)\n`);
360
+ process.stderr.write(`[floom] starting sync poller for ${agentTarget()} at ${skillsDir()} (interval ${intervalMs}ms)\n`);
349
361
  const syncState = { inFlight: true };
350
362
  void autoSync().catch((err) => {
351
363
  process.stderr.write(`[floom] initial sync failed: ${err instanceof Error ? err.message : String(err)}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/floom-mcp-sync",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Lightweight Floom MCP server for installing, publishing, and startup-syncing skills.",
5
5
  "license": "MIT",
6
6
  "type": "module",