@hirey/hi-mcp-server 0.1.10 → 0.1.12

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
@@ -91,15 +91,16 @@ npm install -g @hirey/hi-mcp-server
91
91
  1. 用宿主把 `hi-mcp-server` 作为 `stdio` MCP server 挂上
92
92
  2. 优先执行 `hi_agent_install`,而不是让用户手工走 `register -> connect -> activate`
93
93
  3. `hi_agent_install` 会自动完成 register / activate、delivery capability 声明、默认订阅,以及在 OpenClaw 场景下的 receiver 配置
94
- 4. `agent_id` 可以省略;省略时由 gateway 正式生成 canonical `ag_...`,不需要用户手写
95
- 5. 完成后执行 `hi_agent_doctor`
96
- 6. 如果要 clean reinstall,先执行 `hi_agent_reset`
94
+ 4. 当 receiver 的物料配置(例如 hooks token、adapter URL、transport、default reply route)发生变化时,`hi_agent_install` 会先停止当前 profile 记录的 receiver,再写入新配置并按需要重新启动;如果配置没变,则保留现有 runtime cursor,不重置消费进度
95
+ 5. `agent_id` 可以省略;省略时由 gateway 正式生成 canonical `ag_...`,不需要用户手写
96
+ 6. 完成后执行 `hi_agent_doctor`
97
+ 7. 如果要 clean reinstall,先执行 `hi_agent_reset`;`hi_agent_reset` 现在会等待当前 profile 记录的 receiver 真实退出,再删除本地 state / receiver config,避免立刻重装时旧进程把旧配置写回去
97
98
 
98
99
  如果宿主不能直接执行裸命令 `hi-agent-receiver`,而是需要 `node /path/to/dist/server.js`、`npx ...` 或其它显式 argv 前缀,`hi_agent_install` 现在也支持把 receiver 启动入口写成 `receiver_command_argv` 数组;`hi-mcp-server` 会在这组 argv 后自动追加 `run --config <path>`,不再把整段命令误当成单个可执行文件。
99
100
 
100
101
  对 OpenClaw 的普通用户本地 vendor 安装,不要显式传 `receiver_command="hi-agent-receiver"` 或 `receiver_command_argv=["hi-agent-receiver"]`。这两种旧形态都会重新把启动语义写回“按 PATH 找全局命令”。OpenClaw 要么不传 receiver 启动覆盖,让安装流默认落到 `~/.openclaw/vendor/hi/node_modules/.bin/hi-agent-receiver`,要么只传指向该本地 vendor binary 的精确 `receiver_command_argv`。
101
102
 
102
- 如果宿主此刻就知道“当前用户会话就是 Hi 以后该回去的默认线程”,`hi_agent_install` 也可以直接带上 `host_session_key`、`default_reply_channel`、`default_reply_to`、`default_reply_account_id`、`default_reply_thread_id`、`route_missing_policy`。这组字段会同时写进 installation 的 `delivery_capabilities` 和本地 receiver config,避免出现 gateway 已经知道默认 route、但本地 receiver 还沿旧配置投递的漂移。
103
+ OpenClaw 的普通用户安装,默认就应该把当前聊天绑成 Hi 以后回来的默认线程。因此 `hi_agent_install` 应直接带上 `host_session_key`、`default_reply_channel`、`default_reply_to`、`default_reply_account_id`、`default_reply_thread_id`、`route_missing_policy`。这组字段会同时写进 installation 的 `delivery_capabilities` 和本地 receiver config,避免出现 gateway 已经知道默认 route、但本地 receiver 还沿旧配置投递的漂移。如果拿不到当前聊天的 canonical `host_session_key`,OpenClaw 安装不应宣告成功,而应先把 continuity blocker 说明白。
103
104
 
104
105
  安装后如果要显式验证 continuation route,可以用 `hi_agent_test_delivery`:既可以直接传 `host_session_key` / `reply_*` 做一次显式 route probe,也可以在 installation 已设置 `default_reply_route` 时不传这些字段,让 gateway 自动沿当前 installation 的默认 route 发 probe。
105
106
 
@@ -12,4 +12,15 @@ export declare function resolveInstallDefaultReplyDeliveryContext(args: {
12
12
  defaultReplyAccountId?: unknown;
13
13
  defaultReplyThreadId?: unknown;
14
14
  }): DefaultReplyDeliveryContext | null;
15
+ export declare function resolveInstallRouteMissingPolicy(args: {
16
+ hostKind: 'openclaw' | 'generic';
17
+ explicitRouteMissingPolicy?: unknown;
18
+ defaultReplyRoute?: Record<string, unknown> | null;
19
+ }): {
20
+ ok: true;
21
+ routeMissingPolicy: string;
22
+ } | {
23
+ ok: false;
24
+ error: 'missing_openclaw_default_reply_route';
25
+ };
15
26
  //# sourceMappingURL=defaultReplyRoute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultReplyRoute.d.ts","sourceRoot":"","sources":["../src/defaultReplyRoute.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,wBAAgB,yCAAyC,CAAC,IAAI,EAAE;IAC9D,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GAAG,2BAA2B,GAAG,IAAI,CAyBrC"}
1
+ {"version":3,"file":"defaultReplyRoute.d.ts","sourceRoot":"","sources":["../src/defaultReplyRoute.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,wBAAgB,yCAAyC,CAAC,IAAI,EAAE;IAC9D,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GAAG,2BAA2B,GAAG,IAAI,CAyBrC;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE;IACrD,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACpD,GAAG;IACF,EAAE,EAAE,IAAI,CAAC;IACT,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GAAG;IACF,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,sCAAsC,CAAC;CAC/C,CAcA"}
@@ -26,3 +26,18 @@ export function resolveInstallDefaultReplyDeliveryContext(args) {
26
26
  }
27
27
  return null;
28
28
  }
29
+ export function resolveInstallRouteMissingPolicy(args) {
30
+ const explicitRouteMissingPolicy = normalizeText(args.explicitRouteMissingPolicy);
31
+ // OpenClaw 安装默认就要把当前聊天绑成默认续聊入口;否则安装不该继续宣告成功。
32
+ if (args.hostKind === 'openclaw' && !args.defaultReplyRoute) {
33
+ return {
34
+ ok: false,
35
+ error: 'missing_openclaw_default_reply_route',
36
+ };
37
+ }
38
+ return {
39
+ ok: true,
40
+ routeMissingPolicy: explicitRouteMissingPolicy
41
+ || (args.defaultReplyRoute ? 'use_explicit_default_route' : ''),
42
+ };
43
+ }
@@ -0,0 +1,4 @@
1
+ export declare function receiverConfigMaterialSnapshot(raw: unknown): Record<string, unknown> | null;
2
+ export declare function receiverConfigMaterialEquals(left: unknown, right: unknown): boolean;
3
+ export declare function applyReceiverRuntimeSnapshot(nextConfig: Record<string, unknown>, existingConfig: unknown): Record<string, unknown>;
4
+ //# sourceMappingURL=receiver-config-material.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiver-config-material.d.ts","sourceRoot":"","sources":["../src/receiver-config-material.ts"],"names":[],"mappings":"AAcA,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQ3F;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnF;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,cAAc,EAAE,OAAO,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
@@ -0,0 +1,47 @@
1
+ function isPlainObject(value) {
2
+ return !!value && typeof value === 'object' && !Array.isArray(value);
3
+ }
4
+ function canonicalizeJson(value) {
5
+ if (Array.isArray(value))
6
+ return value.map((entry) => canonicalizeJson(entry));
7
+ if (!isPlainObject(value))
8
+ return value;
9
+ const out = {};
10
+ for (const key of Object.keys(value).sort()) {
11
+ out[key] = canonicalizeJson(value[key]);
12
+ }
13
+ return out;
14
+ }
15
+ export function receiverConfigMaterialSnapshot(raw) {
16
+ if (!isPlainObject(raw))
17
+ return null;
18
+ const snapshot = JSON.parse(JSON.stringify(raw));
19
+ delete snapshot.runtime;
20
+ delete snapshot._generated_at;
21
+ delete snapshot._generated_by;
22
+ delete snapshot._receiver_config_path;
23
+ return canonicalizeJson(snapshot);
24
+ }
25
+ export function receiverConfigMaterialEquals(left, right) {
26
+ return JSON.stringify(receiverConfigMaterialSnapshot(left)) === JSON.stringify(receiverConfigMaterialSnapshot(right));
27
+ }
28
+ export function applyReceiverRuntimeSnapshot(nextConfig, existingConfig) {
29
+ if (!isPlainObject(existingConfig) || !isPlainObject(existingConfig.runtime))
30
+ return nextConfig;
31
+ const runtime = existingConfig.runtime;
32
+ return {
33
+ ...nextConfig,
34
+ // 安装修复时保留已消费 cursor,避免仅因重写物料配置就把 receiver 从头回放。
35
+ runtime: {
36
+ last_consumed_stream_seq: Number.isFinite(Number(runtime.last_consumed_stream_seq))
37
+ ? Math.max(0, Number(runtime.last_consumed_stream_seq))
38
+ : 0,
39
+ last_claim_lease_id: typeof runtime.last_claim_lease_id === 'string'
40
+ ? runtime.last_claim_lease_id
41
+ : null,
42
+ updated_at: typeof runtime.updated_at === 'string'
43
+ ? runtime.updated_at
44
+ : null,
45
+ },
46
+ };
47
+ }
package/dist/server.js CHANGED
@@ -14,8 +14,11 @@ import { createHiAgentClients, exchangeHiAgentClientCredentialsToken, HiAgentGat
14
14
  import { readState, resolveCanonicalOpenClawStateDir, resolveDefaultStateDir, resolveLegacyStateFiles, resolveStateFile, updateState, normalizeStateProfile, } from './state.js';
15
15
  import { looksLikeOpenClawSessionKey, validateOpenClawSessionKey, } from './openclaw-session-key.js';
16
16
  import { buildInstallReceiverCommandArgv, } from './receiver-command.js';
17
- import { resolveInstallDefaultReplyDeliveryContext, } from './defaultReplyRoute.js';
17
+ import { applyReceiverRuntimeSnapshot, receiverConfigMaterialEquals, } from './receiver-config-material.js';
18
+ import { resolveInstallDefaultReplyDeliveryContext, resolveInstallRouteMissingPolicy, } from './defaultReplyRoute.js';
18
19
  const CAPABILITY_CACHE_TTL_MS = 30_000;
20
+ const RECEIVER_STOP_TIMEOUT_MS = 3_000;
21
+ const RECEIVER_STOP_POLL_MS = 100;
19
22
  const resolvedProfile = normalizeStateProfile(process.env.HI_MCP_PROFILE);
20
23
  const config = {
21
24
  host: normalizeText(process.env.HI_MCP_HOST) || '127.0.0.1',
@@ -110,8 +113,8 @@ function controlTools() {
110
113
  host_adapter_url: { type: 'string', description: 'enable_local_receiver=true 时可选:宿主本地接收入口。OpenClaw 默认 full endpoint 为 http://127.0.0.1:18789/hooks/agent;注意 OpenClaw 配置里的 hooks.path 应保持 /hooks,而不是 /hooks/agent。' },
111
114
  host_adapter_bearer_token: { type: 'string', description: 'host_adapter_kind=openclaw_hooks 时必填:本地 hooks bearer token。' },
112
115
  openresponses_model: { type: 'string', description: 'host_adapter_kind=openresponses 时必填:receiver 发给本地入口使用的 model。' },
113
- host_session_key: { type: 'string', description: '可选:把当前 OpenClaw 当前会话显式设为 default continuation route 的 canonical full session_key。只能使用结构化宿主来源返回的完整 key;不要从 openclaw status / openclaw sessions / TUI footer 这类展示文本里抄值。' },
114
- route_missing_policy: { type: 'string', description: "可选:'use_explicit_default_route'|'fail_closed'。默认在提供 host_session_key/default_reply_* 时使用 use_explicit_default_route,否则为 null。" },
116
+ host_session_key: { type: 'string', description: 'OpenClaw 安装默认应传:把当前 OpenClaw 当前会话设为 default continuation route 的 canonical full session_key。只能使用结构化宿主来源返回的完整 key;不要从 openclaw status / openclaw sessions / TUI footer 这类展示文本里抄值。' },
117
+ route_missing_policy: { type: 'string', description: "可选:'use_explicit_default_route'|'fail_closed'。OpenClaw 安装默认要求当前聊天 ready,因此在提供 host_session_key/default_reply_* 时应使用 use_explicit_default_route;缺失 default route 时安装会直接失败,而不是继续留下 continuity_not_ready。" },
115
118
  default_reply_channel: { type: 'string', description: '可选:default continuation route 的 channel。' },
116
119
  default_reply_to: { type: 'string', description: '可选:default continuation route 的宿主 target。' },
117
120
  default_reply_account_id: { type: 'string', description: '可选:default continuation route 的 account_id。' },
@@ -724,6 +727,58 @@ function isProcessAlive(pid) {
724
727
  return false;
725
728
  }
726
729
  }
730
+ async function waitForProcessExit(pid, timeoutMs = RECEIVER_STOP_TIMEOUT_MS) {
731
+ const deadline = Date.now() + timeoutMs;
732
+ while (Date.now() < deadline) {
733
+ if (!isProcessAlive(pid))
734
+ return true;
735
+ await sleep(RECEIVER_STOP_POLL_MS);
736
+ }
737
+ return !isProcessAlive(pid);
738
+ }
739
+ async function stopTrackedReceiverProcess(pidRaw) {
740
+ const pid = Number(pidRaw || 0);
741
+ if (!Number.isInteger(pid) || pid <= 0) {
742
+ return {
743
+ attempted: false,
744
+ pid: null,
745
+ signal: null,
746
+ exited: true,
747
+ timeout_ms: RECEIVER_STOP_TIMEOUT_MS,
748
+ };
749
+ }
750
+ if (!isProcessAlive(pid)) {
751
+ return {
752
+ attempted: true,
753
+ pid,
754
+ signal: null,
755
+ exited: true,
756
+ timeout_ms: RECEIVER_STOP_TIMEOUT_MS,
757
+ };
758
+ }
759
+ try {
760
+ process.kill(pid, 'SIGTERM');
761
+ }
762
+ catch (error) {
763
+ if (error?.code === 'ESRCH') {
764
+ return {
765
+ attempted: true,
766
+ pid,
767
+ signal: 'SIGTERM',
768
+ exited: true,
769
+ timeout_ms: RECEIVER_STOP_TIMEOUT_MS,
770
+ };
771
+ }
772
+ throw error;
773
+ }
774
+ return {
775
+ attempted: true,
776
+ pid,
777
+ signal: 'SIGTERM',
778
+ exited: await waitForProcessExit(pid),
779
+ timeout_ms: RECEIVER_STOP_TIMEOUT_MS,
780
+ };
781
+ }
727
782
  async function startDetachedReceiver(args) {
728
783
  const [command, ...prefixArgs] = args.receiverCommandArgv;
729
784
  if (!command)
@@ -1206,8 +1261,19 @@ async function handleInstall(args) {
1206
1261
  requireOpenClawSessionKey: hostKind === 'openclaw',
1207
1262
  hostKind,
1208
1263
  });
1209
- const routeMissingPolicy = normalizeText(args.route_missing_policy)
1210
- || (defaultReplyRoute ? 'use_explicit_default_route' : '');
1264
+ const routeMissingPolicyResolution = resolveInstallRouteMissingPolicy({
1265
+ hostKind,
1266
+ explicitRouteMissingPolicy: args.route_missing_policy,
1267
+ defaultReplyRoute,
1268
+ });
1269
+ if (!routeMissingPolicyResolution.ok) {
1270
+ return fail(routeMissingPolicyResolution.error, {
1271
+ host_kind: hostKind,
1272
+ hint: 'OpenClaw installs must bind the current chat as the default continuation route. Read the canonical full current session key from a structured OpenClaw host source and pass it as host_session_key.',
1273
+ expected_route_missing_policy: 'use_explicit_default_route',
1274
+ });
1275
+ }
1276
+ const routeMissingPolicy = routeMissingPolicyResolution.routeMissingPolicy;
1211
1277
  const desiredDeliveryCapabilities = buildInstallationDeliveryDeclaration({
1212
1278
  enableLocalReceiver,
1213
1279
  receiverTransport,
@@ -1242,7 +1308,8 @@ async function handleInstall(args) {
1242
1308
  return fail('missing_host_adapter_url');
1243
1309
  }
1244
1310
  const receiverConfigPath = resolveReceiverConfigPath(await loadPersistedState());
1245
- const receiverConfig = buildReceiverConfig({
1311
+ let existingReceiverConfig = await readReceiverConfigSnapshot(receiverConfigPath);
1312
+ const desiredReceiverConfig = buildReceiverConfig({
1246
1313
  receiverConfigPath,
1247
1314
  hostKind,
1248
1315
  receiverTransport,
@@ -1252,16 +1319,37 @@ async function handleInstall(args) {
1252
1319
  openresponsesModel: normalizeText(args.openresponses_model) || undefined,
1253
1320
  defaultReplyRoute,
1254
1321
  });
1255
- await writeReceiverConfigFile(receiverConfigPath, receiverConfig);
1322
+ const receiverConfigChanged = !receiverConfigMaterialEquals(existingReceiverConfig, desiredReceiverConfig);
1323
+ let receiverPid = stateInstallSnapshot(state.runtime).receiver_pid;
1324
+ let receiverStop = null;
1325
+ if (receiverConfigChanged && isProcessAlive(receiverPid)) {
1326
+ // 先停 tracked receiver,避免旧进程继续拿旧 token 投递,并把旧物料配置再写回磁盘。
1327
+ receiverStop = await stopTrackedReceiverProcess(receiverPid);
1328
+ if (!normalizeBooleanFlag(receiverStop?.exited)) {
1329
+ return fail('receiver_stop_timeout', {
1330
+ receiver_config_path: receiverConfigPath,
1331
+ receiver_pid: receiverPid,
1332
+ receiver_stop: receiverStop,
1333
+ });
1334
+ }
1335
+ receiverPid = null;
1336
+ // 停掉 tracked receiver 后再读一次磁盘,尽量保留它退出前最后一次写下的 runtime cursor。
1337
+ existingReceiverConfig = await readReceiverConfigSnapshot(receiverConfigPath);
1338
+ }
1339
+ if (receiverConfigChanged) {
1340
+ const receiverConfig = applyReceiverRuntimeSnapshot(desiredReceiverConfig, existingReceiverConfig);
1341
+ await writeReceiverConfigFile(receiverConfigPath, receiverConfig);
1342
+ }
1256
1343
  state = await persistState((current) => ({
1257
1344
  ...current,
1258
1345
  runtime: buildInstallRuntimeState(current.runtime, {
1259
1346
  host_kind: hostKind,
1260
1347
  receiver_config_path: receiverConfigPath,
1348
+ receiver_pid: isProcessAlive(receiverPid) ? receiverPid : null,
1261
1349
  receiver_last_error: null,
1262
1350
  }),
1263
1351
  }));
1264
- let receiverPid = stateInstallSnapshot(state.runtime).receiver_pid;
1352
+ receiverPid = stateInstallSnapshot(state.runtime).receiver_pid;
1265
1353
  if (receiverShouldStart && !isProcessAlive(receiverPid)) {
1266
1354
  try {
1267
1355
  receiverPid = await startDetachedReceiver({
@@ -1297,12 +1385,14 @@ async function handleInstall(args) {
1297
1385
  }
1298
1386
  receiverPayload = {
1299
1387
  config_path: receiverConfigPath,
1388
+ config_changed: receiverConfigChanged,
1300
1389
  started: receiverShouldStart,
1301
1390
  receiver_pid: receiverPid || null,
1302
1391
  receiver_command_argv: receiverCommandArgv,
1303
1392
  transport: receiverTransport,
1304
1393
  host_adapter_kind: hostAdapterKind,
1305
1394
  host_adapter_url: hostAdapterUrl,
1395
+ ...(receiverStop ? { receiver_stop: receiverStop } : {}),
1306
1396
  };
1307
1397
  }
1308
1398
  if (receiverShouldStart) {
@@ -1335,22 +1425,21 @@ async function handleReset(args) {
1335
1425
  const removeReceiverConfig = args.remove_receiver_config !== false;
1336
1426
  const clearState = args.clear_state !== false;
1337
1427
  let stopResult = null;
1338
- if (stopReceiver && isProcessAlive(installState.receiver_pid)) {
1428
+ if (stopReceiver && Number.isInteger(installState.receiver_pid) && Number(installState.receiver_pid) > 0) {
1339
1429
  try {
1340
- process.kill(Number(installState.receiver_pid), 'SIGTERM');
1341
- stopResult = {
1342
- attempted: true,
1343
- pid: installState.receiver_pid,
1344
- signalled: true,
1345
- };
1430
+ stopResult = await stopTrackedReceiverProcess(installState.receiver_pid);
1346
1431
  }
1347
1432
  catch (error) {
1348
- stopResult = {
1349
- attempted: true,
1433
+ return fail('receiver_stop_failed', {
1350
1434
  pid: installState.receiver_pid,
1351
- signalled: false,
1352
1435
  error: String(error?.message || error || 'receiver_stop_failed'),
1353
- };
1436
+ });
1437
+ }
1438
+ if (!normalizeBooleanFlag(stopResult?.exited)) {
1439
+ return fail('receiver_stop_timeout', {
1440
+ pid: installState.receiver_pid,
1441
+ receiver_stop: stopResult,
1442
+ });
1354
1443
  }
1355
1444
  }
1356
1445
  const receiverConfigPath = installState.receiver_config_path || resolveReceiverConfigPath(state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hirey/hi-mcp-server",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/server.js",