brainllm 13.1.0 → 13.1.2

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
@@ -10,13 +10,15 @@ Self-hosted memory for LLMs in [TriliumNext Notes](https://github.com/TriliumNex
10
10
 
11
11
  [**Site**](https://miisodev.github.io/BrainLLM/) · [Connect to Claude](https://miisodev.github.io/BrainLLM/connect.html) · [How it works](https://miisodev.github.io/BrainLLM/how-it-works.html) · [Docs](https://miisodev.github.io/BrainLLM/docs.html) · [Privacy](https://miisodev.github.io/BrainLLM/privacy.html)
12
12
 
13
- [![Version](https://img.shields.io/badge/version-13.1.0-f59e0b?style=flat-square)](https://github.com/miisodev/BrainLLM/releases)
13
+ [![Version](https://img.shields.io/badge/version-13.1.2-f59e0b?style=flat-square)](https://github.com/miisodev/BrainLLM/releases)
14
14
  [![CI](https://img.shields.io/github/actions/workflow/status/miisodev/BrainLLM/ci.yml?branch=main&style=flat-square&label=CI&color=f59e0b)](https://github.com/miisodev/BrainLLM/actions/workflows/ci.yml)
15
15
  [![License: MIT](https://img.shields.io/badge/license-MIT-a1a1aa?style=flat-square)](./LICENSE)
16
16
  [![Runtime: Bun](https://img.shields.io/badge/runtime-Bun%20%E2%89%A5%201.0-a1a1aa?style=flat-square&logo=bun&logoColor=white)](https://bun.sh)
17
17
  [![MCP](https://img.shields.io/badge/protocol-MCP-0a0a0f?style=flat-square)](https://modelcontextprotocol.io)
18
18
  [![Sponsor](https://img.shields.io/badge/❤-Sponsor-f59e0b?style=flat-square&logo=githubsponsors&logoColor=white)](https://github.com/sponsors/miisodev)
19
19
 
20
+ [![Brainllm MCP server](https://mcprush.com/badge/brainllm-mcp/card.svg)](https://mcprush.com/to/brainllm-mcp?ref=badge)
21
+
20
22
  </div>
21
23
 
22
24
  ---
package/dist/index.js CHANGED
@@ -3286,6 +3286,37 @@ var require_utils = __commonJS(function(exports, module) {
3286
3286
  }
3287
3287
  return output.join("");
3288
3288
  }
3289
+ function removeDotSegmentsRelative(path) {
3290
+ if (path === "" || path[0] === "/") {
3291
+ return removeDotSegments(path);
3292
+ }
3293
+ const segments = path.split("/");
3294
+ const last = segments.length - 1;
3295
+ const output = [];
3296
+ let trailingDirectory = false;
3297
+ for (let i = 0;i <= last; i++) {
3298
+ const segment = segments[i];
3299
+ if (segment === "." || segment === "..") {
3300
+ if (segment === "..") {
3301
+ if (output.length !== 0 && output[output.length - 1] !== "..") {
3302
+ output.pop();
3303
+ } else {
3304
+ output.push("..");
3305
+ }
3306
+ }
3307
+ trailingDirectory = i === last;
3308
+ } else {
3309
+ output.push(segment);
3310
+ }
3311
+ }
3312
+ if (trailingDirectory && output[output.length - 1] !== "..") {
3313
+ output.push("");
3314
+ }
3315
+ if (output.length === 0 || output[0] === "" || output[0].includes(":")) {
3316
+ output.unshift(".");
3317
+ }
3318
+ return output.join("/");
3319
+ }
3289
3320
  var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
3290
3321
  var HOST_DELIM_RE = /[@/?#:]/g;
3291
3322
  var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
@@ -3546,6 +3577,7 @@ var require_utils = __commonJS(function(exports, module) {
3546
3577
  encodeFragment,
3547
3578
  escapePreservingEscapes,
3548
3579
  removeDotSegments,
3580
+ removeDotSegmentsRelative,
3549
3581
  isIPv4,
3550
3582
  isUUID,
3551
3583
  normalizeIPv6,
@@ -3730,16 +3762,18 @@ var require_schemes = __commonJS(function(exports, module) {
3730
3762
 
3731
3763
  // node_modules/fast-uri/index.js
3732
3764
  var require_fast_uri = __commonJS(function(exports, module) {
3733
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3765
+ var { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3734
3766
  var { SCHEMES, getSchemeHandler } = require_schemes();
3735
3767
  var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
3736
3768
  var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
3737
- function decodeValidScheme(scheme) {
3738
- const decodedScheme = unescape(String(scheme));
3739
- if (!VALID_SCHEME.test(decodedScheme)) {
3769
+ var MALFORMED_HOST_ERROR = "URI host is malformed.";
3770
+ var FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
3771
+ function validateScheme(scheme) {
3772
+ const stringScheme = String(scheme);
3773
+ if (!VALID_SCHEME.test(stringScheme)) {
3740
3774
  throw new TypeError(MALFORMED_SCHEME_ERROR);
3741
3775
  }
3742
- return decodedScheme;
3776
+ return stringScheme;
3743
3777
  }
3744
3778
  function normalize(uri, options) {
3745
3779
  if (typeof uri === "string") {
@@ -3774,6 +3808,9 @@ var require_fast_uri = __commonJS(function(exports, module) {
3774
3808
  const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
3775
3809
  const resolvedHost = resolved.host;
3776
3810
  const resolvedHostIsIP = resolvedHost !== undefined && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
3811
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
3812
+ throw new Error(MALFORMED_HOST_ERROR);
3813
+ }
3777
3814
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
3778
3815
  const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
3779
3816
  if (resolved.error && !encodedASCIIHost) {
@@ -3815,14 +3852,15 @@ var require_fast_uri = __commonJS(function(exports, module) {
3815
3852
  if (relative.path[0] === "/") {
3816
3853
  target.path = removeDotSegments(relative.path);
3817
3854
  } else {
3818
- if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
3855
+ const baseHasAuthority = base.userinfo !== undefined || base.host !== undefined || base.port !== undefined;
3856
+ if (baseHasAuthority && !base.path) {
3819
3857
  target.path = "/" + relative.path;
3820
3858
  } else if (!base.path) {
3821
3859
  target.path = relative.path;
3822
3860
  } else {
3823
3861
  target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
3824
3862
  }
3825
- target.path = removeDotSegments(target.path);
3863
+ target.path = base.scheme === undefined && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
3826
3864
  }
3827
3865
  target.query = relative.query;
3828
3866
  }
@@ -3860,13 +3898,14 @@ var require_fast_uri = __commonJS(function(exports, module) {
3860
3898
  const options = Object.assign({}, opts);
3861
3899
  const uriTokens = [];
3862
3900
  if (component.scheme) {
3863
- component.scheme = decodeValidScheme(component.scheme);
3901
+ component.scheme = validateScheme(component.scheme);
3864
3902
  }
3865
3903
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
3866
3904
  if (schemeHandler && schemeHandler.serialize)
3867
3905
  schemeHandler.serialize(component, options);
3868
3906
  const hasAuthority = component.userinfo !== undefined || component.host !== undefined || component.port !== undefined;
3869
- const pathNoScheme = !options.skipEscape && component.scheme === undefined && !hasAuthority;
3907
+ const schemelessReference = (component.scheme === undefined || options.reference === "suffix") && !hasAuthority;
3908
+ const pathNoScheme = !options.skipEscape && schemelessReference;
3870
3909
  if (component.path !== undefined) {
3871
3910
  if (!options.skipEscape) {
3872
3911
  component.path = serializePathEncoding(component.path, pathNoScheme);
@@ -3875,7 +3914,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
3875
3914
  }
3876
3915
  }
3877
3916
  if (options.reference !== "suffix" && component.scheme) {
3878
- component.scheme = decodeValidScheme(component.scheme);
3917
+ component.scheme = validateScheme(component.scheme);
3879
3918
  uriTokens.push(component.scheme, ":");
3880
3919
  }
3881
3920
  const authority = recomposeAuthority(component);
@@ -3891,9 +3930,9 @@ var require_fast_uri = __commonJS(function(exports, module) {
3891
3930
  if (component.path !== undefined) {
3892
3931
  let s = component.path;
3893
3932
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
3894
- s = removeDotSegments(s);
3933
+ s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
3895
3934
  }
3896
- if (pathNoScheme) {
3935
+ if (schemelessReference) {
3897
3936
  s = serializePathEncoding(s, true);
3898
3937
  }
3899
3938
  if (authority === undefined && s[0] === "/" && s[1] === "/") {
@@ -3941,16 +3980,32 @@ var require_fast_uri = __commonJS(function(exports, module) {
3941
3980
  return hasMalformedPercentEncoding(matches[3]) || host !== undefined && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
3942
3981
  }
3943
3982
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
3983
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
3984
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
3985
+ return true;
3986
+ }
3944
3987
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3988
+ let url;
3945
3989
  try {
3946
- parsed.host = new URL("http://" + parsed.host).hostname;
3990
+ url = new URL("http://" + parsed.host);
3947
3991
  } catch (e) {
3948
3992
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3949
3993
  return true;
3950
3994
  }
3995
+ if (!isHostOnlyURL(url)) {
3996
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
3997
+ return true;
3998
+ }
3999
+ parsed.host = url.hostname;
3951
4000
  }
3952
4001
  return false;
3953
4002
  }
4003
+ function hasForbiddenDomainHost(parsed, options, schemeHandler, isIP) {
4004
+ return Boolean(parsed.host && isIP === false && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host));
4005
+ }
4006
+ function isHostOnlyURL(url) {
4007
+ return url.username === "" && url.password === "" && url.port === "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.hostname !== "";
4008
+ }
3954
4009
  function parseWithStatus(uri, opts) {
3955
4010
  const options = Object.assign({}, opts);
3956
4011
  const parsed = {
@@ -4005,9 +4060,8 @@ var require_fast_uri = __commonJS(function(exports, module) {
4005
4060
  parsed.query = matches[7];
4006
4061
  parsed.fragment = matches[8];
4007
4062
  if (parsed.scheme !== undefined) {
4008
- const decodedScheme = unescape(parsed.scheme);
4009
- if (VALID_SCHEME.test(decodedScheme)) {
4010
- parsed.scheme = decodedScheme.toLowerCase();
4063
+ if (VALID_SCHEME.test(parsed.scheme)) {
4064
+ parsed.scheme = parsed.scheme.toLowerCase();
4011
4065
  } else {
4012
4066
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
4013
4067
  malformedScheme = true;
@@ -4035,7 +4089,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
4035
4089
  malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4036
4090
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4037
4091
  if (malformedIPLiteral) {
4038
- parsed.error = parsed.error || "URI host is malformed.";
4092
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4039
4093
  malformedAuthorityOrPort = true;
4040
4094
  }
4041
4095
  } else {
@@ -4063,7 +4117,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
4063
4117
  if (!isIP) {
4064
4118
  host = normalizePercentEncoding(host.toLowerCase());
4065
4119
  }
4066
- parsed.host = reescapeHostDelimiters(host, isIP);
4120
+ parsed.host = isIP || options.scheme !== "null" ? reescapeHostDelimiters(host, isIP) : host;
4067
4121
  }
4068
4122
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4069
4123
  if (parsed.path) {
@@ -20761,6 +20815,15 @@ class McpServer {
20761
20815
  this._promptHandlersInitialized = false;
20762
20816
  this.server = new Server(serverInfo, options);
20763
20817
  this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
20818
+ if (options?.capabilities?.tools) {
20819
+ this.setToolRequestHandlers();
20820
+ }
20821
+ if (options?.capabilities?.resources) {
20822
+ this.setResourceRequestHandlers();
20823
+ }
20824
+ if (options?.capabilities?.prompts) {
20825
+ this.setPromptRequestHandlers();
20826
+ }
20764
20827
  }
20765
20828
  get experimental() {
20766
20829
  if (!this._experimental) {
@@ -32928,7 +32991,7 @@ function createServer(origin = null) {
32928
32991
  const s = new McpServer({
32929
32992
  name: BRAND2.name,
32930
32993
  title: BRAND2.name,
32931
- version: "13.1.0",
32994
+ version: "13.1.2",
32932
32995
  description: BRAND2.description,
32933
32996
  websiteUrl: origin ?? BRAND2.website,
32934
32997
  icons: brandIcons(origin)
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "brainllm",
4
4
  "display_name": "BrainLLM",
5
- "version": "13.1.0",
5
+ "version": "13.1.2",
6
6
  "description": "Self-hosted memory for LLMs in TriliumNext, structured by the server and editable by you.",
7
7
  "long_description": "BrainLLM is an MCP server that organises memory into five purpose-built areas (Master, LLM, Memory, Knowledge, Insights). The model supplies content while the server owns placement, format, lifecycle, dates and backups. Includes a full raw ETAPI surface for advanced use. Requires a running TriliumNext instance and the Bun runtime.",
8
8
  "author": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainllm",
3
- "version": "13.1.0",
3
+ "version": "13.1.2",
4
4
  "mcpName": "io.github.miisodev/brainllm",
5
5
  "description": "Self-hosted memory for LLMs in TriliumNext, structured by the server and editable by you.",
6
6
  "author": "Kevin Miiso Novo <miisodev@gmail.com>",
@@ -62,11 +62,11 @@
62
62
  "prepublishOnly": "bun run build"
63
63
  },
64
64
  "dependencies": {
65
- "@modelcontextprotocol/sdk": "^1.32.0",
65
+ "@modelcontextprotocol/sdk": "^1.32.2",
66
66
  "zod": "^4.6.6"
67
67
  },
68
68
  "devDependencies": {
69
- "@types/bun": "latest",
69
+ "@types/bun": "^1.4.4",
70
70
  "ajv": "^8.20.0",
71
71
  "ajv-formats": "^3.0.1",
72
72
  "sharp": "^0.35.5",
package/server.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.miisodev/brainllm",
4
4
  "description": "Self-hosted memory for LLMs in TriliumNext, structured by the server and editable by you.",
5
- "version": "13.1.0",
5
+ "version": "13.1.2",
6
6
  "websiteUrl": "https://miisodev.github.io/BrainLLM/",
7
7
  "repository": {
8
8
  "url": "https://github.com/miisodev/BrainLLM",
@@ -12,7 +12,7 @@
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "brainllm",
15
- "version": "13.1.0",
15
+ "version": "13.1.2",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },