@hiveai/mcp 0.9.6 → 0.9.8

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/dist/server.d.ts CHANGED
@@ -167,16 +167,26 @@ interface BriefingOutput {
167
167
  }
168
168
  declare function getBriefing(input: GetBriefingInput, ctx: HaiveContext): Promise<BriefingOutput>;
169
169
 
170
- declare const CodeMapInputSchema: {
170
+ declare const CodeMapInputZod: z.ZodObject<{
171
171
  file: z.ZodOptional<z.ZodString>;
172
172
  symbol: z.ZodOptional<z.ZodString>;
173
173
  paths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
174
174
  max_files: z.ZodDefault<z.ZodNumber>;
175
175
  max_tokens: z.ZodOptional<z.ZodNumber>;
176
- };
177
- type CodeMapInput = {
178
- [K in keyof typeof CodeMapInputSchema]: z.infer<(typeof CodeMapInputSchema)[K]>;
179
- };
176
+ }, "strip", z.ZodTypeAny, {
177
+ paths: string[];
178
+ max_files: number;
179
+ symbol?: string | undefined;
180
+ max_tokens?: number | undefined;
181
+ file?: string | undefined;
182
+ }, {
183
+ symbol?: string | undefined;
184
+ paths?: string[] | undefined;
185
+ max_tokens?: number | undefined;
186
+ file?: string | undefined;
187
+ max_files?: number | undefined;
188
+ }>;
189
+ type CodeMapInput = z.infer<typeof CodeMapInputZod>;
180
190
  interface CodeMapToolOutput {
181
191
  available: boolean;
182
192
  generated_at?: string;
package/dist/server.js CHANGED
@@ -1910,6 +1910,7 @@ var CodeMapInputSchema = {
1910
1910
  "Approximate token budget for the response. When the matching set exceeds it, files are ranked by export density (exports per LOC) and the highest-signal ones are kept first. Omit to disable budgeting (legacy behavior)."
1911
1911
  )
1912
1912
  };
1913
+ var CodeMapInputZod = z18.object(CodeMapInputSchema);
1913
1914
  async function codeMapTool(input, ctx) {
1914
1915
  const map = await loadCodeMap2(ctx.paths);
1915
1916
  if (!map) {
@@ -3448,8 +3449,9 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
3448
3449
  }
3449
3450
 
3450
3451
  // src/server.ts
3452
+ import { loadConfigSync } from "@hiveai/core";
3451
3453
  var SERVER_NAME = "haive";
3452
- var SERVER_VERSION = "0.9.6";
3454
+ var SERVER_VERSION = "0.9.8";
3453
3455
  function jsonResult(data) {
3454
3456
  return {
3455
3457
  content: [
@@ -3460,15 +3462,70 @@ function jsonResult(data) {
3460
3462
  ]
3461
3463
  };
3462
3464
  }
3465
+ var ENFORCEMENT_PROFILE_TOOLS = /* @__PURE__ */ new Set([
3466
+ "get_briefing",
3467
+ "mem_save",
3468
+ "mem_tried",
3469
+ "mem_search",
3470
+ "mem_get",
3471
+ "mem_update",
3472
+ "mem_verify",
3473
+ "mem_relevant_to",
3474
+ "code_map",
3475
+ "pre_commit_check"
3476
+ ]);
3477
+ var BRIEFING_TOOLS = /* @__PURE__ */ new Set(["get_briefing", "mem_relevant_to"]);
3478
+ var MUTATING_TOOLS = /* @__PURE__ */ new Set([
3479
+ "mem_save",
3480
+ "mem_tried",
3481
+ "mem_observe",
3482
+ "mem_session_end",
3483
+ "bootstrap_project_save",
3484
+ "mem_update",
3485
+ "mem_approve",
3486
+ "mem_reject",
3487
+ "mem_delete",
3488
+ "runtime_journal_append",
3489
+ "pattern_detect"
3490
+ ]);
3463
3491
  function createHaiveServer(options = {}) {
3464
3492
  const context = createContext(options);
3493
+ const config = loadConfigSync(context.paths);
3494
+ const toolProfile = options.env?.HAIVE_TOOL_PROFILE ?? config.enforcement?.toolProfile ?? "enforcement";
3495
+ const requireBriefingFirst = options.env?.HAIVE_REQUIRE_BRIEFING_FIRST === "0" ? false : config.enforcement?.requireBriefingFirst ?? true;
3496
+ let briefingLoaded = false;
3465
3497
  const tracker = new SessionTracker(context);
3466
3498
  void tracker.init();
3467
3499
  const server = new McpServer(
3468
3500
  { name: SERVER_NAME, version: SERVER_VERSION },
3469
3501
  { capabilities: { tools: {}, prompts: {} } }
3470
3502
  );
3471
- server.tool(
3503
+ const shouldRegisterTool = (name) => toolProfile === "full" || ENFORCEMENT_PROFILE_TOOLS.has(name);
3504
+ const registerTool = (name, description, schema, handler) => {
3505
+ if (!shouldRegisterTool(name)) return;
3506
+ const tool = server.tool.bind(server);
3507
+ tool(
3508
+ name,
3509
+ description,
3510
+ schema,
3511
+ async (input) => {
3512
+ if (BRIEFING_TOOLS.has(name)) {
3513
+ briefingLoaded = true;
3514
+ return await handler(input);
3515
+ }
3516
+ if (requireBriefingFirst && MUTATING_TOOLS.has(name) && !briefingLoaded) {
3517
+ return jsonResult({
3518
+ error: "haive_briefing_required",
3519
+ message: "This hAIve project requires get_briefing or mem_relevant_to before state-changing hAIve tools. Call get_briefing({ task: '...' }) first.",
3520
+ tool: name
3521
+ });
3522
+ }
3523
+ return await handler(input);
3524
+ }
3525
+ );
3526
+ };
3527
+ const shouldRegisterPrompt = (name) => toolProfile === "full" || name === "bootstrap_project" || name === "post_task";
3528
+ registerTool(
3472
3529
  "mem_save",
3473
3530
  [
3474
3531
  "Save a piece of knowledge as a persistent memory that survives across AI sessions.",
@@ -3500,7 +3557,7 @@ function createHaiveServer(options = {}) {
3500
3557
  return jsonResult(await memSave(input, context));
3501
3558
  }
3502
3559
  );
3503
- server.tool(
3560
+ registerTool(
3504
3561
  "mem_suggest_topic",
3505
3562
  [
3506
3563
  "Propose a stable `topic` key (topic-upsert) from type + short title.",
@@ -3517,7 +3574,7 @@ function createHaiveServer(options = {}) {
3517
3574
  MemSuggestTopicInputSchema,
3518
3575
  async (input) => jsonResult(await memSuggestTopic(input, context))
3519
3576
  );
3520
- server.tool(
3577
+ registerTool(
3521
3578
  "mem_tried",
3522
3579
  [
3523
3580
  "Record a FAILED approach so future agents don't repeat the same mistake.",
@@ -3544,7 +3601,7 @@ function createHaiveServer(options = {}) {
3544
3601
  return jsonResult(await memTried(input, context));
3545
3602
  }
3546
3603
  );
3547
- server.tool(
3604
+ registerTool(
3548
3605
  "mem_observe",
3549
3606
  [
3550
3607
  "Capture a code-level discovery made WHILE READING existing code.",
@@ -3576,7 +3633,7 @@ function createHaiveServer(options = {}) {
3576
3633
  return jsonResult(await memObserve(input, context));
3577
3634
  }
3578
3635
  );
3579
- server.tool(
3636
+ registerTool(
3580
3637
  "mem_session_end",
3581
3638
  [
3582
3639
  "Save an end-of-session recap so the NEXT session starts with fresh context.",
@@ -3605,7 +3662,7 @@ function createHaiveServer(options = {}) {
3605
3662
  return jsonResult(await memSessionEnd(input, context));
3606
3663
  }
3607
3664
  );
3608
- server.tool(
3665
+ registerTool(
3609
3666
  "get_briefing",
3610
3667
  [
3611
3668
  "\u2B50 DEFAULT-FIRST for coding agents on any repo where `haive init` ran: call this BEFORE",
@@ -3656,7 +3713,7 @@ function createHaiveServer(options = {}) {
3656
3713
  return jsonResult(await getBriefing(input, context));
3657
3714
  }
3658
3715
  );
3659
- server.tool(
3716
+ registerTool(
3660
3717
  "mem_search",
3661
3718
  [
3662
3719
  "Search memories by keyword or semantic similarity.",
@@ -3688,7 +3745,7 @@ function createHaiveServer(options = {}) {
3688
3745
  return jsonResult(await memSearch(input, context));
3689
3746
  }
3690
3747
  );
3691
- server.tool(
3748
+ registerTool(
3692
3749
  "mem_timeline",
3693
3750
  [
3694
3751
  "Chronological view of related memories: by shared frontmatter.topic OR expanded from a seed id",
@@ -3704,7 +3761,7 @@ function createHaiveServer(options = {}) {
3704
3761
  MemTimelineInputSchema,
3705
3762
  async (input) => jsonResult(await memTimeline(input, context))
3706
3763
  );
3707
- server.tool(
3764
+ registerTool(
3708
3765
  "mem_for_files",
3709
3766
  [
3710
3767
  "Surface memories relevant to the files you are currently editing.",
@@ -3728,7 +3785,7 @@ function createHaiveServer(options = {}) {
3728
3785
  MemForFilesInputSchema,
3729
3786
  async (input) => jsonResult(await memForFiles(input, context))
3730
3787
  );
3731
- server.tool(
3788
+ registerTool(
3732
3789
  "mem_get",
3733
3790
  [
3734
3791
  "Fetch a single memory by its full id with all details.",
@@ -3744,7 +3801,7 @@ function createHaiveServer(options = {}) {
3744
3801
  MemGetInputSchema,
3745
3802
  async (input) => jsonResult(await memGet(input, context))
3746
3803
  );
3747
- server.tool(
3804
+ registerTool(
3748
3805
  "mem_list",
3749
3806
  [
3750
3807
  "List memories with optional filters. Use for browsing, not for task onboarding.",
@@ -3764,7 +3821,7 @@ function createHaiveServer(options = {}) {
3764
3821
  MemListInputSchema,
3765
3822
  async (input) => jsonResult(await memList(input, context))
3766
3823
  );
3767
- server.tool(
3824
+ registerTool(
3768
3825
  "get_project_context",
3769
3826
  [
3770
3827
  "Read .ai/project-context.md (and optionally a module context) directly.",
@@ -3782,7 +3839,7 @@ function createHaiveServer(options = {}) {
3782
3839
  GetProjectContextInputSchema,
3783
3840
  async (input) => jsonResult(await getProjectContext(input, context))
3784
3841
  );
3785
- server.tool(
3842
+ registerTool(
3786
3843
  "bootstrap_project_save",
3787
3844
  [
3788
3845
  "Persist the project context document (.ai/project-context.md) or a module",
@@ -3800,7 +3857,7 @@ function createHaiveServer(options = {}) {
3800
3857
  BootstrapProjectSaveInputSchema,
3801
3858
  async (input) => jsonResult(await bootstrapProjectSave(input, context))
3802
3859
  );
3803
- server.tool(
3860
+ registerTool(
3804
3861
  "code_map",
3805
3862
  [
3806
3863
  "Look up where symbols (classes, functions, interfaces) are defined in the codebase.",
@@ -3821,7 +3878,7 @@ function createHaiveServer(options = {}) {
3821
3878
  CodeMapInputSchema,
3822
3879
  async (input) => jsonResult(await codeMapTool(input, context))
3823
3880
  );
3824
- server.tool(
3881
+ registerTool(
3825
3882
  "mem_resolve_project",
3826
3883
  [
3827
3884
  "Diagnostics: resolve which project root hAIve is using (never throws).",
@@ -3837,7 +3894,7 @@ function createHaiveServer(options = {}) {
3837
3894
  MemResolveProjectInputSchema,
3838
3895
  async (input) => jsonResult(await memResolveProject(input, context))
3839
3896
  );
3840
- server.tool(
3897
+ registerTool(
3841
3898
  "mem_update",
3842
3899
  [
3843
3900
  "Update the body, tags, or anchor of an existing memory in-place.",
@@ -3860,7 +3917,7 @@ function createHaiveServer(options = {}) {
3860
3917
  MemUpdateInputSchema,
3861
3918
  async (input) => jsonResult(await memUpdate(input, context))
3862
3919
  );
3863
- server.tool(
3920
+ registerTool(
3864
3921
  "mem_verify",
3865
3922
  [
3866
3923
  "Check whether memory anchor paths and symbols still exist in the current code.",
@@ -3879,7 +3936,7 @@ function createHaiveServer(options = {}) {
3879
3936
  MemVerifyInputSchema,
3880
3937
  async (input) => jsonResult(await memVerify(input, context))
3881
3938
  );
3882
- server.tool(
3939
+ registerTool(
3883
3940
  "mem_approve",
3884
3941
  [
3885
3942
  "Mark a memory as validated (trusted, approved by a human or the team).",
@@ -3895,7 +3952,7 @@ function createHaiveServer(options = {}) {
3895
3952
  MemApproveInputSchema,
3896
3953
  async (input) => jsonResult(await memApprove(input, context))
3897
3954
  );
3898
- server.tool(
3955
+ registerTool(
3899
3956
  "mem_reject",
3900
3957
  [
3901
3958
  "Mark a memory as rejected and record a reason.",
@@ -3913,7 +3970,7 @@ function createHaiveServer(options = {}) {
3913
3970
  MemRejectInputSchema,
3914
3971
  async (input) => jsonResult(await memReject(input, context))
3915
3972
  );
3916
- server.tool(
3973
+ registerTool(
3917
3974
  "mem_pending",
3918
3975
  [
3919
3976
  "List memories in 'proposed' status awaiting review, sorted by read count.",
@@ -3929,7 +3986,7 @@ function createHaiveServer(options = {}) {
3929
3986
  MemPendingInputSchema,
3930
3987
  async (input) => jsonResult(await memPending(input, context))
3931
3988
  );
3932
- server.tool(
3989
+ registerTool(
3933
3990
  "mem_delete",
3934
3991
  [
3935
3992
  "Permanently delete a memory by id.",
@@ -3946,7 +4003,7 @@ function createHaiveServer(options = {}) {
3946
4003
  MemDeleteInputSchema,
3947
4004
  async (input) => jsonResult(await memDelete(input, context))
3948
4005
  );
3949
- server.tool(
4006
+ registerTool(
3950
4007
  "get_recap",
3951
4008
  [
3952
4009
  "Return ONLY the most recent session_recap. Cheaper than get_briefing when",
@@ -3964,7 +4021,7 @@ function createHaiveServer(options = {}) {
3964
4021
  return jsonResult(await getRecap(input, context));
3965
4022
  }
3966
4023
  );
3967
- server.tool(
4024
+ registerTool(
3968
4025
  "mem_relevant_to",
3969
4026
  [
3970
4027
  "One-shot ranked memories for a task \u2014 use instead of get_briefing when",
@@ -3990,7 +4047,7 @@ function createHaiveServer(options = {}) {
3990
4047
  return jsonResult(await memRelevantTo(input, context));
3991
4048
  }
3992
4049
  );
3993
- server.tool(
4050
+ registerTool(
3994
4051
  "code_search",
3995
4052
  [
3996
4053
  "Semantic search over the codebase \u2014 finds exported symbols (functions, classes,",
@@ -4013,7 +4070,7 @@ function createHaiveServer(options = {}) {
4013
4070
  return jsonResult(await codeSearch(input, context));
4014
4071
  }
4015
4072
  );
4016
- server.tool(
4073
+ registerTool(
4017
4074
  "why_this_file",
4018
4075
  [
4019
4076
  "One-shot file-context lookup: combines recent git history, memories anchored",
@@ -4033,7 +4090,7 @@ function createHaiveServer(options = {}) {
4033
4090
  return jsonResult(await whyThisFile(input, context));
4034
4091
  }
4035
4092
  );
4036
- server.tool(
4093
+ registerTool(
4037
4094
  "anti_patterns_check",
4038
4095
  [
4039
4096
  "Scan a diff (or set of paths) against documented attempt/gotcha memories.",
@@ -4056,7 +4113,7 @@ function createHaiveServer(options = {}) {
4056
4113
  return jsonResult(await antiPatternsCheck(input, context));
4057
4114
  }
4058
4115
  );
4059
- server.tool(
4116
+ registerTool(
4060
4117
  "mem_distill",
4061
4118
  [
4062
4119
  "Cluster recurring observations / failed attempts so a human can collapse",
@@ -4081,7 +4138,7 @@ function createHaiveServer(options = {}) {
4081
4138
  return jsonResult(await memDistill(input, context));
4082
4139
  }
4083
4140
  );
4084
- server.tool(
4141
+ registerTool(
4085
4142
  "why_this_decision",
4086
4143
  [
4087
4144
  "Trace the genealogy of a memory (especially decision/architecture):",
@@ -4103,7 +4160,7 @@ function createHaiveServer(options = {}) {
4103
4160
  return jsonResult(await whyThisDecision(input, context));
4104
4161
  }
4105
4162
  );
4106
- server.tool(
4163
+ registerTool(
4107
4164
  "mem_conflicts_with",
4108
4165
  [
4109
4166
  "Detect memories that potentially CONTRADICT a given memory.",
@@ -4129,7 +4186,7 @@ function createHaiveServer(options = {}) {
4129
4186
  return jsonResult(await memConflicts(input, context));
4130
4187
  }
4131
4188
  );
4132
- server.tool(
4189
+ registerTool(
4133
4190
  "mem_conflict_candidates",
4134
4191
  [
4135
4192
  "Bulk scan for conflict CANDIDATES (not proof):",
@@ -4150,7 +4207,7 @@ function createHaiveServer(options = {}) {
4150
4207
  return jsonResult(await memConflictCandidates(input, context));
4151
4208
  }
4152
4209
  );
4153
- server.tool(
4210
+ registerTool(
4154
4211
  "runtime_journal_append",
4155
4212
  [
4156
4213
  "Append one line to `.ai/.runtime/session-journal.ndjson` \u2014 machine-local session continuity.",
@@ -4164,7 +4221,7 @@ function createHaiveServer(options = {}) {
4164
4221
  RuntimeJournalAppendInputSchema,
4165
4222
  async (input) => jsonResult(await runtimeJournalAppend(input, context))
4166
4223
  );
4167
- server.tool(
4224
+ registerTool(
4168
4225
  "runtime_journal_tail",
4169
4226
  [
4170
4227
  "Read the last N entries from the runtime session journal (parsed JSON lines).",
@@ -4176,7 +4233,7 @@ function createHaiveServer(options = {}) {
4176
4233
  RuntimeJournalTailInputSchema,
4177
4234
  async (input) => jsonResult(await runtimeJournalTail(input, context))
4178
4235
  );
4179
- server.tool(
4236
+ registerTool(
4180
4237
  "pre_commit_check",
4181
4238
  [
4182
4239
  "One-shot 'should I block this commit?' check. Combines three signals:",
@@ -4201,7 +4258,7 @@ function createHaiveServer(options = {}) {
4201
4258
  return jsonResult(await preCommitCheck(input, context));
4202
4259
  }
4203
4260
  );
4204
- server.tool(
4261
+ registerTool(
4205
4262
  "pattern_detect",
4206
4263
  [
4207
4264
  "Heuristic memory detector \u2014 finds knowledge worth saving WITHOUT calling an LLM.",
@@ -4232,7 +4289,7 @@ function createHaiveServer(options = {}) {
4232
4289
  return jsonResult(await patternDetect(input, context));
4233
4290
  }
4234
4291
  );
4235
- server.tool(
4292
+ registerTool(
4236
4293
  "mem_diff",
4237
4294
  [
4238
4295
  "Compare two memories side-by-side to decide if they should be merged.",
@@ -4249,40 +4306,46 @@ function createHaiveServer(options = {}) {
4249
4306
  MemDiffInputSchema,
4250
4307
  async (input) => jsonResult(await memDiff(input, context))
4251
4308
  );
4252
- server.prompt(
4253
- "bootstrap_project",
4254
- [
4255
- "Analyze the project codebase and write .ai/project-context.md \u2014 run once after haive init.",
4256
- "The AI explores the directory structure, reads key files (package.json, README, config),",
4257
- "identifies the tech stack, architectural patterns, key modules, and conventions,",
4258
- "then persists everything via bootstrap_project_save.",
4259
- "For multi-component projects, run with module param to create .ai/modules/<name>/context.md."
4260
- ].join(" "),
4261
- BootstrapProjectArgsSchema,
4262
- (args) => bootstrapProjectPrompt(args, context)
4263
- );
4264
- server.prompt(
4265
- "post_task",
4266
- [
4267
- "\u2B50 Post-task reflection \u2014 run at the end of every session to capture what you learned:",
4268
- "failed approaches (mem_tried), new conventions/decisions/gotchas (mem_save),",
4269
- "code discoveries (mem_observe), and an end-of-session recap (mem_session_end).",
4270
- "In autopilot mode a minimal recap saves automatically; calling this produces a richer one."
4271
- ].join(" "),
4272
- PostTaskArgsSchema,
4273
- (args) => postTaskPrompt(args, context)
4274
- );
4275
- server.prompt(
4276
- "import_docs",
4277
- [
4278
- "Import knowledge from a document (README, ADR, wiki, API spec) as hAIve memories.",
4279
- "Pass the full document content; the AI extracts up to 10 actionable memories",
4280
- "(conventions, decisions, gotchas, architecture) and saves them via mem_save.",
4281
- "Good candidates: ADRs, onboarding docs, runbooks, team wikis."
4282
- ].join(" "),
4283
- ImportDocsArgsSchema,
4284
- (args) => importDocsPrompt(args, context)
4285
- );
4309
+ if (shouldRegisterPrompt("bootstrap_project")) {
4310
+ server.prompt(
4311
+ "bootstrap_project",
4312
+ [
4313
+ "Analyze the project codebase and write .ai/project-context.md \u2014 run once after haive init.",
4314
+ "The AI explores the directory structure, reads key files (package.json, README, config),",
4315
+ "identifies the tech stack, architectural patterns, key modules, and conventions,",
4316
+ "then persists everything via bootstrap_project_save.",
4317
+ "For multi-component projects, run with module param to create .ai/modules/<name>/context.md."
4318
+ ].join(" "),
4319
+ BootstrapProjectArgsSchema,
4320
+ (args) => bootstrapProjectPrompt(args, context)
4321
+ );
4322
+ }
4323
+ if (shouldRegisterPrompt("post_task")) {
4324
+ server.prompt(
4325
+ "post_task",
4326
+ [
4327
+ "\u2B50 Post-task reflection \u2014 run at the end of every session to capture what you learned:",
4328
+ "failed approaches (mem_tried), new conventions/decisions/gotchas (mem_save),",
4329
+ "code discoveries (mem_observe), and an end-of-session recap (mem_session_end).",
4330
+ "In autopilot mode a minimal recap saves automatically; calling this produces a richer one."
4331
+ ].join(" "),
4332
+ PostTaskArgsSchema,
4333
+ (args) => postTaskPrompt(args, context)
4334
+ );
4335
+ }
4336
+ if (shouldRegisterPrompt("import_docs")) {
4337
+ server.prompt(
4338
+ "import_docs",
4339
+ [
4340
+ "Import knowledge from a document (README, ADR, wiki, API spec) as hAIve memories.",
4341
+ "Pass the full document content; the AI extracts up to 10 actionable memories",
4342
+ "(conventions, decisions, gotchas, architecture) and saves them via mem_save.",
4343
+ "Good candidates: ADRs, onboarding docs, runbooks, team wikis."
4344
+ ].join(" "),
4345
+ ImportDocsArgsSchema,
4346
+ (args) => importDocsPrompt(args, context)
4347
+ );
4348
+ }
4286
4349
  return { server, context, tracker };
4287
4350
  }
4288
4351
  function parseMcpCliArgs(argv) {
@@ -4307,7 +4370,7 @@ function printHaiveMcpVersion() {
4307
4370
  console.log(SERVER_VERSION);
4308
4371
  }
4309
4372
  async function runHaiveMcpStdio(options) {
4310
- const { server, context } = createHaiveServer({ root: options.root });
4373
+ const { server, context } = createHaiveServer({ root: options.root, env: process.env });
4311
4374
  console.error(
4312
4375
  `[haive-mcp] starting server v${SERVER_VERSION} (project root: ${context.paths.root})`
4313
4376
  );