@selfagency/beans-mcp 0.4.2 → 0.5.0
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 +86 -12
- package/beans-mcp-server.cjs +451 -124
- package/index.cjs +451 -124
- package/index.d.ts +99 -0
- package/index.js +451 -124
- package/package.json +7 -6
package/index.js
CHANGED
|
@@ -14431,7 +14431,7 @@ var init_v4 = __esm({
|
|
|
14431
14431
|
}
|
|
14432
14432
|
});
|
|
14433
14433
|
|
|
14434
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14434
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
14435
14435
|
function assertCompleteRequestPrompt(request) {
|
|
14436
14436
|
if (request.params.ref.type !== "ref/prompt") {
|
|
14437
14437
|
throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
|
|
@@ -14446,7 +14446,7 @@ function assertCompleteRequestResourceTemplate(request) {
|
|
|
14446
14446
|
}
|
|
14447
14447
|
var LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
|
|
14448
14448
|
var init_types = __esm({
|
|
14449
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14449
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js"() {
|
|
14450
14450
|
"use strict";
|
|
14451
14451
|
init_v4();
|
|
14452
14452
|
LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
@@ -14458,10 +14458,9 @@ var init_types = __esm({
|
|
|
14458
14458
|
CursorSchema = string2();
|
|
14459
14459
|
TaskCreationParamsSchema = looseObject({
|
|
14460
14460
|
/**
|
|
14461
|
-
*
|
|
14462
|
-
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
14461
|
+
* Requested duration in milliseconds to retain task from creation.
|
|
14463
14462
|
*/
|
|
14464
|
-
ttl:
|
|
14463
|
+
ttl: number2().optional(),
|
|
14465
14464
|
/**
|
|
14466
14465
|
* Time in milliseconds to wait between task status requests.
|
|
14467
14466
|
*/
|
|
@@ -14760,7 +14759,11 @@ var init_types = __esm({
|
|
|
14760
14759
|
/**
|
|
14761
14760
|
* Present if the client supports task creation.
|
|
14762
14761
|
*/
|
|
14763
|
-
tasks: ClientTasksCapabilitySchema.optional()
|
|
14762
|
+
tasks: ClientTasksCapabilitySchema.optional(),
|
|
14763
|
+
/**
|
|
14764
|
+
* Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14765
|
+
*/
|
|
14766
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14764
14767
|
});
|
|
14765
14768
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
14766
14769
|
/**
|
|
@@ -14821,7 +14824,11 @@ var init_types = __esm({
|
|
|
14821
14824
|
/**
|
|
14822
14825
|
* Present if the server supports task creation.
|
|
14823
14826
|
*/
|
|
14824
|
-
tasks: ServerTasksCapabilitySchema.optional()
|
|
14827
|
+
tasks: ServerTasksCapabilitySchema.optional(),
|
|
14828
|
+
/**
|
|
14829
|
+
* Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14830
|
+
*/
|
|
14831
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14825
14832
|
});
|
|
14826
14833
|
InitializeResultSchema = ResultSchema.extend({
|
|
14827
14834
|
/**
|
|
@@ -15013,6 +15020,12 @@ var init_types = __esm({
|
|
|
15013
15020
|
* The MIME type of this resource, if known.
|
|
15014
15021
|
*/
|
|
15015
15022
|
mimeType: optional(string2()),
|
|
15023
|
+
/**
|
|
15024
|
+
* The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
|
|
15025
|
+
*
|
|
15026
|
+
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
15027
|
+
*/
|
|
15028
|
+
size: optional(number2()),
|
|
15016
15029
|
/**
|
|
15017
15030
|
* Optional annotations for the client.
|
|
15018
15031
|
*/
|
|
@@ -22744,7 +22757,7 @@ var init_utils = __esm({
|
|
|
22744
22757
|
});
|
|
22745
22758
|
|
|
22746
22759
|
// src/internal/graphql.ts
|
|
22747
|
-
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION;
|
|
22760
|
+
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION, LIST_BEANS_TIMESTAMPS_QUERY;
|
|
22748
22761
|
var init_graphql = __esm({
|
|
22749
22762
|
"src/internal/graphql.ts"() {
|
|
22750
22763
|
"use strict";
|
|
@@ -22772,6 +22785,11 @@ var init_graphql = __esm({
|
|
|
22772
22785
|
mutation($id: ID!) {
|
|
22773
22786
|
deleteBean(id: $id)
|
|
22774
22787
|
}
|
|
22788
|
+
`;
|
|
22789
|
+
LIST_BEANS_TIMESTAMPS_QUERY = `
|
|
22790
|
+
query {
|
|
22791
|
+
beans { id updatedAt }
|
|
22792
|
+
}
|
|
22775
22793
|
`;
|
|
22776
22794
|
}
|
|
22777
22795
|
});
|
|
@@ -22794,12 +22812,26 @@ var init_backend = __esm({
|
|
|
22794
22812
|
init_graphql();
|
|
22795
22813
|
init_utils();
|
|
22796
22814
|
execFileAsync = promisify(execFile);
|
|
22797
|
-
BeansCliBackend = class {
|
|
22815
|
+
BeansCliBackend = class _BeansCliBackend {
|
|
22798
22816
|
constructor(workspaceRoot, cliPath, logDir) {
|
|
22799
22817
|
this.workspaceRoot = workspaceRoot;
|
|
22800
22818
|
this.cliPath = cliPath;
|
|
22801
22819
|
this.logDir = logDir;
|
|
22802
22820
|
}
|
|
22821
|
+
// ---------------------------------------------------------------------------
|
|
22822
|
+
// Cache
|
|
22823
|
+
// ---------------------------------------------------------------------------
|
|
22824
|
+
/** Full unfiltered records keyed by bean ID, stored under the fixed cache key `'all'`. */
|
|
22825
|
+
_cache = /* @__PURE__ */ new Map();
|
|
22826
|
+
/** Last time the unfiltered cache entry `'all'` was fetched (ms). */
|
|
22827
|
+
_cacheTime = /* @__PURE__ */ new Map();
|
|
22828
|
+
/** Short-circuit TTL: skip even the timestamp check within this window (ms). */
|
|
22829
|
+
static BURST_TTL_MS = 5e3;
|
|
22830
|
+
/** Invalidate the unfiltered list cache so the next call does a full fetch. */
|
|
22831
|
+
invalidateCache() {
|
|
22832
|
+
this._cache.delete("all");
|
|
22833
|
+
this._cacheTime.delete("all");
|
|
22834
|
+
}
|
|
22803
22835
|
/**
|
|
22804
22836
|
* Returns a safe environment for executing the Beans CLI,
|
|
22805
22837
|
* whitelisting only necessary variables.
|
|
@@ -22823,7 +22855,7 @@ var init_backend = __esm({
|
|
|
22823
22855
|
return resolve2(this.workspaceRoot, ".beans");
|
|
22824
22856
|
}
|
|
22825
22857
|
resolveBeanFilePath(relativePath) {
|
|
22826
|
-
const cleaned = relativePath.trim().replace(/^\/+/, "");
|
|
22858
|
+
const cleaned = relativePath.trim().replace(/^\/+/, "").replace(/^\.beans(?:[\\/]|$)/, "");
|
|
22827
22859
|
if (!cleaned) {
|
|
22828
22860
|
throw new Error("Path is required");
|
|
22829
22861
|
}
|
|
@@ -22881,10 +22913,48 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22881
22913
|
if (options?.search) {
|
|
22882
22914
|
filter.search = options.search;
|
|
22883
22915
|
}
|
|
22916
|
+
const isCacheable = !filter.status && !filter.type && !filter.search;
|
|
22917
|
+
const cacheKey = "all";
|
|
22918
|
+
if (isCacheable) {
|
|
22919
|
+
const lastFetch = this._cacheTime.get(cacheKey) ?? 0;
|
|
22920
|
+
const cached2 = this._cache.get(cacheKey);
|
|
22921
|
+
const age = Date.now() - lastFetch;
|
|
22922
|
+
if (cached2 && age < _BeansCliBackend.BURST_TTL_MS) {
|
|
22923
|
+
return Array.from(cached2.values());
|
|
22924
|
+
}
|
|
22925
|
+
if (cached2) {
|
|
22926
|
+
try {
|
|
22927
|
+
const { data: tsData } = await this.executeGraphQL(
|
|
22928
|
+
LIST_BEANS_TIMESTAMPS_QUERY
|
|
22929
|
+
);
|
|
22930
|
+
const timestamps = tsData.beans;
|
|
22931
|
+
let dirty = timestamps.length !== cached2.size;
|
|
22932
|
+
if (!dirty) {
|
|
22933
|
+
for (const { id, updatedAt } of timestamps) {
|
|
22934
|
+
const existing = cached2.get(id);
|
|
22935
|
+
if (!existing || existing.updatedAt !== updatedAt) {
|
|
22936
|
+
dirty = true;
|
|
22937
|
+
break;
|
|
22938
|
+
}
|
|
22939
|
+
}
|
|
22940
|
+
}
|
|
22941
|
+
if (!dirty) {
|
|
22942
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22943
|
+
return Array.from(cached2.values());
|
|
22944
|
+
}
|
|
22945
|
+
} catch {
|
|
22946
|
+
}
|
|
22947
|
+
}
|
|
22948
|
+
}
|
|
22884
22949
|
const { data, errors } = await this.executeGraphQL(LIST_BEANS_QUERY, { filter });
|
|
22885
22950
|
if (errors && errors.length > 0) {
|
|
22886
22951
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22887
22952
|
}
|
|
22953
|
+
if (isCacheable) {
|
|
22954
|
+
const byId = new Map(data.beans.map((b) => [b.id, b]));
|
|
22955
|
+
this._cache.set(cacheKey, byId);
|
|
22956
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22957
|
+
}
|
|
22888
22958
|
return data.beans;
|
|
22889
22959
|
}
|
|
22890
22960
|
async create(input) {
|
|
@@ -22893,7 +22963,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22893
22963
|
type: input.type,
|
|
22894
22964
|
status: input.status,
|
|
22895
22965
|
priority: input.priority,
|
|
22896
|
-
body: input.description,
|
|
22966
|
+
body: input.body ?? input.description,
|
|
22897
22967
|
parent: input.parent
|
|
22898
22968
|
};
|
|
22899
22969
|
const { data, errors } = await this.executeGraphQL(CREATE_BEAN_MUTATION, {
|
|
@@ -22902,6 +22972,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22902
22972
|
if (errors && errors.length > 0) {
|
|
22903
22973
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22904
22974
|
}
|
|
22975
|
+
this.invalidateCache();
|
|
22905
22976
|
return data.createBean;
|
|
22906
22977
|
}
|
|
22907
22978
|
async update(beanId, updates) {
|
|
@@ -22971,6 +23042,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22971
23042
|
if (errors && errors.length > 0) {
|
|
22972
23043
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22973
23044
|
}
|
|
23045
|
+
this.invalidateCache();
|
|
22974
23046
|
return data.updateBean;
|
|
22975
23047
|
}
|
|
22976
23048
|
async delete(beanId) {
|
|
@@ -22980,8 +23052,37 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22980
23052
|
if (errors && errors.length > 0) {
|
|
22981
23053
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22982
23054
|
}
|
|
23055
|
+
this.invalidateCache();
|
|
22983
23056
|
return { deleted: true, beanId };
|
|
22984
23057
|
}
|
|
23058
|
+
async bulkCreate(beans, defaultParent) {
|
|
23059
|
+
const results = [];
|
|
23060
|
+
for (const item of beans) {
|
|
23061
|
+
try {
|
|
23062
|
+
const bean = await this.create({
|
|
23063
|
+
...item,
|
|
23064
|
+
parent: item.parent ?? defaultParent
|
|
23065
|
+
});
|
|
23066
|
+
results.push({ bean });
|
|
23067
|
+
} catch (error48) {
|
|
23068
|
+
results.push({ error: error48.message });
|
|
23069
|
+
}
|
|
23070
|
+
}
|
|
23071
|
+
return results;
|
|
23072
|
+
}
|
|
23073
|
+
async bulkUpdate(beans, defaultParent) {
|
|
23074
|
+
const results = [];
|
|
23075
|
+
for (const { beanId, ...updates } of beans) {
|
|
23076
|
+
try {
|
|
23077
|
+
const resolvedParent = updates.parent ?? (updates.clearParent ? void 0 : defaultParent);
|
|
23078
|
+
const bean = await this.update(beanId, { ...updates, parent: resolvedParent });
|
|
23079
|
+
results.push({ beanId, bean });
|
|
23080
|
+
} catch (error48) {
|
|
23081
|
+
results.push({ beanId, error: error48.message });
|
|
23082
|
+
}
|
|
23083
|
+
}
|
|
23084
|
+
return results;
|
|
23085
|
+
}
|
|
22985
23086
|
async openConfig() {
|
|
22986
23087
|
const configPath = join(this.workspaceRoot, ".beans.yml");
|
|
22987
23088
|
const content = await readFile(configPath, "utf8");
|
|
@@ -23040,6 +23141,120 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23040
23141
|
linesReturned: ringBuffer.length
|
|
23041
23142
|
};
|
|
23042
23143
|
}
|
|
23144
|
+
/**
|
|
23145
|
+
* Split a YAML scalar value from any trailing inline comment.
|
|
23146
|
+
* Understands single-quoted and double-quoted YAML strings so it won't
|
|
23147
|
+
* mistake a `#` inside a quoted value for a comment delimiter.
|
|
23148
|
+
*/
|
|
23149
|
+
splitYamlInlineComment(value) {
|
|
23150
|
+
let inSingle = false;
|
|
23151
|
+
let inDouble = false;
|
|
23152
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
23153
|
+
const char = value[i];
|
|
23154
|
+
if (inSingle) {
|
|
23155
|
+
if (char === "'") {
|
|
23156
|
+
if (value[i + 1] === "'") {
|
|
23157
|
+
i += 1;
|
|
23158
|
+
} else {
|
|
23159
|
+
inSingle = false;
|
|
23160
|
+
}
|
|
23161
|
+
}
|
|
23162
|
+
continue;
|
|
23163
|
+
}
|
|
23164
|
+
if (inDouble) {
|
|
23165
|
+
if (char === "\\") {
|
|
23166
|
+
i += 1;
|
|
23167
|
+
continue;
|
|
23168
|
+
}
|
|
23169
|
+
if (char === '"') {
|
|
23170
|
+
inDouble = false;
|
|
23171
|
+
}
|
|
23172
|
+
continue;
|
|
23173
|
+
}
|
|
23174
|
+
if (char === "'") {
|
|
23175
|
+
inSingle = true;
|
|
23176
|
+
continue;
|
|
23177
|
+
}
|
|
23178
|
+
if (char === '"') {
|
|
23179
|
+
inDouble = true;
|
|
23180
|
+
continue;
|
|
23181
|
+
}
|
|
23182
|
+
if (char === "#" && i > 0 && /\s/.test(value[i - 1])) {
|
|
23183
|
+
const valuePart = value.slice(0, i).trimEnd();
|
|
23184
|
+
return {
|
|
23185
|
+
valuePart,
|
|
23186
|
+
commentPart: value.slice(valuePart.length)
|
|
23187
|
+
};
|
|
23188
|
+
}
|
|
23189
|
+
}
|
|
23190
|
+
return { valuePart: value, commentPart: "" };
|
|
23191
|
+
}
|
|
23192
|
+
/** Returns true when `value` looks like a YAML block scalar indicator (`>`, `|`, `>-`, `|-`, etc.) */
|
|
23193
|
+
isYamlBlockScalarIndicator(value) {
|
|
23194
|
+
return /^[>|][+-]?[0-9]*$/.test(value) || /^[>|][0-9]*[+-]?$/.test(value);
|
|
23195
|
+
}
|
|
23196
|
+
/** Escape a plain string for use inside a YAML double-quoted scalar. */
|
|
23197
|
+
escapeForYamlDoubleQuoted(value) {
|
|
23198
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
23199
|
+
}
|
|
23200
|
+
/**
|
|
23201
|
+
* Normalise a raw YAML title value to a double-quoted scalar.
|
|
23202
|
+
* Handles: empty, already double-quoted, single-quoted (unescaping `''`),
|
|
23203
|
+
* block-scalar indicators, and plain unquoted values.
|
|
23204
|
+
*/
|
|
23205
|
+
normalizeFrontmatterTitleValue(value) {
|
|
23206
|
+
const trimmed = value.trim();
|
|
23207
|
+
if (trimmed === "") {
|
|
23208
|
+
return '""';
|
|
23209
|
+
}
|
|
23210
|
+
if (this.isYamlBlockScalarIndicator(trimmed)) {
|
|
23211
|
+
return value;
|
|
23212
|
+
}
|
|
23213
|
+
if (/^"(?:[^"\\]|\\[\s\S])*"$/.test(trimmed)) {
|
|
23214
|
+
return trimmed;
|
|
23215
|
+
}
|
|
23216
|
+
if (/^'(?:[^']|'')*'$/.test(trimmed)) {
|
|
23217
|
+
const inner = trimmed.slice(1, -1).replace(/''/g, "'");
|
|
23218
|
+
return `"${this.escapeForYamlDoubleQuoted(inner)}"`;
|
|
23219
|
+
}
|
|
23220
|
+
return `"${this.escapeForYamlDoubleQuoted(trimmed)}"`;
|
|
23221
|
+
}
|
|
23222
|
+
/**
|
|
23223
|
+
* Ensure every `title:` line in YAML frontmatter is double-quoted.
|
|
23224
|
+
* Handles already-quoted (single or double), multi-word, and special-char values.
|
|
23225
|
+
* Preserves inline comments and handles both LF and CRLF line endings.
|
|
23226
|
+
*/
|
|
23227
|
+
quoteFrontmatterTitles(content) {
|
|
23228
|
+
const crlfOpen = content.startsWith("---\r\n");
|
|
23229
|
+
const lfOpen = content.startsWith("---\n");
|
|
23230
|
+
if (!crlfOpen && !lfOpen) {
|
|
23231
|
+
return content;
|
|
23232
|
+
}
|
|
23233
|
+
const eol = crlfOpen ? "\r\n" : "\n";
|
|
23234
|
+
const openEnd = `---${eol}`.length;
|
|
23235
|
+
const closeMarker = `${eol}---`;
|
|
23236
|
+
const closeIdx = content.indexOf(closeMarker, openEnd);
|
|
23237
|
+
if (closeIdx === -1) {
|
|
23238
|
+
return content;
|
|
23239
|
+
}
|
|
23240
|
+
const frontmatter = content.slice(openEnd, closeIdx);
|
|
23241
|
+
const rest = content.slice(closeIdx);
|
|
23242
|
+
const lines = frontmatter.split(eol);
|
|
23243
|
+
const fixedLines = lines.map((line) => {
|
|
23244
|
+
if (!line.startsWith("title:")) {
|
|
23245
|
+
return line;
|
|
23246
|
+
}
|
|
23247
|
+
const colonIdx = line.indexOf(":");
|
|
23248
|
+
const afterColon = line.slice(colonIdx + 1);
|
|
23249
|
+
const leadingSpace = afterColon.length - afterColon.trimStart().length;
|
|
23250
|
+
const raw = afterColon.trimStart();
|
|
23251
|
+
const { valuePart, commentPart } = this.splitYamlInlineComment(raw);
|
|
23252
|
+
const normalized = this.normalizeFrontmatterTitleValue(valuePart);
|
|
23253
|
+
const prefix = `title:${" ".repeat(Math.max(1, leadingSpace))}`;
|
|
23254
|
+
return `${prefix}${normalized}${commentPart}`;
|
|
23255
|
+
});
|
|
23256
|
+
return `---${eol}${fixedLines.join(eol)}${rest}`;
|
|
23257
|
+
}
|
|
23043
23258
|
async readBeanFile(relativePath) {
|
|
23044
23259
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23045
23260
|
const content = await readFile(absolutePath, "utf8");
|
|
@@ -23047,20 +23262,22 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23047
23262
|
}
|
|
23048
23263
|
async editBeanFile(relativePath, content) {
|
|
23049
23264
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23265
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23050
23266
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
23051
|
-
await writeFile(absolutePath,
|
|
23052
|
-
return { path: absolutePath, bytes: Buffer.byteLength(
|
|
23267
|
+
await writeFile(absolutePath, fixed, "utf8");
|
|
23268
|
+
return { path: absolutePath, bytes: Buffer.byteLength(fixed, "utf8") };
|
|
23053
23269
|
}
|
|
23054
23270
|
async createBeanFile(relativePath, content, options) {
|
|
23055
23271
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23272
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23056
23273
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
23057
|
-
await writeFile(absolutePath,
|
|
23274
|
+
await writeFile(absolutePath, fixed, {
|
|
23058
23275
|
encoding: "utf8",
|
|
23059
23276
|
flag: options?.overwrite ? "w" : "wx"
|
|
23060
23277
|
});
|
|
23061
23278
|
return {
|
|
23062
23279
|
path: absolutePath,
|
|
23063
|
-
bytes: Buffer.byteLength(
|
|
23280
|
+
bytes: Buffer.byteLength(fixed, "utf8"),
|
|
23064
23281
|
created: true
|
|
23065
23282
|
};
|
|
23066
23283
|
}
|
|
@@ -23073,7 +23290,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23073
23290
|
}
|
|
23074
23291
|
});
|
|
23075
23292
|
|
|
23076
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23293
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
23077
23294
|
function deserializeMessage(line) {
|
|
23078
23295
|
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
23079
23296
|
}
|
|
@@ -23082,7 +23299,7 @@ function serializeMessage(message) {
|
|
|
23082
23299
|
}
|
|
23083
23300
|
var ReadBuffer;
|
|
23084
23301
|
var init_stdio = __esm({
|
|
23085
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23302
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
23086
23303
|
"use strict";
|
|
23087
23304
|
init_types();
|
|
23088
23305
|
ReadBuffer = class {
|
|
@@ -23108,7 +23325,7 @@ var init_stdio = __esm({
|
|
|
23108
23325
|
}
|
|
23109
23326
|
});
|
|
23110
23327
|
|
|
23111
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23328
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
23112
23329
|
var stdio_exports = {};
|
|
23113
23330
|
__export(stdio_exports, {
|
|
23114
23331
|
StdioServerTransport: () => StdioServerTransport
|
|
@@ -23116,7 +23333,7 @@ __export(stdio_exports, {
|
|
|
23116
23333
|
import process3 from "process";
|
|
23117
23334
|
var StdioServerTransport;
|
|
23118
23335
|
var init_stdio2 = __esm({
|
|
23119
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23336
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js"() {
|
|
23120
23337
|
"use strict";
|
|
23121
23338
|
init_stdio();
|
|
23122
23339
|
StdioServerTransport = class {
|
|
@@ -27123,7 +27340,7 @@ init_core2();
|
|
|
27123
27340
|
// node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/mini/coerce.js
|
|
27124
27341
|
init_core2();
|
|
27125
27342
|
|
|
27126
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27343
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
27127
27344
|
function isZ4Schema(s) {
|
|
27128
27345
|
const schema = s;
|
|
27129
27346
|
return !!schema._zod;
|
|
@@ -27267,10 +27484,10 @@ function getLiteralValue(schema) {
|
|
|
27267
27484
|
return void 0;
|
|
27268
27485
|
}
|
|
27269
27486
|
|
|
27270
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27487
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
27271
27488
|
init_types();
|
|
27272
27489
|
|
|
27273
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27490
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
27274
27491
|
function isTerminal(status) {
|
|
27275
27492
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
27276
27493
|
}
|
|
@@ -28559,7 +28776,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
28559
28776
|
return combined;
|
|
28560
28777
|
};
|
|
28561
28778
|
|
|
28562
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28779
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
28563
28780
|
function mapMiniTarget(t) {
|
|
28564
28781
|
if (!t)
|
|
28565
28782
|
return "draft-7";
|
|
@@ -28601,7 +28818,7 @@ function parseWithCompat(schema, data) {
|
|
|
28601
28818
|
return result.data;
|
|
28602
28819
|
}
|
|
28603
28820
|
|
|
28604
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28821
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
28605
28822
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
28606
28823
|
var Protocol = class {
|
|
28607
28824
|
constructor(_options) {
|
|
@@ -28813,6 +29030,10 @@ var Protocol = class {
|
|
|
28813
29030
|
this._progressHandlers.clear();
|
|
28814
29031
|
this._taskProgressTokens.clear();
|
|
28815
29032
|
this._pendingDebouncedNotifications.clear();
|
|
29033
|
+
for (const info of this._timeoutInfo.values()) {
|
|
29034
|
+
clearTimeout(info.timeoutId);
|
|
29035
|
+
}
|
|
29036
|
+
this._timeoutInfo.clear();
|
|
28816
29037
|
for (const controller of this._requestHandlerAbortControllers.values()) {
|
|
28817
29038
|
controller.abort();
|
|
28818
29039
|
}
|
|
@@ -28943,7 +29164,9 @@ var Protocol = class {
|
|
|
28943
29164
|
await capturedTransport?.send(errorResponse);
|
|
28944
29165
|
}
|
|
28945
29166
|
}).catch((error48) => this._onerror(new Error(`Failed to send response: ${error48}`))).finally(() => {
|
|
28946
|
-
this._requestHandlerAbortControllers.
|
|
29167
|
+
if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
|
|
29168
|
+
this._requestHandlerAbortControllers.delete(request.id);
|
|
29169
|
+
}
|
|
28947
29170
|
});
|
|
28948
29171
|
}
|
|
28949
29172
|
_onprogress(notification) {
|
|
@@ -29549,10 +29772,10 @@ function mergeCapabilities(base, additional) {
|
|
|
29549
29772
|
return result;
|
|
29550
29773
|
}
|
|
29551
29774
|
|
|
29552
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29775
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29553
29776
|
init_types();
|
|
29554
29777
|
|
|
29555
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29778
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
29556
29779
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
29557
29780
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
29558
29781
|
function createDefaultAjvInstance() {
|
|
@@ -29620,7 +29843,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
29620
29843
|
}
|
|
29621
29844
|
};
|
|
29622
29845
|
|
|
29623
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29846
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
29624
29847
|
init_types();
|
|
29625
29848
|
var ExperimentalServerTasks = class {
|
|
29626
29849
|
constructor(_server) {
|
|
@@ -29834,7 +30057,7 @@ var ExperimentalServerTasks = class {
|
|
|
29834
30057
|
}
|
|
29835
30058
|
};
|
|
29836
30059
|
|
|
29837
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30060
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
29838
30061
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
29839
30062
|
if (!requests) {
|
|
29840
30063
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -29869,7 +30092,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
29869
30092
|
}
|
|
29870
30093
|
}
|
|
29871
30094
|
|
|
29872
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30095
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29873
30096
|
var Server = class extends Protocol {
|
|
29874
30097
|
/**
|
|
29875
30098
|
* Initializes this server with the given name and version information.
|
|
@@ -30249,10 +30472,10 @@ var Server = class extends Protocol {
|
|
|
30249
30472
|
}
|
|
30250
30473
|
};
|
|
30251
30474
|
|
|
30252
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30475
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30253
30476
|
init_types();
|
|
30254
30477
|
|
|
30255
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30478
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
30256
30479
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
30257
30480
|
function isCompletable(schema) {
|
|
30258
30481
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -30266,7 +30489,7 @@ var McpZodTypeKind;
|
|
|
30266
30489
|
McpZodTypeKind2["Completable"] = "McpCompletable";
|
|
30267
30490
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
30268
30491
|
|
|
30269
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30492
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
30270
30493
|
var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
|
|
30271
30494
|
function validateToolName(name) {
|
|
30272
30495
|
const warnings = [];
|
|
@@ -30324,7 +30547,7 @@ function validateAndWarnToolName(name) {
|
|
|
30324
30547
|
return result.isValid;
|
|
30325
30548
|
}
|
|
30326
30549
|
|
|
30327
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30550
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
30328
30551
|
var ExperimentalMcpServerTasks = class {
|
|
30329
30552
|
constructor(_mcpServer) {
|
|
30330
30553
|
this._mcpServer = _mcpServer;
|
|
@@ -30343,7 +30566,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
30343
30566
|
init_external();
|
|
30344
30567
|
init_external();
|
|
30345
30568
|
|
|
30346
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30569
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30347
30570
|
var McpServer = class {
|
|
30348
30571
|
constructor(serverInfo, options) {
|
|
30349
30572
|
this._registeredResources = {};
|
|
@@ -30967,6 +31190,9 @@ var McpServer = class {
|
|
|
30967
31190
|
annotations = rest.shift();
|
|
30968
31191
|
}
|
|
30969
31192
|
} else if (typeof firstArg === "object" && firstArg !== null) {
|
|
31193
|
+
if (Object.values(firstArg).some((v) => typeof v === "object" && v !== null)) {
|
|
31194
|
+
throw new Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);
|
|
31195
|
+
}
|
|
30970
31196
|
annotations = rest.shift();
|
|
30971
31197
|
}
|
|
30972
31198
|
}
|
|
@@ -31085,6 +31311,9 @@ function getZodSchemaObject(schema) {
|
|
|
31085
31311
|
if (isZodRawShapeCompat(schema)) {
|
|
31086
31312
|
return objectFromShape(schema);
|
|
31087
31313
|
}
|
|
31314
|
+
if (!isZodSchemaInstance(schema)) {
|
|
31315
|
+
throw new Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");
|
|
31316
|
+
}
|
|
31088
31317
|
return schema;
|
|
31089
31318
|
}
|
|
31090
31319
|
function promptArgumentsFromSchema(schema) {
|
|
@@ -31133,6 +31362,90 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
31133
31362
|
import { execFile as execFile2 } from "child_process";
|
|
31134
31363
|
import { promisify as promisify2 } from "util";
|
|
31135
31364
|
|
|
31365
|
+
// package.json
|
|
31366
|
+
var package_default = {
|
|
31367
|
+
name: "@selfagency/beans-mcp",
|
|
31368
|
+
version: "0.5.0",
|
|
31369
|
+
private: false,
|
|
31370
|
+
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31371
|
+
author: {
|
|
31372
|
+
name: "Daniel Sieradski",
|
|
31373
|
+
email: "daniel@self.agency",
|
|
31374
|
+
url: "https://self.agency"
|
|
31375
|
+
},
|
|
31376
|
+
homepage: "https://github.com/selfagency/beans-mcp",
|
|
31377
|
+
bugs: {
|
|
31378
|
+
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31379
|
+
},
|
|
31380
|
+
repository: {
|
|
31381
|
+
type: "git",
|
|
31382
|
+
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31383
|
+
},
|
|
31384
|
+
mcpName: "io.github.selfagency/beans-mcp",
|
|
31385
|
+
keywords: [
|
|
31386
|
+
"beans",
|
|
31387
|
+
"mcp",
|
|
31388
|
+
"model-context-protocol",
|
|
31389
|
+
"issue-tracker",
|
|
31390
|
+
"ai"
|
|
31391
|
+
],
|
|
31392
|
+
license: "MIT",
|
|
31393
|
+
type: "module",
|
|
31394
|
+
exports: {
|
|
31395
|
+
".": {
|
|
31396
|
+
types: "./dist/index.d.ts",
|
|
31397
|
+
import: "./dist/index.js",
|
|
31398
|
+
require: "./dist/index.cjs"
|
|
31399
|
+
}
|
|
31400
|
+
},
|
|
31401
|
+
main: "./dist/index.cjs",
|
|
31402
|
+
module: "./dist/index.js",
|
|
31403
|
+
types: "./dist/index.d.ts",
|
|
31404
|
+
bin: {
|
|
31405
|
+
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31406
|
+
},
|
|
31407
|
+
scripts: {
|
|
31408
|
+
build: "tsup",
|
|
31409
|
+
format: "oxfmt",
|
|
31410
|
+
"lint:fix": "oxlint --fix",
|
|
31411
|
+
lint: "oxlint",
|
|
31412
|
+
postbuild: "node ./scripts/write-dist-package.js",
|
|
31413
|
+
prepare: "husky",
|
|
31414
|
+
release: "zx ./scripts/release.js",
|
|
31415
|
+
"test:coverage": "vitest run --coverage",
|
|
31416
|
+
"test:watch": "vitest",
|
|
31417
|
+
test: "vitest run",
|
|
31418
|
+
"type-check": "tsc --noEmit"
|
|
31419
|
+
},
|
|
31420
|
+
devDependencies: {
|
|
31421
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
31422
|
+
"@octokit/rest": "^22.0.1",
|
|
31423
|
+
"@types/node": "25.5.2",
|
|
31424
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
31425
|
+
"@vitest/ui": "4.1.2",
|
|
31426
|
+
husky: "^9.1.7",
|
|
31427
|
+
"lint-staged": "^16.4.0",
|
|
31428
|
+
ora: "^9.3.0",
|
|
31429
|
+
oxfmt: "^0.43.0",
|
|
31430
|
+
oxlint: "^1.58.0",
|
|
31431
|
+
"oxlint-tsgolint": "^0.20.0",
|
|
31432
|
+
tsup: "8.5.1",
|
|
31433
|
+
typescript: "6.0.2",
|
|
31434
|
+
vitest: "4.1.2",
|
|
31435
|
+
zod: "4.3.6",
|
|
31436
|
+
zx: "^8.8.5"
|
|
31437
|
+
},
|
|
31438
|
+
engines: {
|
|
31439
|
+
node: ">=18"
|
|
31440
|
+
},
|
|
31441
|
+
"lint-staged": {
|
|
31442
|
+
"src/**/*.ts": [
|
|
31443
|
+
"pnpm run lint:fix",
|
|
31444
|
+
"pnpm run format"
|
|
31445
|
+
]
|
|
31446
|
+
}
|
|
31447
|
+
};
|
|
31448
|
+
|
|
31136
31449
|
// src/internal/queryHelpers.ts
|
|
31137
31450
|
function sortBeansInternal(beans, mode) {
|
|
31138
31451
|
const sorted = [...beans];
|
|
@@ -31293,92 +31606,6 @@ var MAX_PATH_LENGTH = 1024;
|
|
|
31293
31606
|
|
|
31294
31607
|
// src/server/BeansMcpServer.ts
|
|
31295
31608
|
init_utils();
|
|
31296
|
-
|
|
31297
|
-
// package.json
|
|
31298
|
-
var package_default = {
|
|
31299
|
-
name: "@selfagency/beans-mcp",
|
|
31300
|
-
version: "0.4.2",
|
|
31301
|
-
private: false,
|
|
31302
|
-
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31303
|
-
author: {
|
|
31304
|
-
name: "Daniel Sieradski",
|
|
31305
|
-
email: "daniel@self.agency",
|
|
31306
|
-
url: "https://self.agency"
|
|
31307
|
-
},
|
|
31308
|
-
homepage: "https://github.com/hmans/beans",
|
|
31309
|
-
bugs: {
|
|
31310
|
-
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31311
|
-
},
|
|
31312
|
-
repository: {
|
|
31313
|
-
type: "git",
|
|
31314
|
-
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31315
|
-
},
|
|
31316
|
-
mcpName: "io.github.selfagency/beans-mcp",
|
|
31317
|
-
keywords: [
|
|
31318
|
-
"beans",
|
|
31319
|
-
"mcp",
|
|
31320
|
-
"model-context-protocol",
|
|
31321
|
-
"issue-tracker",
|
|
31322
|
-
"ai"
|
|
31323
|
-
],
|
|
31324
|
-
license: "MIT",
|
|
31325
|
-
type: "module",
|
|
31326
|
-
exports: {
|
|
31327
|
-
".": {
|
|
31328
|
-
types: "./dist/index.d.ts",
|
|
31329
|
-
import: "./dist/index.js",
|
|
31330
|
-
require: "./dist/index.cjs"
|
|
31331
|
-
}
|
|
31332
|
-
},
|
|
31333
|
-
main: "./dist/index.cjs",
|
|
31334
|
-
module: "./dist/index.js",
|
|
31335
|
-
types: "./dist/index.d.ts",
|
|
31336
|
-
bin: {
|
|
31337
|
-
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31338
|
-
},
|
|
31339
|
-
scripts: {
|
|
31340
|
-
build: "tsup",
|
|
31341
|
-
format: "oxfmt",
|
|
31342
|
-
"lint:fix": "oxlint --fix",
|
|
31343
|
-
lint: "oxlint",
|
|
31344
|
-
postbuild: "node ./scripts/write-dist-package.js",
|
|
31345
|
-
prepare: "husky",
|
|
31346
|
-
release: "zx ./scripts/release.js",
|
|
31347
|
-
"test:coverage": "vitest run --coverage",
|
|
31348
|
-
"test:watch": "vitest",
|
|
31349
|
-
test: "vitest run",
|
|
31350
|
-
"type-check": "tsc --noEmit"
|
|
31351
|
-
},
|
|
31352
|
-
devDependencies: {
|
|
31353
|
-
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
31354
|
-
"@octokit/rest": "^22.0.1",
|
|
31355
|
-
"@types/node": "25.5.0",
|
|
31356
|
-
"@vitest/coverage-v8": "^4.1.0",
|
|
31357
|
-
"@vitest/ui": "4.1.0",
|
|
31358
|
-
husky: "^9.1.7",
|
|
31359
|
-
"lint-staged": "^16.3.3",
|
|
31360
|
-
ora: "^9.3.0",
|
|
31361
|
-
oxfmt: "^0.40.0",
|
|
31362
|
-
oxlint: "^1.55.0",
|
|
31363
|
-
"oxlint-tsgolint": "^0.16.0",
|
|
31364
|
-
tsup: "8.5.1",
|
|
31365
|
-
typescript: "^5.9.3",
|
|
31366
|
-
vitest: "4.1.0",
|
|
31367
|
-
zod: "4.3.6",
|
|
31368
|
-
zx: "^8.8.5"
|
|
31369
|
-
},
|
|
31370
|
-
engines: {
|
|
31371
|
-
node: ">=18"
|
|
31372
|
-
},
|
|
31373
|
-
"lint-staged": {
|
|
31374
|
-
"src/**/*.ts": [
|
|
31375
|
-
"pnpm run lint:fix",
|
|
31376
|
-
"pnpm run format"
|
|
31377
|
-
]
|
|
31378
|
-
}
|
|
31379
|
-
};
|
|
31380
|
-
|
|
31381
|
-
// src/server/BeansMcpServer.ts
|
|
31382
31609
|
var execFileAsync2 = promisify2(execFile2);
|
|
31383
31610
|
var PACKAGE_VERSION = package_default.version ?? "0.0.0-dev";
|
|
31384
31611
|
function getSafeCliEnv(env) {
|
|
@@ -31450,7 +31677,12 @@ function viewHandler(backend) {
|
|
|
31450
31677
|
const byId = new Map(beans.map((b) => [b.id, b]));
|
|
31451
31678
|
const found = ids.map((id) => byId.get(id)).filter(Boolean);
|
|
31452
31679
|
const missingBeanIds = ids.filter((id) => !byId.has(id));
|
|
31453
|
-
return makeTextAndStructured({
|
|
31680
|
+
return makeTextAndStructured({
|
|
31681
|
+
beans: found,
|
|
31682
|
+
missingBeanIds,
|
|
31683
|
+
count: found.length,
|
|
31684
|
+
requestedCount: ids.length
|
|
31685
|
+
});
|
|
31454
31686
|
};
|
|
31455
31687
|
}
|
|
31456
31688
|
async function checkVersionCompatibility(cliPath, workspaceRoot, detector) {
|
|
@@ -31542,7 +31774,11 @@ function deleteHandler(backend) {
|
|
|
31542
31774
|
await backend.delete(id);
|
|
31543
31775
|
results.push({ beanId: id, deleted: true });
|
|
31544
31776
|
} catch (error48) {
|
|
31545
|
-
results.push({
|
|
31777
|
+
results.push({
|
|
31778
|
+
beanId: id,
|
|
31779
|
+
deleted: false,
|
|
31780
|
+
error: error48.message
|
|
31781
|
+
});
|
|
31546
31782
|
}
|
|
31547
31783
|
}
|
|
31548
31784
|
return makeTextAndStructured({
|
|
@@ -31553,6 +31789,28 @@ function deleteHandler(backend) {
|
|
|
31553
31789
|
});
|
|
31554
31790
|
};
|
|
31555
31791
|
}
|
|
31792
|
+
function bulkCreateHandler(backend) {
|
|
31793
|
+
return async (input) => {
|
|
31794
|
+
const results = await backend.bulkCreate(input.beans, input.parent);
|
|
31795
|
+
return makeTextAndStructured({
|
|
31796
|
+
results,
|
|
31797
|
+
requestedCount: input.beans.length,
|
|
31798
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31799
|
+
failedCount: results.filter((r) => r.error).length
|
|
31800
|
+
});
|
|
31801
|
+
};
|
|
31802
|
+
}
|
|
31803
|
+
function bulkUpdateHandler(backend) {
|
|
31804
|
+
return async (input) => {
|
|
31805
|
+
const results = await backend.bulkUpdate(input.beans, input.parent);
|
|
31806
|
+
return makeTextAndStructured({
|
|
31807
|
+
results,
|
|
31808
|
+
requestedCount: input.beans.length,
|
|
31809
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31810
|
+
failedCount: results.filter((r) => r.error).length
|
|
31811
|
+
});
|
|
31812
|
+
};
|
|
31813
|
+
}
|
|
31556
31814
|
function queryHandler(backend) {
|
|
31557
31815
|
return async (opts) => handleQueryOperation(backend, opts);
|
|
31558
31816
|
}
|
|
@@ -31636,7 +31894,8 @@ function registerTools(server, backend) {
|
|
|
31636
31894
|
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
31637
31895
|
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31638
31896
|
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31639
|
-
|
|
31897
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
31898
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
31640
31899
|
parent: external_exports3.string().max(MAX_ID_LENGTH).optional()
|
|
31641
31900
|
}),
|
|
31642
31901
|
annotations: {
|
|
@@ -31750,6 +32009,68 @@ function registerTools(server, backend) {
|
|
|
31750
32009
|
},
|
|
31751
32010
|
deleteHandler(backend)
|
|
31752
32011
|
);
|
|
32012
|
+
const beanCreateItemSchema = external_exports3.object({
|
|
32013
|
+
title: external_exports3.string().min(1).max(MAX_TITLE_LENGTH),
|
|
32014
|
+
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
32015
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32016
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32017
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
32018
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
32019
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item")
|
|
32020
|
+
});
|
|
32021
|
+
server.registerTool(
|
|
32022
|
+
"beans_bulk_create",
|
|
32023
|
+
{
|
|
32024
|
+
title: "Bulk Create Beans",
|
|
32025
|
+
description: "Create multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32026
|
+
inputSchema: external_exports3.object({
|
|
32027
|
+
beans: external_exports3.array(beanCreateItemSchema).min(1),
|
|
32028
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32029
|
+
}),
|
|
32030
|
+
annotations: {
|
|
32031
|
+
readOnlyHint: false,
|
|
32032
|
+
destructiveHint: false,
|
|
32033
|
+
idempotentHint: false,
|
|
32034
|
+
openWorldHint: false
|
|
32035
|
+
}
|
|
32036
|
+
},
|
|
32037
|
+
bulkCreateHandler(backend)
|
|
32038
|
+
);
|
|
32039
|
+
const beanUpdateItemSchema = external_exports3.object({
|
|
32040
|
+
beanId: external_exports3.string().min(1).max(MAX_ID_LENGTH),
|
|
32041
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32042
|
+
type: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32043
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32044
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item"),
|
|
32045
|
+
clearParent: external_exports3.boolean().optional(),
|
|
32046
|
+
blocking: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32047
|
+
blockedBy: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32048
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32049
|
+
bodyAppend: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32050
|
+
bodyReplace: external_exports3.array(external_exports3.object({ old: external_exports3.string().max(MAX_DESCRIPTION_LENGTH), new: external_exports3.string().max(MAX_DESCRIPTION_LENGTH) })).optional(),
|
|
32051
|
+
ifMatch: external_exports3.string().max(MAX_METADATA_LENGTH).optional()
|
|
32052
|
+
}).refine(
|
|
32053
|
+
(input) => !(input.body !== void 0 && (input.bodyAppend !== void 0 || input.bodyReplace !== void 0)),
|
|
32054
|
+
{ message: "body cannot be combined with bodyAppend/bodyReplace" }
|
|
32055
|
+
);
|
|
32056
|
+
server.registerTool(
|
|
32057
|
+
"beans_bulk_update",
|
|
32058
|
+
{
|
|
32059
|
+
title: "Bulk Update Beans",
|
|
32060
|
+
description: "Update multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32061
|
+
inputSchema: external_exports3.object({
|
|
32062
|
+
beans: external_exports3.array(beanUpdateItemSchema).min(1),
|
|
32063
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32064
|
+
}),
|
|
32065
|
+
annotations: {
|
|
32066
|
+
readOnlyHint: false,
|
|
32067
|
+
destructiveHint: false,
|
|
32068
|
+
idempotentHint: false,
|
|
32069
|
+
openWorldHint: false
|
|
32070
|
+
}
|
|
32071
|
+
},
|
|
32072
|
+
bulkUpdateHandler(backend)
|
|
32073
|
+
);
|
|
31753
32074
|
server.registerTool(
|
|
31754
32075
|
"beans_query",
|
|
31755
32076
|
{
|
|
@@ -31835,6 +32156,12 @@ var MutableBackend = class {
|
|
|
31835
32156
|
delete(id) {
|
|
31836
32157
|
return this.inner.delete(id);
|
|
31837
32158
|
}
|
|
32159
|
+
bulkCreate(beans, defaultParent) {
|
|
32160
|
+
return this.inner.bulkCreate(beans, defaultParent);
|
|
32161
|
+
}
|
|
32162
|
+
bulkUpdate(beans, defaultParent) {
|
|
32163
|
+
return this.inner.bulkUpdate(beans, defaultParent);
|
|
32164
|
+
}
|
|
31838
32165
|
openConfig() {
|
|
31839
32166
|
return this.inner.openConfig();
|
|
31840
32167
|
}
|