@hiveai/mcp 0.9.7 → 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/index.js CHANGED
@@ -3451,8 +3451,9 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
3451
3451
  }
3452
3452
 
3453
3453
  // src/server.ts
3454
+ import { loadConfigSync } from "@hiveai/core";
3454
3455
  var SERVER_NAME = "haive";
3455
- var SERVER_VERSION = "0.9.7";
3456
+ var SERVER_VERSION = "0.9.8";
3456
3457
  function jsonResult(data) {
3457
3458
  return {
3458
3459
  content: [
@@ -3463,15 +3464,70 @@ function jsonResult(data) {
3463
3464
  ]
3464
3465
  };
3465
3466
  }
3467
+ var ENFORCEMENT_PROFILE_TOOLS = /* @__PURE__ */ new Set([
3468
+ "get_briefing",
3469
+ "mem_save",
3470
+ "mem_tried",
3471
+ "mem_search",
3472
+ "mem_get",
3473
+ "mem_update",
3474
+ "mem_verify",
3475
+ "mem_relevant_to",
3476
+ "code_map",
3477
+ "pre_commit_check"
3478
+ ]);
3479
+ var BRIEFING_TOOLS = /* @__PURE__ */ new Set(["get_briefing", "mem_relevant_to"]);
3480
+ var MUTATING_TOOLS = /* @__PURE__ */ new Set([
3481
+ "mem_save",
3482
+ "mem_tried",
3483
+ "mem_observe",
3484
+ "mem_session_end",
3485
+ "bootstrap_project_save",
3486
+ "mem_update",
3487
+ "mem_approve",
3488
+ "mem_reject",
3489
+ "mem_delete",
3490
+ "runtime_journal_append",
3491
+ "pattern_detect"
3492
+ ]);
3466
3493
  function createHaiveServer(options = {}) {
3467
3494
  const context = createContext(options);
3495
+ const config = loadConfigSync(context.paths);
3496
+ const toolProfile = options.env?.HAIVE_TOOL_PROFILE ?? config.enforcement?.toolProfile ?? "enforcement";
3497
+ const requireBriefingFirst = options.env?.HAIVE_REQUIRE_BRIEFING_FIRST === "0" ? false : config.enforcement?.requireBriefingFirst ?? true;
3498
+ let briefingLoaded = false;
3468
3499
  const tracker = new SessionTracker(context);
3469
3500
  void tracker.init();
3470
3501
  const server = new McpServer(
3471
3502
  { name: SERVER_NAME, version: SERVER_VERSION },
3472
3503
  { capabilities: { tools: {}, prompts: {} } }
3473
3504
  );
3474
- server.tool(
3505
+ const shouldRegisterTool = (name) => toolProfile === "full" || ENFORCEMENT_PROFILE_TOOLS.has(name);
3506
+ const registerTool = (name, description, schema, handler) => {
3507
+ if (!shouldRegisterTool(name)) return;
3508
+ const tool = server.tool.bind(server);
3509
+ tool(
3510
+ name,
3511
+ description,
3512
+ schema,
3513
+ async (input) => {
3514
+ if (BRIEFING_TOOLS.has(name)) {
3515
+ briefingLoaded = true;
3516
+ return await handler(input);
3517
+ }
3518
+ if (requireBriefingFirst && MUTATING_TOOLS.has(name) && !briefingLoaded) {
3519
+ return jsonResult({
3520
+ error: "haive_briefing_required",
3521
+ message: "This hAIve project requires get_briefing or mem_relevant_to before state-changing hAIve tools. Call get_briefing({ task: '...' }) first.",
3522
+ tool: name
3523
+ });
3524
+ }
3525
+ return await handler(input);
3526
+ }
3527
+ );
3528
+ };
3529
+ const shouldRegisterPrompt = (name) => toolProfile === "full" || name === "bootstrap_project" || name === "post_task";
3530
+ registerTool(
3475
3531
  "mem_save",
3476
3532
  [
3477
3533
  "Save a piece of knowledge as a persistent memory that survives across AI sessions.",
@@ -3503,7 +3559,7 @@ function createHaiveServer(options = {}) {
3503
3559
  return jsonResult(await memSave(input, context));
3504
3560
  }
3505
3561
  );
3506
- server.tool(
3562
+ registerTool(
3507
3563
  "mem_suggest_topic",
3508
3564
  [
3509
3565
  "Propose a stable `topic` key (topic-upsert) from type + short title.",
@@ -3520,7 +3576,7 @@ function createHaiveServer(options = {}) {
3520
3576
  MemSuggestTopicInputSchema,
3521
3577
  async (input) => jsonResult(await memSuggestTopic(input, context))
3522
3578
  );
3523
- server.tool(
3579
+ registerTool(
3524
3580
  "mem_tried",
3525
3581
  [
3526
3582
  "Record a FAILED approach so future agents don't repeat the same mistake.",
@@ -3547,7 +3603,7 @@ function createHaiveServer(options = {}) {
3547
3603
  return jsonResult(await memTried(input, context));
3548
3604
  }
3549
3605
  );
3550
- server.tool(
3606
+ registerTool(
3551
3607
  "mem_observe",
3552
3608
  [
3553
3609
  "Capture a code-level discovery made WHILE READING existing code.",
@@ -3579,7 +3635,7 @@ function createHaiveServer(options = {}) {
3579
3635
  return jsonResult(await memObserve(input, context));
3580
3636
  }
3581
3637
  );
3582
- server.tool(
3638
+ registerTool(
3583
3639
  "mem_session_end",
3584
3640
  [
3585
3641
  "Save an end-of-session recap so the NEXT session starts with fresh context.",
@@ -3608,7 +3664,7 @@ function createHaiveServer(options = {}) {
3608
3664
  return jsonResult(await memSessionEnd(input, context));
3609
3665
  }
3610
3666
  );
3611
- server.tool(
3667
+ registerTool(
3612
3668
  "get_briefing",
3613
3669
  [
3614
3670
  "\u2B50 DEFAULT-FIRST for coding agents on any repo where `haive init` ran: call this BEFORE",
@@ -3659,7 +3715,7 @@ function createHaiveServer(options = {}) {
3659
3715
  return jsonResult(await getBriefing(input, context));
3660
3716
  }
3661
3717
  );
3662
- server.tool(
3718
+ registerTool(
3663
3719
  "mem_search",
3664
3720
  [
3665
3721
  "Search memories by keyword or semantic similarity.",
@@ -3691,7 +3747,7 @@ function createHaiveServer(options = {}) {
3691
3747
  return jsonResult(await memSearch(input, context));
3692
3748
  }
3693
3749
  );
3694
- server.tool(
3750
+ registerTool(
3695
3751
  "mem_timeline",
3696
3752
  [
3697
3753
  "Chronological view of related memories: by shared frontmatter.topic OR expanded from a seed id",
@@ -3707,7 +3763,7 @@ function createHaiveServer(options = {}) {
3707
3763
  MemTimelineInputSchema,
3708
3764
  async (input) => jsonResult(await memTimeline(input, context))
3709
3765
  );
3710
- server.tool(
3766
+ registerTool(
3711
3767
  "mem_for_files",
3712
3768
  [
3713
3769
  "Surface memories relevant to the files you are currently editing.",
@@ -3731,7 +3787,7 @@ function createHaiveServer(options = {}) {
3731
3787
  MemForFilesInputSchema,
3732
3788
  async (input) => jsonResult(await memForFiles(input, context))
3733
3789
  );
3734
- server.tool(
3790
+ registerTool(
3735
3791
  "mem_get",
3736
3792
  [
3737
3793
  "Fetch a single memory by its full id with all details.",
@@ -3747,7 +3803,7 @@ function createHaiveServer(options = {}) {
3747
3803
  MemGetInputSchema,
3748
3804
  async (input) => jsonResult(await memGet(input, context))
3749
3805
  );
3750
- server.tool(
3806
+ registerTool(
3751
3807
  "mem_list",
3752
3808
  [
3753
3809
  "List memories with optional filters. Use for browsing, not for task onboarding.",
@@ -3767,7 +3823,7 @@ function createHaiveServer(options = {}) {
3767
3823
  MemListInputSchema,
3768
3824
  async (input) => jsonResult(await memList(input, context))
3769
3825
  );
3770
- server.tool(
3826
+ registerTool(
3771
3827
  "get_project_context",
3772
3828
  [
3773
3829
  "Read .ai/project-context.md (and optionally a module context) directly.",
@@ -3785,7 +3841,7 @@ function createHaiveServer(options = {}) {
3785
3841
  GetProjectContextInputSchema,
3786
3842
  async (input) => jsonResult(await getProjectContext(input, context))
3787
3843
  );
3788
- server.tool(
3844
+ registerTool(
3789
3845
  "bootstrap_project_save",
3790
3846
  [
3791
3847
  "Persist the project context document (.ai/project-context.md) or a module",
@@ -3803,7 +3859,7 @@ function createHaiveServer(options = {}) {
3803
3859
  BootstrapProjectSaveInputSchema,
3804
3860
  async (input) => jsonResult(await bootstrapProjectSave(input, context))
3805
3861
  );
3806
- server.tool(
3862
+ registerTool(
3807
3863
  "code_map",
3808
3864
  [
3809
3865
  "Look up where symbols (classes, functions, interfaces) are defined in the codebase.",
@@ -3824,7 +3880,7 @@ function createHaiveServer(options = {}) {
3824
3880
  CodeMapInputSchema,
3825
3881
  async (input) => jsonResult(await codeMapTool(input, context))
3826
3882
  );
3827
- server.tool(
3883
+ registerTool(
3828
3884
  "mem_resolve_project",
3829
3885
  [
3830
3886
  "Diagnostics: resolve which project root hAIve is using (never throws).",
@@ -3840,7 +3896,7 @@ function createHaiveServer(options = {}) {
3840
3896
  MemResolveProjectInputSchema,
3841
3897
  async (input) => jsonResult(await memResolveProject(input, context))
3842
3898
  );
3843
- server.tool(
3899
+ registerTool(
3844
3900
  "mem_update",
3845
3901
  [
3846
3902
  "Update the body, tags, or anchor of an existing memory in-place.",
@@ -3863,7 +3919,7 @@ function createHaiveServer(options = {}) {
3863
3919
  MemUpdateInputSchema,
3864
3920
  async (input) => jsonResult(await memUpdate(input, context))
3865
3921
  );
3866
- server.tool(
3922
+ registerTool(
3867
3923
  "mem_verify",
3868
3924
  [
3869
3925
  "Check whether memory anchor paths and symbols still exist in the current code.",
@@ -3882,7 +3938,7 @@ function createHaiveServer(options = {}) {
3882
3938
  MemVerifyInputSchema,
3883
3939
  async (input) => jsonResult(await memVerify(input, context))
3884
3940
  );
3885
- server.tool(
3941
+ registerTool(
3886
3942
  "mem_approve",
3887
3943
  [
3888
3944
  "Mark a memory as validated (trusted, approved by a human or the team).",
@@ -3898,7 +3954,7 @@ function createHaiveServer(options = {}) {
3898
3954
  MemApproveInputSchema,
3899
3955
  async (input) => jsonResult(await memApprove(input, context))
3900
3956
  );
3901
- server.tool(
3957
+ registerTool(
3902
3958
  "mem_reject",
3903
3959
  [
3904
3960
  "Mark a memory as rejected and record a reason.",
@@ -3916,7 +3972,7 @@ function createHaiveServer(options = {}) {
3916
3972
  MemRejectInputSchema,
3917
3973
  async (input) => jsonResult(await memReject(input, context))
3918
3974
  );
3919
- server.tool(
3975
+ registerTool(
3920
3976
  "mem_pending",
3921
3977
  [
3922
3978
  "List memories in 'proposed' status awaiting review, sorted by read count.",
@@ -3932,7 +3988,7 @@ function createHaiveServer(options = {}) {
3932
3988
  MemPendingInputSchema,
3933
3989
  async (input) => jsonResult(await memPending(input, context))
3934
3990
  );
3935
- server.tool(
3991
+ registerTool(
3936
3992
  "mem_delete",
3937
3993
  [
3938
3994
  "Permanently delete a memory by id.",
@@ -3949,7 +4005,7 @@ function createHaiveServer(options = {}) {
3949
4005
  MemDeleteInputSchema,
3950
4006
  async (input) => jsonResult(await memDelete(input, context))
3951
4007
  );
3952
- server.tool(
4008
+ registerTool(
3953
4009
  "get_recap",
3954
4010
  [
3955
4011
  "Return ONLY the most recent session_recap. Cheaper than get_briefing when",
@@ -3967,7 +4023,7 @@ function createHaiveServer(options = {}) {
3967
4023
  return jsonResult(await getRecap(input, context));
3968
4024
  }
3969
4025
  );
3970
- server.tool(
4026
+ registerTool(
3971
4027
  "mem_relevant_to",
3972
4028
  [
3973
4029
  "One-shot ranked memories for a task \u2014 use instead of get_briefing when",
@@ -3993,7 +4049,7 @@ function createHaiveServer(options = {}) {
3993
4049
  return jsonResult(await memRelevantTo(input, context));
3994
4050
  }
3995
4051
  );
3996
- server.tool(
4052
+ registerTool(
3997
4053
  "code_search",
3998
4054
  [
3999
4055
  "Semantic search over the codebase \u2014 finds exported symbols (functions, classes,",
@@ -4016,7 +4072,7 @@ function createHaiveServer(options = {}) {
4016
4072
  return jsonResult(await codeSearch(input, context));
4017
4073
  }
4018
4074
  );
4019
- server.tool(
4075
+ registerTool(
4020
4076
  "why_this_file",
4021
4077
  [
4022
4078
  "One-shot file-context lookup: combines recent git history, memories anchored",
@@ -4036,7 +4092,7 @@ function createHaiveServer(options = {}) {
4036
4092
  return jsonResult(await whyThisFile(input, context));
4037
4093
  }
4038
4094
  );
4039
- server.tool(
4095
+ registerTool(
4040
4096
  "anti_patterns_check",
4041
4097
  [
4042
4098
  "Scan a diff (or set of paths) against documented attempt/gotcha memories.",
@@ -4059,7 +4115,7 @@ function createHaiveServer(options = {}) {
4059
4115
  return jsonResult(await antiPatternsCheck(input, context));
4060
4116
  }
4061
4117
  );
4062
- server.tool(
4118
+ registerTool(
4063
4119
  "mem_distill",
4064
4120
  [
4065
4121
  "Cluster recurring observations / failed attempts so a human can collapse",
@@ -4084,7 +4140,7 @@ function createHaiveServer(options = {}) {
4084
4140
  return jsonResult(await memDistill(input, context));
4085
4141
  }
4086
4142
  );
4087
- server.tool(
4143
+ registerTool(
4088
4144
  "why_this_decision",
4089
4145
  [
4090
4146
  "Trace the genealogy of a memory (especially decision/architecture):",
@@ -4106,7 +4162,7 @@ function createHaiveServer(options = {}) {
4106
4162
  return jsonResult(await whyThisDecision(input, context));
4107
4163
  }
4108
4164
  );
4109
- server.tool(
4165
+ registerTool(
4110
4166
  "mem_conflicts_with",
4111
4167
  [
4112
4168
  "Detect memories that potentially CONTRADICT a given memory.",
@@ -4132,7 +4188,7 @@ function createHaiveServer(options = {}) {
4132
4188
  return jsonResult(await memConflicts(input, context));
4133
4189
  }
4134
4190
  );
4135
- server.tool(
4191
+ registerTool(
4136
4192
  "mem_conflict_candidates",
4137
4193
  [
4138
4194
  "Bulk scan for conflict CANDIDATES (not proof):",
@@ -4153,7 +4209,7 @@ function createHaiveServer(options = {}) {
4153
4209
  return jsonResult(await memConflictCandidates(input, context));
4154
4210
  }
4155
4211
  );
4156
- server.tool(
4212
+ registerTool(
4157
4213
  "runtime_journal_append",
4158
4214
  [
4159
4215
  "Append one line to `.ai/.runtime/session-journal.ndjson` \u2014 machine-local session continuity.",
@@ -4167,7 +4223,7 @@ function createHaiveServer(options = {}) {
4167
4223
  RuntimeJournalAppendInputSchema,
4168
4224
  async (input) => jsonResult(await runtimeJournalAppend(input, context))
4169
4225
  );
4170
- server.tool(
4226
+ registerTool(
4171
4227
  "runtime_journal_tail",
4172
4228
  [
4173
4229
  "Read the last N entries from the runtime session journal (parsed JSON lines).",
@@ -4179,7 +4235,7 @@ function createHaiveServer(options = {}) {
4179
4235
  RuntimeJournalTailInputSchema,
4180
4236
  async (input) => jsonResult(await runtimeJournalTail(input, context))
4181
4237
  );
4182
- server.tool(
4238
+ registerTool(
4183
4239
  "pre_commit_check",
4184
4240
  [
4185
4241
  "One-shot 'should I block this commit?' check. Combines three signals:",
@@ -4204,7 +4260,7 @@ function createHaiveServer(options = {}) {
4204
4260
  return jsonResult(await preCommitCheck(input, context));
4205
4261
  }
4206
4262
  );
4207
- server.tool(
4263
+ registerTool(
4208
4264
  "pattern_detect",
4209
4265
  [
4210
4266
  "Heuristic memory detector \u2014 finds knowledge worth saving WITHOUT calling an LLM.",
@@ -4235,7 +4291,7 @@ function createHaiveServer(options = {}) {
4235
4291
  return jsonResult(await patternDetect(input, context));
4236
4292
  }
4237
4293
  );
4238
- server.tool(
4294
+ registerTool(
4239
4295
  "mem_diff",
4240
4296
  [
4241
4297
  "Compare two memories side-by-side to decide if they should be merged.",
@@ -4252,40 +4308,46 @@ function createHaiveServer(options = {}) {
4252
4308
  MemDiffInputSchema,
4253
4309
  async (input) => jsonResult(await memDiff(input, context))
4254
4310
  );
4255
- server.prompt(
4256
- "bootstrap_project",
4257
- [
4258
- "Analyze the project codebase and write .ai/project-context.md \u2014 run once after haive init.",
4259
- "The AI explores the directory structure, reads key files (package.json, README, config),",
4260
- "identifies the tech stack, architectural patterns, key modules, and conventions,",
4261
- "then persists everything via bootstrap_project_save.",
4262
- "For multi-component projects, run with module param to create .ai/modules/<name>/context.md."
4263
- ].join(" "),
4264
- BootstrapProjectArgsSchema,
4265
- (args) => bootstrapProjectPrompt(args, context)
4266
- );
4267
- server.prompt(
4268
- "post_task",
4269
- [
4270
- "\u2B50 Post-task reflection \u2014 run at the end of every session to capture what you learned:",
4271
- "failed approaches (mem_tried), new conventions/decisions/gotchas (mem_save),",
4272
- "code discoveries (mem_observe), and an end-of-session recap (mem_session_end).",
4273
- "In autopilot mode a minimal recap saves automatically; calling this produces a richer one."
4274
- ].join(" "),
4275
- PostTaskArgsSchema,
4276
- (args) => postTaskPrompt(args, context)
4277
- );
4278
- server.prompt(
4279
- "import_docs",
4280
- [
4281
- "Import knowledge from a document (README, ADR, wiki, API spec) as hAIve memories.",
4282
- "Pass the full document content; the AI extracts up to 10 actionable memories",
4283
- "(conventions, decisions, gotchas, architecture) and saves them via mem_save.",
4284
- "Good candidates: ADRs, onboarding docs, runbooks, team wikis."
4285
- ].join(" "),
4286
- ImportDocsArgsSchema,
4287
- (args) => importDocsPrompt(args, context)
4288
- );
4311
+ if (shouldRegisterPrompt("bootstrap_project")) {
4312
+ server.prompt(
4313
+ "bootstrap_project",
4314
+ [
4315
+ "Analyze the project codebase and write .ai/project-context.md \u2014 run once after haive init.",
4316
+ "The AI explores the directory structure, reads key files (package.json, README, config),",
4317
+ "identifies the tech stack, architectural patterns, key modules, and conventions,",
4318
+ "then persists everything via bootstrap_project_save.",
4319
+ "For multi-component projects, run with module param to create .ai/modules/<name>/context.md."
4320
+ ].join(" "),
4321
+ BootstrapProjectArgsSchema,
4322
+ (args) => bootstrapProjectPrompt(args, context)
4323
+ );
4324
+ }
4325
+ if (shouldRegisterPrompt("post_task")) {
4326
+ server.prompt(
4327
+ "post_task",
4328
+ [
4329
+ "\u2B50 Post-task reflection \u2014 run at the end of every session to capture what you learned:",
4330
+ "failed approaches (mem_tried), new conventions/decisions/gotchas (mem_save),",
4331
+ "code discoveries (mem_observe), and an end-of-session recap (mem_session_end).",
4332
+ "In autopilot mode a minimal recap saves automatically; calling this produces a richer one."
4333
+ ].join(" "),
4334
+ PostTaskArgsSchema,
4335
+ (args) => postTaskPrompt(args, context)
4336
+ );
4337
+ }
4338
+ if (shouldRegisterPrompt("import_docs")) {
4339
+ server.prompt(
4340
+ "import_docs",
4341
+ [
4342
+ "Import knowledge from a document (README, ADR, wiki, API spec) as hAIve memories.",
4343
+ "Pass the full document content; the AI extracts up to 10 actionable memories",
4344
+ "(conventions, decisions, gotchas, architecture) and saves them via mem_save.",
4345
+ "Good candidates: ADRs, onboarding docs, runbooks, team wikis."
4346
+ ].join(" "),
4347
+ ImportDocsArgsSchema,
4348
+ (args) => importDocsPrompt(args, context)
4349
+ );
4350
+ }
4289
4351
  return { server, context, tracker };
4290
4352
  }
4291
4353
  function parseMcpCliArgs(argv) {
@@ -4310,7 +4372,7 @@ function printHaiveMcpVersion() {
4310
4372
  console.log(SERVER_VERSION);
4311
4373
  }
4312
4374
  async function runHaiveMcpStdio(options) {
4313
- const { server, context } = createHaiveServer({ root: options.root });
4375
+ const { server, context } = createHaiveServer({ root: options.root, env: process.env });
4314
4376
  console.error(
4315
4377
  `[haive-mcp] starting server v${SERVER_VERSION} (project root: ${context.paths.root})`
4316
4378
  );