@claudeink/mcp-server 0.5.0 → 0.6.1

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 (2) hide show
  1. package/dist/index.js +142 -175
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
6
6
 
7
7
  // src/tools/source.ts
8
8
  import { z } from "zod";
9
- import { mkdir as mkdir3 } from "fs/promises";
9
+ import { mkdir as mkdir3, readFile as readFile4 } from "fs/promises";
10
10
  import { join as join4 } from "path";
11
11
 
12
12
  // src/lib/config.ts
@@ -23,7 +23,7 @@ var PATHS = {
23
23
  logs: join(CLAUDEINK_DIR, "logs")
24
24
  };
25
25
  var DEFAULT_CONFIG = {
26
- apiBaseUrl: "https://api.claudeink.app",
26
+ apiBaseUrl: "https://app.claudeink.com",
27
27
  syncIntervalMs: 3e5,
28
28
  // 5 minutes
29
29
  heartbeatIntervalMs: 3e5,
@@ -39,9 +39,6 @@ var DEFAULT_TAG_QUEUE = {
39
39
  avgTagsPerItem: 0
40
40
  }
41
41
  };
42
- var DEFAULT_CRAWL_SCHEDULES = {
43
- schedules: []
44
- };
45
42
  async function ensureDir() {
46
43
  await mkdir(CLAUDEINK_DIR, { recursive: true });
47
44
  await mkdir(PATHS.logs, { recursive: true });
@@ -73,18 +70,22 @@ async function getCredentials() {
73
70
  if (!await fileExists(PATHS.credentials)) return null;
74
71
  return readJson(PATHS.credentials, null);
75
72
  }
73
+ async function saveCredentials(creds) {
74
+ await writeJson(PATHS.credentials, creds, true);
75
+ }
76
76
  async function getConfig() {
77
77
  return readJson(PATHS.config, DEFAULT_CONFIG);
78
78
  }
79
+ async function saveConfig(config) {
80
+ const current = await getConfig();
81
+ await writeJson(PATHS.config, { ...current, ...config });
82
+ }
79
83
  async function getTagQueue() {
80
84
  return readJson(PATHS.tagQueue, DEFAULT_TAG_QUEUE);
81
85
  }
82
86
  async function saveTagQueue(queue) {
83
87
  await writeJson(PATHS.tagQueue, queue);
84
88
  }
85
- async function getCrawlSchedules() {
86
- return readJson(PATHS.crawlSchedules, DEFAULT_CRAWL_SCHEDULES);
87
- }
88
89
 
89
90
  // src/lib/sources.ts
90
91
  import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
@@ -166,6 +167,7 @@ var DEFAULT_STATE = {
166
167
  published: {},
167
168
  configs: {},
168
169
  crawlerSources: {},
170
+ writingMasters: {},
169
171
  lastSyncAt: ""
170
172
  };
171
173
  async function getStatePath() {
@@ -211,11 +213,6 @@ async function moveDraftToPublished(id, data) {
211
213
  state.published[id] = data;
212
214
  await writeState(state);
213
215
  }
214
- async function updateConfig(key, data) {
215
- const state = await readState();
216
- state.configs[key] = data;
217
- await writeState(state);
218
- }
219
216
  async function updateCrawlerSource(id, data) {
220
217
  const state = await readState();
221
218
  state.crawlerSources[id] = data;
@@ -254,7 +251,13 @@ async function sourceAdd(input) {
254
251
  const filePath = join4(dir, filename);
255
252
  const meta = {
256
253
  title: input.title,
257
- source: input.url ? new URL(input.url).hostname : "manual",
254
+ source: input.url ? (() => {
255
+ try {
256
+ return new URL(input.url).hostname;
257
+ } catch {
258
+ return input.url;
259
+ }
260
+ })() : "manual",
258
261
  published: date,
259
262
  url: input.url
260
263
  };
@@ -303,14 +306,21 @@ var sourceCrawlSchema = z.object({
303
306
  sourceId: z.string().optional().describe("\u6307\u5B9A\u722C\u866B\u6E90\u540D\u79F0\uFF0C\u4E0D\u4F20\u5219\u5168\u91CF")
304
307
  });
305
308
  async function sourceCrawl(input) {
306
- const schedules = await getCrawlSchedules();
307
- if (schedules.schedules.length === 0) {
309
+ const config = await getConfig();
310
+ const configPath = join4(config.workflowDir || process.cwd(), "tools", "crawler", "config.json");
311
+ let crawlerConfig;
312
+ try {
313
+ crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
314
+ } catch {
315
+ crawlerConfig = { sources: [] };
316
+ }
317
+ if (crawlerConfig.sources.length === 0) {
308
318
  return {
309
319
  success: false,
310
320
  message: "\u6682\u65E0\u914D\u7F6E\u722C\u866B\u6E90\u3002\u8BF7\u5148\u7528 source.subscribe \u6DFB\u52A0\u3002"
311
321
  };
312
322
  }
313
- const targets = input.sourceId ? schedules.schedules.filter((s) => s.name === input.sourceId) : schedules.schedules.filter((s) => s.enabled);
323
+ const targets = input.sourceId ? crawlerConfig.sources.filter((s) => s.name === input.sourceId) : crawlerConfig.sources.filter((s) => s.enabled !== false);
314
324
  if (targets.length === 0) {
315
325
  return {
316
326
  success: false,
@@ -420,7 +430,7 @@ async function sourceTagApply(input) {
420
430
 
421
431
  // src/tools/subscribe.ts
422
432
  import { z as z2 } from "zod";
423
- import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
433
+ import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
424
434
  import { join as join5 } from "path";
425
435
  var sourceSubscribeSchema = z2.object({
426
436
  action: z2.enum(["add", "remove", "list"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
@@ -435,7 +445,7 @@ async function sourceSubscribe(input) {
435
445
  const configPath = join5(config.workflowDir || process.cwd(), "tools/crawler/config.json");
436
446
  let crawlerConfig;
437
447
  try {
438
- crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
448
+ crawlerConfig = JSON.parse(await readFile5(configPath, "utf-8"));
439
449
  } catch {
440
450
  crawlerConfig = { sources: [] };
441
451
  }
@@ -488,7 +498,7 @@ async function sourceSubscribe(input) {
488
498
  import { z as z3 } from "zod";
489
499
 
490
500
  // src/lib/drafts.ts
491
- import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir4, unlink } from "fs/promises";
501
+ import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir4, unlink } from "fs/promises";
492
502
  import { join as join6, basename } from "path";
493
503
  import matter2 from "gray-matter";
494
504
  import { glob as glob2 } from "glob";
@@ -533,7 +543,7 @@ async function saveDraft(options) {
533
543
  return { filePath, meta, content: options.content };
534
544
  }
535
545
  async function publishDraft(options) {
536
- const raw = await readFile5(options.file, "utf-8");
546
+ const raw = await readFile6(options.file, "utf-8");
537
547
  const { data, content } = matter2(raw);
538
548
  const meta = data;
539
549
  meta.status = "published";
@@ -683,6 +693,8 @@ async function analyticsPush(input) {
683
693
  sources: [],
684
694
  drafts: [],
685
695
  published: [],
696
+ configs: [],
697
+ crawlerSources: [],
686
698
  analytics: [payload]
687
699
  });
688
700
  if (!res.ok) {
@@ -704,114 +716,21 @@ var analyticsReportSchema = z4.object({
704
716
  async function analyticsReport(input) {
705
717
  return {
706
718
  success: true,
707
- message: "\u6570\u636E\u62A5\u544A\u529F\u80FD\u9700\u8981\u4E91\u7AEF Dashboard \u652F\u6301\uFF0C\u8BF7\u8BBF\u95EE https://app.claudeink.app \u67E5\u770B\u8BE6\u7EC6\u6570\u636E\u5206\u6790\u3002",
719
+ message: "\u6570\u636E\u62A5\u544A\u529F\u80FD\u9700\u8981\u4E91\u7AEF Dashboard \u652F\u6301\uFF0C\u8BF7\u8BBF\u95EE https://app.claudeink.com \u67E5\u770B\u8BE6\u7EC6\u6570\u636E\u5206\u6790\u3002",
708
720
  data: {
709
- dashboardUrl: "https://app.claudeink.app/analytics",
721
+ dashboardUrl: "https://app.claudeink.com/analytics",
710
722
  account: input.account,
711
723
  period: input.period || "30d"
712
724
  }
713
725
  };
714
726
  }
715
727
 
716
- // src/tools/account.ts
728
+ // src/tools/sync.ts
717
729
  import { z as z5 } from "zod";
718
- import { readFile as readFile6, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
730
+ import { writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
719
731
  import { join as join7 } from "path";
720
- var accountCreateSchema = z5.object({
721
- name: z5.string().describe("\u8D26\u53F7\u540D\u79F0\uFF08\u82F1\u6587\u5C0F\u5199\uFF0C\u7528\u4F5C\u6587\u4EF6\u540D\uFF09"),
722
- platform: z5.string().describe("\u5E73\u53F0\u540D\u79F0\uFF0C\u5982 wechat, xiaohongshu"),
723
- displayName: z5.string().optional().describe("\u663E\u793A\u540D\u79F0"),
724
- domains: z5.array(z5.string()).describe("\u5185\u5BB9\u9886\u57DF"),
725
- description: z5.string().optional().describe("\u8D26\u53F7\u5B9A\u4F4D\u63CF\u8FF0"),
726
- profileUrl: z5.string().optional().describe("\u8D26\u53F7\u5728\u5E73\u53F0\u4E0A\u7684\u4E3B\u9875 URL")
727
- });
728
- async function accountCreate(input) {
729
- const config = await getConfig();
730
- const yamlPath = join7(config.workflowDir, "accounts", `${input.name}.yaml`);
731
- try {
732
- await readFile6(yamlPath);
733
- return { success: false, message: `\u8D26\u53F7 ${input.name} \u5DF2\u5B58\u5728` };
734
- } catch {
735
- }
736
- let template = "";
737
- try {
738
- template = await readFile6(
739
- join7(config.workflowDir, "accounts", "_template.yaml"),
740
- "utf-8"
741
- );
742
- } catch {
743
- template = defaultTemplate();
744
- }
745
- const yamlContent = template.replace(/name:\s*""/, `name: "${input.displayName || input.name}"`).replace(/id:\s*""/, `id: "${input.name}"`).replace(/platform:\s*""/, `platform: "${input.platform}"`).replace(/profile_url:\s*""/, `profile_url: "${input.profileUrl || ""}"`).replace(/description:\s*""/, `description: "${input.description || ""}"`).replace(
746
- /domains:\s*\n\s*- ""/,
747
- `domains:
748
- ${input.domains.map((d) => ` - "${d}"`).join("\n")}`
749
- );
750
- await writeFile6(yamlPath, yamlContent, "utf-8");
751
- const accountDir = join7(config.workflowDir, "accounts", input.name);
752
- await mkdir5(join7(accountDir, "drafts"), { recursive: true });
753
- await mkdir5(join7(accountDir, "published"), { recursive: true });
754
- await mkdir5(join7(accountDir, "assets"), { recursive: true });
755
- await updateConfig(`account:${input.name}`, {
756
- type: "account",
757
- name: input.name,
758
- displayName: input.displayName || input.name,
759
- content: yamlContent,
760
- metadata: { platform: input.platform, profileUrl: input.profileUrl || "" },
761
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
762
- });
763
- return {
764
- success: true,
765
- message: `\u8D26\u53F7 ${input.name} \u5DF2\u521B\u5EFA
766
- \u914D\u7F6E: accounts/${input.name}.yaml
767
- \u76EE\u5F55: accounts/${input.name}/drafts/, published/, assets/`,
768
- data: {
769
- config: yamlPath,
770
- directories: [
771
- `accounts/${input.name}/drafts/`,
772
- `accounts/${input.name}/published/`,
773
- `accounts/${input.name}/assets/`
774
- ]
775
- }
776
- };
777
- }
778
- function defaultTemplate() {
779
- return `# ClaudeInk \u8D26\u53F7\u914D\u7F6E
780
- name: ""
781
- id: ""
782
- platform: ""
783
- profile_url: ""
784
- description: ""
785
-
786
- domains:
787
- - ""
788
-
789
- style:
790
- tone: "\u5E73\u5B9E"
791
- voice: "\u53E3\u8BED\u5316"
792
- formality: "medium"
793
- emotion: "\u9002\u5EA6"
794
- humor: "\u5076\u5C14"
795
- language: "zh-CN"
796
-
797
- persona:
798
- role: ""
799
- background: ""
800
- first_person: "\u6211"
801
-
802
- paths:
803
- drafts: "accounts/{id}/drafts/"
804
- published: "accounts/{id}/published/"
805
- assets: "accounts/{id}/assets/"
806
- `;
807
- }
808
-
809
- // src/tools/sync.ts
810
- import { z as z6 } from "zod";
811
- import { writeFile as writeFile7 } from "fs/promises";
812
- import { join as join8 } from "path";
813
- var syncPushSchema = z6.object({
814
- workDir: z6.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
732
+ var syncPushSchema = z5.object({
733
+ workDir: z5.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
815
734
  });
816
735
  async function syncPush(input) {
817
736
  const creds = await getCredentials();
@@ -899,8 +818,8 @@ async function syncPush(input) {
899
818
  return { success: false, message: `\u540C\u6B65\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}` };
900
819
  }
901
820
  }
902
- var syncPullSchema = z6.object({
903
- workDir: z6.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55")
821
+ var syncPullSchema = z5.object({
822
+ workDir: z5.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55")
904
823
  });
905
824
  async function syncPull(input) {
906
825
  const creds = await getCredentials();
@@ -925,37 +844,77 @@ async function syncPull(input) {
925
844
  }
926
845
  let updated = 0;
927
846
  const state = await readState();
928
- for (const config2 of cloudData.configs) {
929
- const stateKey = `${config2.type}:${config2.name}`;
847
+ for (const cfgItem of cloudData.configs) {
848
+ const stateKey = `${cfgItem.type}:${cfgItem.name}`;
930
849
  const localUpdatedAt = state.configs[stateKey]?.updatedAt || "";
931
- if (!localUpdatedAt || config2.updatedAt > localUpdatedAt) {
850
+ if (!localUpdatedAt || cfgItem.updatedAt > localUpdatedAt) {
932
851
  let filePath = "";
933
- if (config2.type === "base_rules") {
934
- filePath = join8(workDir, "base-rules.md");
935
- } else if (config2.type === "platform") {
936
- filePath = join8(workDir, "platforms", `${config2.name}.md`);
937
- } else if (config2.type === "account") {
938
- filePath = join8(workDir, "accounts", `${config2.name}.yaml`);
852
+ if (cfgItem.type === "base_rules") {
853
+ filePath = join7(workDir, "base-rules.md");
854
+ } else if (cfgItem.type === "platform") {
855
+ filePath = join7(workDir, "platforms", `${cfgItem.name}.md`);
856
+ } else if (cfgItem.type === "account") {
857
+ filePath = join7(workDir, "accounts", `${cfgItem.name}.yaml`);
939
858
  }
940
- if (filePath && config2.content) {
941
- await writeFile7(filePath, config2.content, "utf-8");
859
+ if (filePath && cfgItem.content) {
860
+ await writeFile6(filePath, cfgItem.content, "utf-8");
942
861
  state.configs[stateKey] = {
943
- type: config2.type,
944
- name: config2.name,
945
- displayName: config2.displayName,
946
- content: config2.content,
947
- metadata: config2.metadata || {},
948
- updatedAt: config2.updatedAt
862
+ type: cfgItem.type,
863
+ name: cfgItem.name,
864
+ displayName: cfgItem.displayName,
865
+ content: cfgItem.content,
866
+ metadata: cfgItem.metadata || {},
867
+ updatedAt: cfgItem.updatedAt
949
868
  };
950
869
  updated++;
951
870
  }
952
871
  }
953
872
  }
873
+ let crawlerCount = 0;
874
+ state.crawlerSources = {};
875
+ for (const cfg of cloudData.configs || []) {
876
+ if (cfg.type === "crawler" && cfg.content) {
877
+ try {
878
+ const sources = JSON.parse(cfg.content);
879
+ for (const s of sources) {
880
+ state.crawlerSources[s.id] = {
881
+ name: s.name,
882
+ url: s.url,
883
+ type: s.type || "rss",
884
+ icon: s.icon || "",
885
+ enabled: s.enabled !== false
886
+ };
887
+ }
888
+ const crawlerDir = join7(workDir, "tools", "crawler");
889
+ await mkdir5(crawlerDir, { recursive: true });
890
+ const crawlerConfigPath = join7(crawlerDir, "config.json");
891
+ await writeFile6(crawlerConfigPath, JSON.stringify({ sources }, null, 2), "utf-8");
892
+ crawlerCount = sources.length;
893
+ } catch (e) {
894
+ console.error("[sync.pull] Failed to parse crawler sources:", e);
895
+ }
896
+ }
897
+ }
898
+ if (cloudData.writingMasters && Object.keys(cloudData.writingMasters).length > 0) {
899
+ state.writingMasters = state.writingMasters || {};
900
+ for (const [accountName, master] of Object.entries(cloudData.writingMasters)) {
901
+ state.writingMasters[accountName] = {
902
+ id: master.id,
903
+ name: master.name,
904
+ stylePrompt: master.stylePrompt
905
+ };
906
+ }
907
+ }
954
908
  await replaceState(state);
909
+ const masterCount = cloudData.writingMasters ? Object.keys(cloudData.writingMasters).length : 0;
955
910
  return {
956
911
  success: true,
957
- message: updated > 0 ? `\u2705 \u4ECE\u4E91\u7AEF\u540C\u6B65\u4E86 ${updated} \u4E2A\u914D\u7F6E\u6587\u4EF6` : "\u672C\u5730\u914D\u7F6E\u5DF2\u662F\u6700\u65B0\uFF0C\u65E0\u9700\u66F4\u65B0",
958
- data: { updated }
912
+ message: updated > 0 || masterCount > 0 || crawlerCount > 0 ? [
913
+ `\u2705 \u4ECE\u4E91\u7AEF\u540C\u6B65\u4E86 ${updated} \u4E2A\u914D\u7F6E\u6587\u4EF6`,
914
+ crawlerCount > 0 ? ` \u8BA2\u9605\u6E90: ${crawlerCount} \u4E2A` : "",
915
+ masterCount > 0 ? ` \u5199\u4F5C\u5927\u5E08: ${masterCount} \u4E2A` : ""
916
+ ].filter(Boolean).join("\n") : "\u672C\u5730\u914D\u7F6E\u5DF2\u662F\u6700\u65B0\uFF0C\u65E0\u9700\u66F4\u65B0",
917
+ data: { updated, crawlerSources: crawlerCount, writingMasters: masterCount }
959
918
  };
960
919
  } catch (err) {
961
920
  return { success: false, message: `\u62C9\u53D6\u9519\u8BEF: ${err instanceof Error ? err.message : err}` };
@@ -963,16 +922,17 @@ async function syncPull(input) {
963
922
  }
964
923
 
965
924
  // src/tools/workflow.ts
966
- import { z as z7 } from "zod";
967
- import { cp, mkdir as mkdir6, access as access2, writeFile as writeFile8 } from "fs/promises";
968
- import { join as join9, dirname } from "path";
925
+ import { z as z6 } from "zod";
926
+ import { cp, mkdir as mkdir6, access as access2 } from "fs/promises";
927
+ import { join as join8, dirname } from "path";
969
928
  import { fileURLToPath } from "url";
929
+ var DEFAULT_API_BASE_URL = "https://app.claudeink.com";
970
930
  var __filename = fileURLToPath(import.meta.url);
971
931
  var __dirname = dirname(__filename);
972
- var WORKFLOW_SRC = join9(__dirname, "..", "workflow");
973
- var workflowInitSchema = z7.object({
974
- workDir: z7.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
975
- licenseKey: z7.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
932
+ var WORKFLOW_SRC = join8(__dirname, "..", "workflow");
933
+ var workflowInitSchema = z6.object({
934
+ workDir: z6.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
935
+ licenseKey: z6.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
976
936
  });
977
937
  async function workflowInit(input) {
978
938
  const cwd = input.workDir;
@@ -980,8 +940,8 @@ async function workflowInit(input) {
980
940
  try {
981
941
  const items = ["CLAUDE.md", "base-rules.md", "platforms", "accounts", "tools"];
982
942
  for (const item of items) {
983
- const src = join9(WORKFLOW_SRC, item);
984
- const dest = join9(cwd, item);
943
+ const src = join8(WORKFLOW_SRC, item);
944
+ const dest = join8(cwd, item);
985
945
  try {
986
946
  await access2(dest);
987
947
  results.push(`\u23ED\uFE0F ${item} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7`);
@@ -1000,34 +960,45 @@ async function workflowInit(input) {
1000
960
  ".claudeink"
1001
961
  ];
1002
962
  for (const dir of dirs) {
1003
- await mkdir6(join9(cwd, dir), { recursive: true });
963
+ await mkdir6(join8(cwd, dir), { recursive: true });
1004
964
  }
1005
965
  results.push("\u2705 \u8FD0\u884C\u65F6\u76EE\u5F55\u5DF2\u521B\u5EFA");
1006
- const emptyState = {
1007
- sources: {},
1008
- drafts: {},
1009
- published: {},
1010
- configs: {},
1011
- crawlerSources: {},
1012
- lastSyncAt: ""
1013
- };
1014
- await replaceState(emptyState);
1015
- results.push("\u2705 \u672C\u5730\u72B6\u6001\u8868\u5DF2\u521D\u59CB\u5316");
966
+ await saveConfig({ workflowDir: cwd });
967
+ const statePath = join8(cwd, ".claudeink", "state.json");
968
+ try {
969
+ await access2(statePath);
970
+ results.push("\u23ED\uFE0F \u672C\u5730\u72B6\u6001\u8868\u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7");
971
+ } catch {
972
+ const emptyState = {
973
+ sources: {},
974
+ drafts: {},
975
+ published: {},
976
+ configs: {},
977
+ crawlerSources: {},
978
+ writingMasters: {},
979
+ lastSyncAt: ""
980
+ };
981
+ await replaceState(emptyState);
982
+ results.push("\u2705 \u672C\u5730\u72B6\u6001\u8868\u5DF2\u521D\u59CB\u5316");
983
+ }
1016
984
  let activated = false;
1017
985
  if (input.licenseKey) {
1018
986
  try {
1019
- const res = await fetch("https://app.claudeink.com/api/auth/activate", {
987
+ const activateUrl = `${DEFAULT_API_BASE_URL}/api/auth/activate`;
988
+ const res = await fetch(activateUrl, {
1020
989
  method: "POST",
1021
990
  headers: { "Content-Type": "application/json" },
1022
991
  body: JSON.stringify({ key: input.licenseKey })
1023
992
  });
1024
993
  const data = await res.json();
1025
994
  if (data.userId) {
1026
- await writeFile8(
1027
- join9(cwd, ".claudeink", "credentials.json"),
1028
- JSON.stringify(data, null, 2),
1029
- { mode: 384 }
1030
- );
995
+ await saveCredentials({
996
+ licenseKey: input.licenseKey,
997
+ token: data.token,
998
+ userId: data.userId,
999
+ plan: data.plan,
1000
+ expiresAt: data.expiresAt
1001
+ });
1031
1002
  results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
1032
1003
  activated = true;
1033
1004
  } else {
@@ -1050,10 +1021,10 @@ async function workflowInit(input) {
1050
1021
  }
1051
1022
  }
1052
1023
  try {
1053
- await access2(join9(cwd, "tools", "crawler", "package.json"));
1024
+ await access2(join8(cwd, "tools", "crawler", "package.json"));
1054
1025
  const { execSync } = await import("child_process");
1055
1026
  execSync("npm install --silent", {
1056
- cwd: join9(cwd, "tools", "crawler"),
1027
+ cwd: join8(cwd, "tools", "crawler"),
1057
1028
  stdio: "pipe"
1058
1029
  });
1059
1030
  results.push("\u2705 \u722C\u866B\u4F9D\u8D56\u5DF2\u5B89\u88C5");
@@ -1083,7 +1054,7 @@ async function workflowInit(input) {
1083
1054
  // src/index.ts
1084
1055
  var server = new McpServer({
1085
1056
  name: "ClaudeInk",
1086
- version: "0.5.0"
1057
+ version: "0.6.1"
1087
1058
  });
1088
1059
  server.tool("workflow.init", "\u521D\u59CB\u5316\u5199\u4F5C\u5DE5\u4F5C\u6D41\uFF08\u91CA\u653E\u4E09\u5C42\u914D\u7F6E + \u6FC0\u6D3B License + \u81EA\u52A8\u540C\u6B65\u4E91\u7AEF\u914D\u7F6E\uFF09", workflowInitSchema.shape, async (input) => {
1089
1060
  const result = await workflowInit(input);
@@ -1133,14 +1104,10 @@ server.tool("analytics.report", "\u83B7\u53D6\u6570\u636E\u5206\u6790\u62A5\u544
1133
1104
  const result = await analyticsReport(input);
1134
1105
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
1135
1106
  });
1136
- server.tool("account.create", "\u521B\u5EFA\u65B0\u81EA\u5A92\u4F53\u8D26\u53F7", accountCreateSchema.shape, async (input) => {
1137
- const result = await accountCreate(input);
1138
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
1139
- });
1140
1107
  async function main() {
1141
1108
  const transport = new StdioServerTransport();
1142
1109
  await server.connect(transport);
1143
- console.error("[ClaudeInk MCP] Server started on stdio (13 tools)");
1110
+ console.error("[ClaudeInk MCP] Server started on stdio (12 tools)");
1144
1111
  }
1145
1112
  main().catch((err) => {
1146
1113
  console.error("[ClaudeInk MCP] Fatal error:", err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeink/mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "ClaudeInk MCP Server - 自媒体多平台写作系统的本地 MCP 服务,连接 Claude 与云端后台",
5
5
  "mcpName": "io.github.weekdmond/claudeink",
6
6
  "type": "module",