@hirey/hi-mcp-server 0.1.8 → 0.1.10

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
@@ -97,6 +97,8 @@ npm install -g @hirey/hi-mcp-server
97
97
 
98
98
  如果宿主不能直接执行裸命令 `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
99
 
100
+ 对 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
+
100
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 还沿旧配置投递的漂移。
101
103
 
102
104
  安装后如果要显式验证 continuation route,可以用 `hi_agent_test_delivery`:既可以直接传 `host_session_key` / `reply_*` 做一次显式 route probe,也可以在 installation 已设置 `default_reply_route` 时不传这些字段,让 gateway 自动沿当前 installation 的默认 route 发 probe。
@@ -0,0 +1,15 @@
1
+ export type DefaultReplyDeliveryContext = {
2
+ channel: string | null;
3
+ to: string | null;
4
+ account_id: string | null;
5
+ thread_id: string | null;
6
+ };
7
+ export declare function resolveInstallDefaultReplyDeliveryContext(args: {
8
+ hostKind: 'openclaw' | 'generic';
9
+ hasSessionKey: boolean;
10
+ defaultReplyChannel?: unknown;
11
+ defaultReplyTo?: unknown;
12
+ defaultReplyAccountId?: unknown;
13
+ defaultReplyThreadId?: unknown;
14
+ }): DefaultReplyDeliveryContext | null;
15
+ //# sourceMappingURL=defaultReplyRoute.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,28 @@
1
+ function normalizeText(input) {
2
+ return String(input || '').trim();
3
+ }
4
+ export function resolveInstallDefaultReplyDeliveryContext(args) {
5
+ const explicit = {
6
+ channel: normalizeText(args.defaultReplyChannel) || null,
7
+ to: normalizeText(args.defaultReplyTo) || null,
8
+ account_id: normalizeText(args.defaultReplyAccountId) || null,
9
+ thread_id: normalizeText(args.defaultReplyThreadId) || null,
10
+ };
11
+ const hasExplicit = !!(explicit.channel
12
+ || explicit.to
13
+ || explicit.account_id
14
+ || explicit.thread_id);
15
+ if (hasExplicit)
16
+ return explicit;
17
+ // OpenClaw hooks continuation accepts `last|imessage`; when we already have the
18
+ // canonical session key, `last` is the canonical "same chat" lane.
19
+ if (args.hostKind === 'openclaw' && args.hasSessionKey) {
20
+ return {
21
+ channel: 'last',
22
+ to: null,
23
+ account_id: null,
24
+ thread_id: null,
25
+ };
26
+ }
27
+ return null;
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"receiver-command.d.ts","sourceRoot":"","sources":["../src/receiver-command.ts"],"names":[],"mappings":"AAGA,wBAAgB,0CAA0C,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,CAEjG;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,EAAE,CAQX"}
1
+ {"version":3,"file":"receiver-command.d.ts","sourceRoot":"","sources":["../src/receiver-command.ts"],"names":[],"mappings":"AAGA,wBAAgB,0CAA0C,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,CAEjG;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,EAAE,CAmBX"}
@@ -4,13 +4,23 @@ export function resolveCanonicalOpenClawReceiverBinaryPath(homeDir = os.homedir(
4
4
  return path.join(homeDir, '.openclaw', 'vendor', 'hi', 'node_modules', '.bin', 'hi-agent-receiver');
5
5
  }
6
6
  export function buildInstallReceiverCommandArgv(args) {
7
- if (args.explicitArgv.length > 0)
7
+ const useCanonicalOpenClawReceiver = args.hostKind === 'openclaw' && args.enableLocalReceiver;
8
+ if (args.explicitArgv.length > 0) {
9
+ // OpenClaw's public install path is user-local vendor install, so a bare
10
+ // receiver command should never override the canonical local binary path.
11
+ if (useCanonicalOpenClawReceiver && args.explicitArgv[0] === 'hi-agent-receiver') {
12
+ return [resolveCanonicalOpenClawReceiverBinaryPath(args.homeDir), ...args.explicitArgv.slice(1)];
13
+ }
8
14
  return args.explicitArgv;
9
- if (args.receiverCommand)
15
+ }
16
+ if (args.receiverCommand) {
17
+ if (useCanonicalOpenClawReceiver && args.receiverCommand === 'hi-agent-receiver') {
18
+ return [resolveCanonicalOpenClawReceiverBinaryPath(args.homeDir)];
19
+ }
10
20
  return [args.receiverCommand];
21
+ }
11
22
  // OpenClaw's public install path is user-local vendor install, not global PATH.
12
- if (args.hostKind === 'openclaw' && args.enableLocalReceiver) {
23
+ if (useCanonicalOpenClawReceiver)
13
24
  return [resolveCanonicalOpenClawReceiverBinaryPath(args.homeDir)];
14
- }
15
25
  return ['hi-agent-receiver'];
16
26
  }
package/dist/server.js CHANGED
@@ -14,6 +14,7 @@ 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
18
  const CAPABILITY_CACHE_TTL_MS = 30_000;
18
19
  const resolvedProfile = normalizeStateProfile(process.env.HI_MCP_PROFILE);
19
20
  const config = {
@@ -622,16 +623,15 @@ function buildDefaultReplyRoute(args, options = {}) {
622
623
  const sessionKey = normalizeReplyRouteSessionKey(args.host_session_key, {
623
624
  requireOpenClawSessionKey: options.requireOpenClawSessionKey,
624
625
  });
625
- const deliveryContext = {
626
- channel: normalizeText(args.default_reply_channel) || null,
627
- to: normalizeText(args.default_reply_to) || null,
628
- account_id: normalizeText(args.default_reply_account_id) || null,
629
- thread_id: normalizeText(args.default_reply_thread_id) || null,
630
- };
631
- const hasDeliveryContext = !!(deliveryContext.channel
632
- || deliveryContext.to
633
- || deliveryContext.account_id
634
- || deliveryContext.thread_id);
626
+ const deliveryContext = resolveInstallDefaultReplyDeliveryContext({
627
+ hostKind: options.hostKind === 'openclaw' ? 'openclaw' : 'generic',
628
+ hasSessionKey: !!sessionKey,
629
+ defaultReplyChannel: args.default_reply_channel,
630
+ defaultReplyTo: args.default_reply_to,
631
+ defaultReplyAccountId: args.default_reply_account_id,
632
+ defaultReplyThreadId: args.default_reply_thread_id,
633
+ });
634
+ const hasDeliveryContext = !!deliveryContext;
635
635
  if (!sessionKey && !hasDeliveryContext)
636
636
  return null;
637
637
  return {
@@ -1204,6 +1204,7 @@ async function handleInstall(args) {
1204
1204
  const defaultReplyRoute = buildDefaultReplyRoute(args, {
1205
1205
  installationId: state.identity?.installation_id || null,
1206
1206
  requireOpenClawSessionKey: hostKind === 'openclaw',
1207
+ hostKind,
1207
1208
  });
1208
1209
  const routeMissingPolicy = normalizeText(args.route_missing_policy)
1209
1210
  || (defaultReplyRoute ? 'use_explicit_default_route' : '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hirey/hi-mcp-server",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/server.js",