@claudeink/mcp-server 2.0.1 → 2.1.0

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/dist/cli.js +136 -162
  2. package/dist/index.js +129 -155
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -28975,7 +28975,7 @@ async function workflowInit(input) {
28975
28975
  }
28976
28976
  await writeState(state);
28977
28977
  results.push("\u2705 state.json");
28978
- if (activated) {
28978
+ if (state.credentials?.token) {
28979
28979
  try {
28980
28980
  const pullResult = await syncPull({ workDir: cwd });
28981
28981
  if (pullResult.success) {
@@ -32757,46 +32757,12 @@ var init_knowledge = __esm({
32757
32757
  }
32758
32758
  });
32759
32759
 
32760
- // src/lib/push.ts
32761
- function fireAndForgetPush(payload) {
32762
- doPush(payload).catch(() => {
32763
- });
32764
- }
32765
- async function doPush(partial2) {
32766
- const creds = await getCredentials();
32767
- if (!creds?.token) return;
32768
- const config2 = await getConfig();
32769
- const payload = {
32770
- knowledge: partial2.knowledge || [],
32771
- crawlerSources: partial2.crawlerSources || []
32772
- };
32773
- await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
32774
- try {
32775
- await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
32776
- method: "POST",
32777
- headers: {
32778
- "Content-Type": "application/json",
32779
- Authorization: `Bearer ${creds.token}`
32780
- },
32781
- body: JSON.stringify(payload)
32782
- });
32783
- } catch (err) {
32784
- await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
32785
- }
32786
- }
32787
- var init_push = __esm({
32788
- "src/lib/push.ts"() {
32789
- "use strict";
32790
- init_state();
32791
- init_logger();
32792
- }
32793
- });
32794
-
32795
32760
  // src/tools/ink.ts
32796
32761
  import { readFile as readFile3 } from "fs/promises";
32797
32762
  import { extname } from "path";
32798
- async function inkSave(input) {
32763
+ async function inkWrite(input) {
32799
32764
  try {
32765
+ let localId;
32800
32766
  if (input.id) {
32801
32767
  const result = await updateKnowledgeFile(input.id, {
32802
32768
  title: input.title,
@@ -32805,99 +32771,30 @@ async function inkSave(input) {
32805
32771
  category: input.category
32806
32772
  });
32807
32773
  if (!result) {
32808
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
32809
- }
32810
- fireAndForgetPush({
32811
- knowledge: [{
32812
- id: result.meta.id,
32813
- title: result.meta.title,
32814
- tags: result.meta.tags,
32815
- category: result.meta.category,
32816
- source_type: result.meta.source_type,
32817
- url: result.meta.url,
32818
- created_at: result.meta.created_at,
32819
- updated_at: result.meta.updated_at
32820
- }]
32821
- });
32822
- await log("INFO", "ink.save", `updated id=${input.id} title="${input.title}"`);
32823
- return {
32824
- success: true,
32825
- message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D`,
32826
- data: { id: result.meta.id }
32827
- };
32828
- }
32829
- const { id } = await saveKnowledge({
32830
- content: input.content,
32831
- title: input.title,
32832
- tags: input.tags,
32833
- category: input.category,
32834
- source_type: input.source_type,
32835
- url: input.url
32836
- });
32837
- fireAndForgetPush({
32838
- knowledge: [{
32839
- id,
32774
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u672C\u5730\u6761\u76EE` };
32775
+ }
32776
+ localId = input.id;
32777
+ } else {
32778
+ const { id } = await saveKnowledge({
32779
+ content: input.content,
32840
32780
  title: input.title,
32841
32781
  tags: input.tags,
32842
32782
  category: input.category,
32843
32783
  source_type: input.source_type,
32844
- url: input.url,
32845
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
32846
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
32847
- }]
32848
- });
32849
- await log("INFO", "ink.save", `created id=${id} title="${input.title}" tags=${JSON.stringify(input.tags)}`);
32850
- return {
32851
- success: true,
32852
- message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D`,
32853
- data: { id }
32854
- };
32855
- } catch (err) {
32856
- await log("ERROR", "ink.save", `failed: ${err.message}`);
32857
- return { success: false, message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}` };
32858
- }
32859
- }
32860
- async function inkDelete(input) {
32861
- try {
32862
- if (!input.confirm) {
32863
- const index = await readIndex();
32864
- const entry = index.entries[input.id];
32865
- if (!entry) {
32866
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
32867
- }
32784
+ url: input.url
32785
+ });
32786
+ localId = id;
32787
+ }
32788
+ const creds = await getCredentials();
32789
+ if (!creds?.token) {
32790
+ await log("INFO", "ink.write", `saved locally id=${localId} title="${input.title}" (no cloud auth)`);
32868
32791
  return {
32869
- success: false,
32870
- message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
32871
- data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
32792
+ success: true,
32793
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\u5230\u672C\u5730\uFF08\u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7\u4E91\u7AEF\u540C\u6B65\uFF09`,
32794
+ data: { id: localId }
32872
32795
  };
32873
32796
  }
32874
- const deleted = await deleteKnowledgeFile(input.id);
32875
- if (!deleted) {
32876
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
32877
- }
32878
- fireAndForgetPush({
32879
- knowledge: [{
32880
- id: input.id,
32881
- title: "",
32882
- tags: [],
32883
- category: "reference",
32884
- source_type: "conversation",
32885
- created_at: "",
32886
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
32887
- }]
32888
- });
32889
- await log("INFO", "ink.delete", `deleted id=${input.id}`);
32890
- return { success: true, message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`, data: { id: input.id } };
32891
- } catch (err) {
32892
- await log("ERROR", "ink.delete", `failed: ${err.message}`);
32893
- return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
32894
- }
32895
- }
32896
- async function inkWrite(input) {
32897
- const creds = await getCredentials();
32898
- if (!creds?.token) return { success: false, message: "\u672A\u8BA4\u8BC1\uFF0C\u8BF7\u5148\u8FD0\u884C ink.init" };
32899
- const config2 = await getConfig();
32900
- try {
32797
+ const config2 = await getConfig();
32901
32798
  let coverUrl = input.cover || null;
32902
32799
  if (coverUrl) {
32903
32800
  if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
@@ -32929,24 +32826,71 @@ async function inkWrite(input) {
32929
32826
  tags: input.tags,
32930
32827
  category: input.category,
32931
32828
  excerpt,
32932
- source_ids: input.source_ids
32829
+ source_type: input.source_type,
32830
+ url: input.url,
32831
+ source_ids: input.source_ids,
32832
+ local_id: localId
32933
32833
  })
32934
32834
  });
32935
32835
  if (!res.ok) {
32936
32836
  const err = await res.text();
32937
- await log("ERROR", "ink.write", `save failed: ${err}`);
32938
- return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err}` };
32837
+ await log("ERROR", "ink.write", `cloud save failed: ${err}`);
32838
+ return {
32839
+ success: true,
32840
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${err}`,
32841
+ data: { id: localId }
32842
+ };
32939
32843
  }
32940
32844
  const data = await res.json();
32941
- await log("INFO", "ink.write", `saved article="${input.title}" id=${data.id} slug=${data.slug}`);
32845
+ await log("INFO", "ink.write", `saved id=${localId} cloud_id=${data.id} title="${input.title}"`);
32942
32846
  return {
32943
32847
  success: true,
32944
- message: `\u6587\u7AE0\u300C${input.title}\u300D\u5DF2\u4FDD\u5B58\u4E3A\u8349\u7A3F\uFF0C\u8BF7\u5230 Dashboard \u53D1\u5E03`,
32945
- data: { id: data.id, slug: data.slug, status: data.status }
32848
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09`,
32849
+ data: { id: localId, cloud_id: data.id, slug: data.slug, status: data.status }
32946
32850
  };
32947
32851
  } catch (err) {
32948
32852
  await log("ERROR", "ink.write", `failed: ${err.message}`);
32949
- return { success: false, message: `\u5199\u6587\u7AE0\u5931\u8D25: ${err.message}` };
32853
+ return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err.message}` };
32854
+ }
32855
+ }
32856
+ async function inkDelete(input) {
32857
+ try {
32858
+ if (!input.confirm) {
32859
+ const index = await readIndex();
32860
+ const entry = index.entries[input.id];
32861
+ if (!entry) {
32862
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
32863
+ }
32864
+ return {
32865
+ success: false,
32866
+ message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
32867
+ data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
32868
+ };
32869
+ }
32870
+ const deleted = await deleteKnowledgeFile(input.id);
32871
+ if (!deleted) {
32872
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
32873
+ }
32874
+ try {
32875
+ const creds = await getCredentials();
32876
+ if (creds?.token) {
32877
+ const config2 = await getConfig();
32878
+ await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
32879
+ method: "DELETE",
32880
+ headers: {
32881
+ "Content-Type": "application/json",
32882
+ Authorization: `Bearer ${creds.token}`
32883
+ },
32884
+ body: JSON.stringify({ local_id: input.id })
32885
+ });
32886
+ }
32887
+ } catch {
32888
+ }
32889
+ await log("INFO", "ink.delete", `deleted id=${input.id}`);
32890
+ return { success: true, message: `\u5DF2\u5220\u9664 ${input.id}`, data: { id: input.id } };
32891
+ } catch (err) {
32892
+ await log("ERROR", "ink.delete", `failed: ${err.message}`);
32893
+ return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
32950
32894
  }
32951
32895
  }
32952
32896
  async function inkTags(input) {
@@ -32967,12 +32911,12 @@ async function inkTags(input) {
32967
32911
  }
32968
32912
  const count = await renameTag(input.tag, input.new_tag);
32969
32913
  if (count === 0) {
32970
- return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5` };
32914
+ return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u6761\u76EE` };
32971
32915
  }
32972
32916
  await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
32973
32917
  return {
32974
32918
  success: true,
32975
- message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
32919
+ message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
32976
32920
  data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
32977
32921
  };
32978
32922
  }
@@ -32982,12 +32926,12 @@ async function inkTags(input) {
32982
32926
  }
32983
32927
  const count = await mergeTags(input.source_tags, input.new_tag);
32984
32928
  if (count === 0) {
32985
- return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5" };
32929
+ return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u6761\u76EE" };
32986
32930
  }
32987
32931
  await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
32988
32932
  return {
32989
32933
  success: true,
32990
- message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
32934
+ message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
32991
32935
  data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
32992
32936
  };
32993
32937
  }
@@ -33052,37 +32996,30 @@ async function uploadImageFromUrl(imageUrl, type, token, apiBase) {
33052
32996
  return { success: false, error: err.message };
33053
32997
  }
33054
32998
  }
33055
- var inkSaveSchema, inkDeleteSchema, inkWriteSchema, inkTagsSchema;
32999
+ var inkWriteSchema, inkDeleteSchema, inkTagsSchema;
33056
33000
  var init_ink = __esm({
33057
33001
  "src/tools/ink.ts"() {
33058
33002
  "use strict";
33059
33003
  init_zod();
33060
33004
  init_knowledge();
33061
- init_push();
33062
33005
  init_state();
33063
33006
  init_logger();
33064
- inkSaveSchema = external_exports.object({
33065
- id: external_exports.string().optional().describe("\u77E5\u8BC6\u7247\u6BB5 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
33066
- content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
33067
- title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
33007
+ inkWriteSchema = external_exports.object({
33008
+ id: external_exports.string().optional().describe("\u672C\u5730 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\u5DF2\u6709\u6761\u76EE\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
33009
+ title: external_exports.string().describe("\u6807\u9898"),
33010
+ content: external_exports.string().describe("Markdown \u5168\u6587"),
33068
33011
  tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
33069
33012
  category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
33070
33013
  source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
33071
- url: external_exports.string().optional().describe("\u6765\u6E90 URL")
33014
+ url: external_exports.string().optional().describe("\u6765\u6E90 URL"),
33015
+ cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
33016
+ excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
33017
+ source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ID\uFF08\u6EAF\u6E90\uFF09")
33072
33018
  });
33073
33019
  inkDeleteSchema = external_exports.object({
33074
- id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
33020
+ id: external_exports.string().describe("\u6761\u76EE ID"),
33075
33021
  confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
33076
33022
  });
33077
- inkWriteSchema = external_exports.object({
33078
- title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
33079
- content: external_exports.string().describe("Markdown \u5168\u6587"),
33080
- cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
33081
- tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6587\u7AE0\u6807\u7B7E"),
33082
- category: external_exports.string().optional().describe("\u6587\u7AE0\u5206\u7C7B"),
33083
- excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
33084
- source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ink ID\uFF08\u6EAF\u6E90\uFF09")
33085
- });
33086
33023
  inkTagsSchema = external_exports.object({
33087
33024
  action: external_exports.enum(["list", "rename", "merge"]).describe("\u64CD\u4F5C\uFF1Alist\uFF08\u5217\u51FA\u6240\u6709\u6807\u7B7E\uFF09/ rename\uFF08\u91CD\u547D\u540D\uFF09/ merge\uFF08\u5408\u5E76\uFF09"),
33088
33025
  tag: external_exports.string().optional().describe("\u76EE\u6807\u6807\u7B7E\uFF08rename/merge \u65F6\u4F7F\u7528\uFF09"),
@@ -33092,6 +33029,41 @@ var init_ink = __esm({
33092
33029
  }
33093
33030
  });
33094
33031
 
33032
+ // src/lib/push.ts
33033
+ function fireAndForgetPush(payload) {
33034
+ doPush(payload).catch(() => {
33035
+ });
33036
+ }
33037
+ async function doPush(partial2) {
33038
+ const creds = await getCredentials();
33039
+ if (!creds?.token) return;
33040
+ const config2 = await getConfig();
33041
+ const payload = {
33042
+ knowledge: partial2.knowledge || [],
33043
+ crawlerSources: partial2.crawlerSources || []
33044
+ };
33045
+ await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
33046
+ try {
33047
+ await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
33048
+ method: "POST",
33049
+ headers: {
33050
+ "Content-Type": "application/json",
33051
+ Authorization: `Bearer ${creds.token}`
33052
+ },
33053
+ body: JSON.stringify(payload)
33054
+ });
33055
+ } catch (err) {
33056
+ await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
33057
+ }
33058
+ }
33059
+ var init_push = __esm({
33060
+ "src/lib/push.ts"() {
33061
+ "use strict";
33062
+ init_state();
33063
+ init_logger();
33064
+ }
33065
+ });
33066
+
33095
33067
  // src/tools/source.ts
33096
33068
  import { readFile as readFile4 } from "fs/promises";
33097
33069
  import { join as join5 } from "path";
@@ -33332,7 +33304,7 @@ async function main() {
33332
33304
  }
33333
33305
  const transport = new StdioServerTransport();
33334
33306
  await server.connect(transport);
33335
- await log("INFO", "server", "started (8 tools)");
33307
+ await log("INFO", "server", "started (7 tools)");
33336
33308
  }
33337
33309
  var server;
33338
33310
  var init_index = __esm({
@@ -33349,7 +33321,7 @@ var init_index = __esm({
33349
33321
  init_logger();
33350
33322
  server = new McpServer({
33351
33323
  name: "ClaudeInk",
33352
- version: "2.0.1"
33324
+ version: "2.1.0"
33353
33325
  });
33354
33326
  server.tool("ink.init", "\u521D\u59CB\u5316\u77E5\u8BC6\u5E93\uFF08\u521B\u5EFA\u76EE\u5F55 + \u6FC0\u6D3B License + \u540C\u6B65\u4E91\u7AEF\uFF09", workflowInitSchema.shape, async (input) => {
33355
33327
  const result = await workflowInit(input);
@@ -33359,23 +33331,19 @@ var init_index = __esm({
33359
33331
  const result = await sync2(input);
33360
33332
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33361
33333
  });
33362
- server.tool("ink.save", "\u4FDD\u5B58\u6216\u66F4\u65B0\u77E5\u8BC6\u7D20\u6750\uFF08\u6709 id \u66F4\u65B0\uFF0C\u65E0 id \u65B0\u5EFA\uFF09", inkSaveSchema.shape, async (input) => {
33363
- const result = await inkSave(input);
33334
+ server.tool("ink.write", "\u4FDD\u5B58\u5185\u5BB9\uFF08\u672C\u5730 .md + \u4E0A\u4F20\u4E91\u7AEF\uFF09\u3002Claude \u751F\u6210\u5185\u5BB9\u540E\u8C03\u7528\u6B64\u5DE5\u5177\u4FDD\u5B58\u3002", inkWriteSchema.shape, async (input) => {
33335
+ const result = await inkWrite(input);
33364
33336
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33365
33337
  });
33366
- server.tool("ink.delete", "\u5220\u9664\u77E5\u8BC6\u7247\u6BB5\uFF08\u9700\u786E\u8BA4\uFF09", inkDeleteSchema.shape, async (input) => {
33338
+ server.tool("ink.delete", "\u5220\u9664\u6761\u76EE\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09", inkDeleteSchema.shape, async (input) => {
33367
33339
  const result = await inkDelete(input);
33368
33340
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33369
33341
  });
33370
- server.tool("ink.write", "\u5199\u6587\u7AE0\u4FDD\u5B58\u4E3A\u8349\u7A3F\u3002Claude \u5199\u5B8C\u535A\u5BA2\u6587\u7AE0\u540E\u81EA\u52A8\u8C03\u7528\uFF0C\u63D0\u4F9B\u6807\u9898\u3001Markdown \u5185\u5BB9\u3001\u5C01\u9762\u56FE\u548C\u6807\u7B7E\u3002", inkWriteSchema.shape, async (input) => {
33371
- const result = await inkWrite(input);
33372
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33373
- });
33374
33342
  server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
33375
33343
  const result = await inkTags(input);
33376
33344
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33377
33345
  });
33378
- server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u5185\u5BB9\u81EA\u52A8\u5B58\u5165\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
33346
+ server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u7D20\u6750\u5B58\u5165\u672C\u5730\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
33379
33347
  const result = await sourceCrawl(input);
33380
33348
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33381
33349
  });
@@ -33383,6 +33351,9 @@ var init_index = __esm({
33383
33351
  const result = await sourceSubscribe(input);
33384
33352
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
33385
33353
  });
33354
+ process.on("unhandledRejection", (err) => {
33355
+ console.error(`[ClaudeInk] Unhandled rejection: ${err}`);
33356
+ });
33386
33357
  main().catch(async (err) => {
33387
33358
  await log("ERROR", "server", `fatal: ${err.message || err}`);
33388
33359
  process.exit(1);
@@ -33523,7 +33494,10 @@ switch (command) {
33523
33494
  console.log("@claudeink/mcp-server v0.0.3");
33524
33495
  break;
33525
33496
  default:
33526
- Promise.resolve().then(() => init_index());
33497
+ Promise.resolve().then(() => (init_index(), index_exports)).catch((err) => {
33498
+ console.error(`[ClaudeInk] Fatal: ${err?.message || err}`);
33499
+ process.exit(1);
33500
+ });
33527
33501
  break;
33528
33502
  }
33529
33503
  /*! Bundled license information:
package/dist/index.js CHANGED
@@ -24690,7 +24690,7 @@ async function workflowInit(input) {
24690
24690
  }
24691
24691
  await writeState(state);
24692
24692
  results.push("\u2705 state.json");
24693
- if (activated) {
24693
+ if (state.credentials?.token) {
24694
24694
  try {
24695
24695
  const pullResult = await syncPull({ workDir: cwd });
24696
24696
  if (pullResult.success) {
@@ -24971,46 +24971,22 @@ async function mergeTags(sourceTags, targetTag) {
24971
24971
  });
24972
24972
  }
24973
24973
 
24974
- // src/lib/push.ts
24975
- function fireAndForgetPush(payload) {
24976
- doPush(payload).catch(() => {
24977
- });
24978
- }
24979
- async function doPush(partial2) {
24980
- const creds = await getCredentials();
24981
- if (!creds?.token) return;
24982
- const config2 = await getConfig();
24983
- const payload = {
24984
- knowledge: partial2.knowledge || [],
24985
- crawlerSources: partial2.crawlerSources || []
24986
- };
24987
- await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
24988
- try {
24989
- await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
24990
- method: "POST",
24991
- headers: {
24992
- "Content-Type": "application/json",
24993
- Authorization: `Bearer ${creds.token}`
24994
- },
24995
- body: JSON.stringify(payload)
24996
- });
24997
- } catch (err) {
24998
- await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
24999
- }
25000
- }
25001
-
25002
24974
  // src/tools/ink.ts
25003
- var inkSaveSchema = external_exports.object({
25004
- id: external_exports.string().optional().describe("\u77E5\u8BC6\u7247\u6BB5 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
25005
- content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
25006
- title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
24975
+ var inkWriteSchema = external_exports.object({
24976
+ id: external_exports.string().optional().describe("\u672C\u5730 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\u5DF2\u6709\u6761\u76EE\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
24977
+ title: external_exports.string().describe("\u6807\u9898"),
24978
+ content: external_exports.string().describe("Markdown \u5168\u6587"),
25007
24979
  tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
25008
24980
  category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
25009
24981
  source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
25010
- url: external_exports.string().optional().describe("\u6765\u6E90 URL")
24982
+ url: external_exports.string().optional().describe("\u6765\u6E90 URL"),
24983
+ cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
24984
+ excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
24985
+ source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ID\uFF08\u6EAF\u6E90\uFF09")
25011
24986
  });
25012
- async function inkSave(input) {
24987
+ async function inkWrite(input) {
25013
24988
  try {
24989
+ let localId;
25014
24990
  if (input.id) {
25015
24991
  const result = await updateKnowledgeFile(input.id, {
25016
24992
  title: input.title,
@@ -25019,112 +24995,30 @@ async function inkSave(input) {
25019
24995
  category: input.category
25020
24996
  });
25021
24997
  if (!result) {
25022
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
25023
- }
25024
- fireAndForgetPush({
25025
- knowledge: [{
25026
- id: result.meta.id,
25027
- title: result.meta.title,
25028
- tags: result.meta.tags,
25029
- category: result.meta.category,
25030
- source_type: result.meta.source_type,
25031
- url: result.meta.url,
25032
- created_at: result.meta.created_at,
25033
- updated_at: result.meta.updated_at
25034
- }]
25035
- });
25036
- await log("INFO", "ink.save", `updated id=${input.id} title="${input.title}"`);
25037
- return {
25038
- success: true,
25039
- message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D`,
25040
- data: { id: result.meta.id }
25041
- };
25042
- }
25043
- const { id } = await saveKnowledge({
25044
- content: input.content,
25045
- title: input.title,
25046
- tags: input.tags,
25047
- category: input.category,
25048
- source_type: input.source_type,
25049
- url: input.url
25050
- });
25051
- fireAndForgetPush({
25052
- knowledge: [{
25053
- id,
24998
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u672C\u5730\u6761\u76EE` };
24999
+ }
25000
+ localId = input.id;
25001
+ } else {
25002
+ const { id } = await saveKnowledge({
25003
+ content: input.content,
25054
25004
  title: input.title,
25055
25005
  tags: input.tags,
25056
25006
  category: input.category,
25057
25007
  source_type: input.source_type,
25058
- url: input.url,
25059
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
25060
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
25061
- }]
25062
- });
25063
- await log("INFO", "ink.save", `created id=${id} title="${input.title}" tags=${JSON.stringify(input.tags)}`);
25064
- return {
25065
- success: true,
25066
- message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D`,
25067
- data: { id }
25068
- };
25069
- } catch (err) {
25070
- await log("ERROR", "ink.save", `failed: ${err.message}`);
25071
- return { success: false, message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}` };
25072
- }
25073
- }
25074
- var inkDeleteSchema = external_exports.object({
25075
- id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
25076
- confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
25077
- });
25078
- async function inkDelete(input) {
25079
- try {
25080
- if (!input.confirm) {
25081
- const index = await readIndex();
25082
- const entry = index.entries[input.id];
25083
- if (!entry) {
25084
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
25085
- }
25008
+ url: input.url
25009
+ });
25010
+ localId = id;
25011
+ }
25012
+ const creds = await getCredentials();
25013
+ if (!creds?.token) {
25014
+ await log("INFO", "ink.write", `saved locally id=${localId} title="${input.title}" (no cloud auth)`);
25086
25015
  return {
25087
- success: false,
25088
- message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
25089
- data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
25016
+ success: true,
25017
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\u5230\u672C\u5730\uFF08\u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7\u4E91\u7AEF\u540C\u6B65\uFF09`,
25018
+ data: { id: localId }
25090
25019
  };
25091
25020
  }
25092
- const deleted = await deleteKnowledgeFile(input.id);
25093
- if (!deleted) {
25094
- return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
25095
- }
25096
- fireAndForgetPush({
25097
- knowledge: [{
25098
- id: input.id,
25099
- title: "",
25100
- tags: [],
25101
- category: "reference",
25102
- source_type: "conversation",
25103
- created_at: "",
25104
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
25105
- }]
25106
- });
25107
- await log("INFO", "ink.delete", `deleted id=${input.id}`);
25108
- return { success: true, message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`, data: { id: input.id } };
25109
- } catch (err) {
25110
- await log("ERROR", "ink.delete", `failed: ${err.message}`);
25111
- return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
25112
- }
25113
- }
25114
- var inkWriteSchema = external_exports.object({
25115
- title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
25116
- content: external_exports.string().describe("Markdown \u5168\u6587"),
25117
- cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
25118
- tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6587\u7AE0\u6807\u7B7E"),
25119
- category: external_exports.string().optional().describe("\u6587\u7AE0\u5206\u7C7B"),
25120
- excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
25121
- source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ink ID\uFF08\u6EAF\u6E90\uFF09")
25122
- });
25123
- async function inkWrite(input) {
25124
- const creds = await getCredentials();
25125
- if (!creds?.token) return { success: false, message: "\u672A\u8BA4\u8BC1\uFF0C\u8BF7\u5148\u8FD0\u884C ink.init" };
25126
- const config2 = await getConfig();
25127
- try {
25021
+ const config2 = await getConfig();
25128
25022
  let coverUrl = input.cover || null;
25129
25023
  if (coverUrl) {
25130
25024
  if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
@@ -25156,24 +25050,75 @@ async function inkWrite(input) {
25156
25050
  tags: input.tags,
25157
25051
  category: input.category,
25158
25052
  excerpt,
25159
- source_ids: input.source_ids
25053
+ source_type: input.source_type,
25054
+ url: input.url,
25055
+ source_ids: input.source_ids,
25056
+ local_id: localId
25160
25057
  })
25161
25058
  });
25162
25059
  if (!res.ok) {
25163
25060
  const err = await res.text();
25164
- await log("ERROR", "ink.write", `save failed: ${err}`);
25165
- return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err}` };
25061
+ await log("ERROR", "ink.write", `cloud save failed: ${err}`);
25062
+ return {
25063
+ success: true,
25064
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${err}`,
25065
+ data: { id: localId }
25066
+ };
25166
25067
  }
25167
25068
  const data = await res.json();
25168
- await log("INFO", "ink.write", `saved article="${input.title}" id=${data.id} slug=${data.slug}`);
25069
+ await log("INFO", "ink.write", `saved id=${localId} cloud_id=${data.id} title="${input.title}"`);
25169
25070
  return {
25170
25071
  success: true,
25171
- message: `\u6587\u7AE0\u300C${input.title}\u300D\u5DF2\u4FDD\u5B58\u4E3A\u8349\u7A3F\uFF0C\u8BF7\u5230 Dashboard \u53D1\u5E03`,
25172
- data: { id: data.id, slug: data.slug, status: data.status }
25072
+ message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09`,
25073
+ data: { id: localId, cloud_id: data.id, slug: data.slug, status: data.status }
25173
25074
  };
25174
25075
  } catch (err) {
25175
25076
  await log("ERROR", "ink.write", `failed: ${err.message}`);
25176
- return { success: false, message: `\u5199\u6587\u7AE0\u5931\u8D25: ${err.message}` };
25077
+ return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err.message}` };
25078
+ }
25079
+ }
25080
+ var inkDeleteSchema = external_exports.object({
25081
+ id: external_exports.string().describe("\u6761\u76EE ID"),
25082
+ confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
25083
+ });
25084
+ async function inkDelete(input) {
25085
+ try {
25086
+ if (!input.confirm) {
25087
+ const index = await readIndex();
25088
+ const entry = index.entries[input.id];
25089
+ if (!entry) {
25090
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
25091
+ }
25092
+ return {
25093
+ success: false,
25094
+ message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
25095
+ data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
25096
+ };
25097
+ }
25098
+ const deleted = await deleteKnowledgeFile(input.id);
25099
+ if (!deleted) {
25100
+ return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
25101
+ }
25102
+ try {
25103
+ const creds = await getCredentials();
25104
+ if (creds?.token) {
25105
+ const config2 = await getConfig();
25106
+ await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
25107
+ method: "DELETE",
25108
+ headers: {
25109
+ "Content-Type": "application/json",
25110
+ Authorization: `Bearer ${creds.token}`
25111
+ },
25112
+ body: JSON.stringify({ local_id: input.id })
25113
+ });
25114
+ }
25115
+ } catch {
25116
+ }
25117
+ await log("INFO", "ink.delete", `deleted id=${input.id}`);
25118
+ return { success: true, message: `\u5DF2\u5220\u9664 ${input.id}`, data: { id: input.id } };
25119
+ } catch (err) {
25120
+ await log("ERROR", "ink.delete", `failed: ${err.message}`);
25121
+ return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
25177
25122
  }
25178
25123
  }
25179
25124
  var inkTagsSchema = external_exports.object({
@@ -25200,12 +25145,12 @@ async function inkTags(input) {
25200
25145
  }
25201
25146
  const count = await renameTag(input.tag, input.new_tag);
25202
25147
  if (count === 0) {
25203
- return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5` };
25148
+ return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u6761\u76EE` };
25204
25149
  }
25205
25150
  await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
25206
25151
  return {
25207
25152
  success: true,
25208
- message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
25153
+ message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
25209
25154
  data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
25210
25155
  };
25211
25156
  }
@@ -25215,12 +25160,12 @@ async function inkTags(input) {
25215
25160
  }
25216
25161
  const count = await mergeTags(input.source_tags, input.new_tag);
25217
25162
  if (count === 0) {
25218
- return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5" };
25163
+ return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u6761\u76EE" };
25219
25164
  }
25220
25165
  await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
25221
25166
  return {
25222
25167
  success: true,
25223
- message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
25168
+ message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
25224
25169
  data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
25225
25170
  };
25226
25171
  }
@@ -25292,6 +25237,36 @@ import { readFile as readFile4 } from "fs/promises";
25292
25237
  import { join as join5 } from "path";
25293
25238
  import { readdirSync } from "fs";
25294
25239
  import { execSync } from "child_process";
25240
+
25241
+ // src/lib/push.ts
25242
+ function fireAndForgetPush(payload) {
25243
+ doPush(payload).catch(() => {
25244
+ });
25245
+ }
25246
+ async function doPush(partial2) {
25247
+ const creds = await getCredentials();
25248
+ if (!creds?.token) return;
25249
+ const config2 = await getConfig();
25250
+ const payload = {
25251
+ knowledge: partial2.knowledge || [],
25252
+ crawlerSources: partial2.crawlerSources || []
25253
+ };
25254
+ await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
25255
+ try {
25256
+ await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
25257
+ method: "POST",
25258
+ headers: {
25259
+ "Content-Type": "application/json",
25260
+ Authorization: `Bearer ${creds.token}`
25261
+ },
25262
+ body: JSON.stringify(payload)
25263
+ });
25264
+ } catch (err) {
25265
+ await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
25266
+ }
25267
+ }
25268
+
25269
+ // src/tools/source.ts
25295
25270
  var sourceCrawlSchema = external_exports.object({
25296
25271
  sourceId: external_exports.string().optional().describe("\u6307\u5B9A\u722C\u866B\u6E90\u540D\u79F0\uFF0C\u4E0D\u4F20\u5219\u5168\u91CF")
25297
25272
  });
@@ -25497,7 +25472,7 @@ async function sourceSubscribe(input) {
25497
25472
  // src/index.ts
25498
25473
  var server = new McpServer({
25499
25474
  name: "ClaudeInk",
25500
- version: "2.0.1"
25475
+ version: "2.1.0"
25501
25476
  });
25502
25477
  server.tool("ink.init", "\u521D\u59CB\u5316\u77E5\u8BC6\u5E93\uFF08\u521B\u5EFA\u76EE\u5F55 + \u6FC0\u6D3B License + \u540C\u6B65\u4E91\u7AEF\uFF09", workflowInitSchema.shape, async (input) => {
25503
25478
  const result = await workflowInit(input);
@@ -25507,23 +25482,19 @@ server.tool("ink.sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\
25507
25482
  const result = await sync(input);
25508
25483
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25509
25484
  });
25510
- server.tool("ink.save", "\u4FDD\u5B58\u6216\u66F4\u65B0\u77E5\u8BC6\u7D20\u6750\uFF08\u6709 id \u66F4\u65B0\uFF0C\u65E0 id \u65B0\u5EFA\uFF09", inkSaveSchema.shape, async (input) => {
25511
- const result = await inkSave(input);
25485
+ server.tool("ink.write", "\u4FDD\u5B58\u5185\u5BB9\uFF08\u672C\u5730 .md + \u4E0A\u4F20\u4E91\u7AEF\uFF09\u3002Claude \u751F\u6210\u5185\u5BB9\u540E\u8C03\u7528\u6B64\u5DE5\u5177\u4FDD\u5B58\u3002", inkWriteSchema.shape, async (input) => {
25486
+ const result = await inkWrite(input);
25512
25487
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25513
25488
  });
25514
- server.tool("ink.delete", "\u5220\u9664\u77E5\u8BC6\u7247\u6BB5\uFF08\u9700\u786E\u8BA4\uFF09", inkDeleteSchema.shape, async (input) => {
25489
+ server.tool("ink.delete", "\u5220\u9664\u6761\u76EE\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09", inkDeleteSchema.shape, async (input) => {
25515
25490
  const result = await inkDelete(input);
25516
25491
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25517
25492
  });
25518
- server.tool("ink.write", "\u5199\u6587\u7AE0\u4FDD\u5B58\u4E3A\u8349\u7A3F\u3002Claude \u5199\u5B8C\u535A\u5BA2\u6587\u7AE0\u540E\u81EA\u52A8\u8C03\u7528\uFF0C\u63D0\u4F9B\u6807\u9898\u3001Markdown \u5185\u5BB9\u3001\u5C01\u9762\u56FE\u548C\u6807\u7B7E\u3002", inkWriteSchema.shape, async (input) => {
25519
- const result = await inkWrite(input);
25520
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25521
- });
25522
25493
  server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
25523
25494
  const result = await inkTags(input);
25524
25495
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25525
25496
  });
25526
- server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u5185\u5BB9\u81EA\u52A8\u5B58\u5165\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
25497
+ server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u7D20\u6750\u5B58\u5165\u672C\u5730\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
25527
25498
  const result = await sourceCrawl(input);
25528
25499
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25529
25500
  });
@@ -25531,6 +25502,9 @@ server.tool("ink.subscribe", "\u7BA1\u7406\u8BA2\u9605\u6E90\uFF08\u6DFB\u52A0/\
25531
25502
  const result = await sourceSubscribe(input);
25532
25503
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25533
25504
  });
25505
+ process.on("unhandledRejection", (err) => {
25506
+ console.error(`[ClaudeInk] Unhandled rejection: ${err}`);
25507
+ });
25534
25508
  async function main() {
25535
25509
  try {
25536
25510
  const state = await readState();
@@ -25542,7 +25516,7 @@ async function main() {
25542
25516
  }
25543
25517
  const transport = new StdioServerTransport();
25544
25518
  await server.connect(transport);
25545
- await log("INFO", "server", "started (8 tools)");
25519
+ await log("INFO", "server", "started (7 tools)");
25546
25520
  }
25547
25521
  main().catch(async (err) => {
25548
25522
  await log("ERROR", "server", `fatal: ${err.message || err}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeink/mcp-server",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "ClaudeInk MCP Server — Claude 对话知识沉淀系统,保存、搜索、整合对话中的有价值内容",
5
5
  "mcpName": "io.github.weekdmond/claudeink",
6
6
  "type": "module",