@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.cjs
CHANGED
|
@@ -14433,7 +14433,7 @@ var init_v4 = __esm({
|
|
|
14433
14433
|
}
|
|
14434
14434
|
});
|
|
14435
14435
|
|
|
14436
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14436
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
14437
14437
|
function assertCompleteRequestPrompt(request) {
|
|
14438
14438
|
if (request.params.ref.type !== "ref/prompt") {
|
|
14439
14439
|
throw new TypeError(`Expected CompleteRequestPrompt, but got ${request.params.ref.type}`);
|
|
@@ -14448,7 +14448,7 @@ function assertCompleteRequestResourceTemplate(request) {
|
|
|
14448
14448
|
}
|
|
14449
14449
|
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;
|
|
14450
14450
|
var init_types = __esm({
|
|
14451
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
14451
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js"() {
|
|
14452
14452
|
"use strict";
|
|
14453
14453
|
init_v4();
|
|
14454
14454
|
LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
@@ -14460,10 +14460,9 @@ var init_types = __esm({
|
|
|
14460
14460
|
CursorSchema = string2();
|
|
14461
14461
|
TaskCreationParamsSchema = looseObject({
|
|
14462
14462
|
/**
|
|
14463
|
-
*
|
|
14464
|
-
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
14463
|
+
* Requested duration in milliseconds to retain task from creation.
|
|
14465
14464
|
*/
|
|
14466
|
-
ttl:
|
|
14465
|
+
ttl: number2().optional(),
|
|
14467
14466
|
/**
|
|
14468
14467
|
* Time in milliseconds to wait between task status requests.
|
|
14469
14468
|
*/
|
|
@@ -14762,7 +14761,11 @@ var init_types = __esm({
|
|
|
14762
14761
|
/**
|
|
14763
14762
|
* Present if the client supports task creation.
|
|
14764
14763
|
*/
|
|
14765
|
-
tasks: ClientTasksCapabilitySchema.optional()
|
|
14764
|
+
tasks: ClientTasksCapabilitySchema.optional(),
|
|
14765
|
+
/**
|
|
14766
|
+
* Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14767
|
+
*/
|
|
14768
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14766
14769
|
});
|
|
14767
14770
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
14768
14771
|
/**
|
|
@@ -14823,7 +14826,11 @@ var init_types = __esm({
|
|
|
14823
14826
|
/**
|
|
14824
14827
|
* Present if the server supports task creation.
|
|
14825
14828
|
*/
|
|
14826
|
-
tasks: ServerTasksCapabilitySchema.optional()
|
|
14829
|
+
tasks: ServerTasksCapabilitySchema.optional(),
|
|
14830
|
+
/**
|
|
14831
|
+
* Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
14832
|
+
*/
|
|
14833
|
+
extensions: record(string2(), AssertObjectSchema).optional()
|
|
14827
14834
|
});
|
|
14828
14835
|
InitializeResultSchema = ResultSchema.extend({
|
|
14829
14836
|
/**
|
|
@@ -15015,6 +15022,12 @@ var init_types = __esm({
|
|
|
15015
15022
|
* The MIME type of this resource, if known.
|
|
15016
15023
|
*/
|
|
15017
15024
|
mimeType: optional(string2()),
|
|
15025
|
+
/**
|
|
15026
|
+
* The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
|
|
15027
|
+
*
|
|
15028
|
+
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
15029
|
+
*/
|
|
15030
|
+
size: optional(number2()),
|
|
15018
15031
|
/**
|
|
15019
15032
|
* Optional annotations for the client.
|
|
15020
15033
|
*/
|
|
@@ -22747,7 +22760,7 @@ var init_utils = __esm({
|
|
|
22747
22760
|
});
|
|
22748
22761
|
|
|
22749
22762
|
// src/internal/graphql.ts
|
|
22750
|
-
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION;
|
|
22763
|
+
var LIST_BEANS_QUERY, CREATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION, UPDATE_BEAN_MUTATION_WITH_IF_MATCH, DELETE_BEAN_MUTATION, LIST_BEANS_TIMESTAMPS_QUERY;
|
|
22751
22764
|
var init_graphql = __esm({
|
|
22752
22765
|
"src/internal/graphql.ts"() {
|
|
22753
22766
|
"use strict";
|
|
@@ -22775,6 +22788,11 @@ var init_graphql = __esm({
|
|
|
22775
22788
|
mutation($id: ID!) {
|
|
22776
22789
|
deleteBean(id: $id)
|
|
22777
22790
|
}
|
|
22791
|
+
`;
|
|
22792
|
+
LIST_BEANS_TIMESTAMPS_QUERY = `
|
|
22793
|
+
query {
|
|
22794
|
+
beans { id updatedAt }
|
|
22795
|
+
}
|
|
22778
22796
|
`;
|
|
22779
22797
|
}
|
|
22780
22798
|
});
|
|
@@ -22797,12 +22815,26 @@ var init_backend = __esm({
|
|
|
22797
22815
|
init_graphql();
|
|
22798
22816
|
init_utils();
|
|
22799
22817
|
execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
22800
|
-
BeansCliBackend = class {
|
|
22818
|
+
BeansCliBackend = class _BeansCliBackend {
|
|
22801
22819
|
constructor(workspaceRoot, cliPath, logDir) {
|
|
22802
22820
|
this.workspaceRoot = workspaceRoot;
|
|
22803
22821
|
this.cliPath = cliPath;
|
|
22804
22822
|
this.logDir = logDir;
|
|
22805
22823
|
}
|
|
22824
|
+
// ---------------------------------------------------------------------------
|
|
22825
|
+
// Cache
|
|
22826
|
+
// ---------------------------------------------------------------------------
|
|
22827
|
+
/** Full unfiltered records keyed by bean ID, stored under the fixed cache key `'all'`. */
|
|
22828
|
+
_cache = /* @__PURE__ */ new Map();
|
|
22829
|
+
/** Last time the unfiltered cache entry `'all'` was fetched (ms). */
|
|
22830
|
+
_cacheTime = /* @__PURE__ */ new Map();
|
|
22831
|
+
/** Short-circuit TTL: skip even the timestamp check within this window (ms). */
|
|
22832
|
+
static BURST_TTL_MS = 5e3;
|
|
22833
|
+
/** Invalidate the unfiltered list cache so the next call does a full fetch. */
|
|
22834
|
+
invalidateCache() {
|
|
22835
|
+
this._cache.delete("all");
|
|
22836
|
+
this._cacheTime.delete("all");
|
|
22837
|
+
}
|
|
22806
22838
|
/**
|
|
22807
22839
|
* Returns a safe environment for executing the Beans CLI,
|
|
22808
22840
|
* whitelisting only necessary variables.
|
|
@@ -22826,7 +22858,7 @@ var init_backend = __esm({
|
|
|
22826
22858
|
return (0, import_node_path2.resolve)(this.workspaceRoot, ".beans");
|
|
22827
22859
|
}
|
|
22828
22860
|
resolveBeanFilePath(relativePath) {
|
|
22829
|
-
const cleaned = relativePath.trim().replace(/^\/+/, "");
|
|
22861
|
+
const cleaned = relativePath.trim().replace(/^\/+/, "").replace(/^\.beans(?:[\\/]|$)/, "");
|
|
22830
22862
|
if (!cleaned) {
|
|
22831
22863
|
throw new Error("Path is required");
|
|
22832
22864
|
}
|
|
@@ -22884,10 +22916,48 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22884
22916
|
if (options?.search) {
|
|
22885
22917
|
filter.search = options.search;
|
|
22886
22918
|
}
|
|
22919
|
+
const isCacheable = !filter.status && !filter.type && !filter.search;
|
|
22920
|
+
const cacheKey = "all";
|
|
22921
|
+
if (isCacheable) {
|
|
22922
|
+
const lastFetch = this._cacheTime.get(cacheKey) ?? 0;
|
|
22923
|
+
const cached2 = this._cache.get(cacheKey);
|
|
22924
|
+
const age = Date.now() - lastFetch;
|
|
22925
|
+
if (cached2 && age < _BeansCliBackend.BURST_TTL_MS) {
|
|
22926
|
+
return Array.from(cached2.values());
|
|
22927
|
+
}
|
|
22928
|
+
if (cached2) {
|
|
22929
|
+
try {
|
|
22930
|
+
const { data: tsData } = await this.executeGraphQL(
|
|
22931
|
+
LIST_BEANS_TIMESTAMPS_QUERY
|
|
22932
|
+
);
|
|
22933
|
+
const timestamps = tsData.beans;
|
|
22934
|
+
let dirty = timestamps.length !== cached2.size;
|
|
22935
|
+
if (!dirty) {
|
|
22936
|
+
for (const { id, updatedAt } of timestamps) {
|
|
22937
|
+
const existing = cached2.get(id);
|
|
22938
|
+
if (!existing || existing.updatedAt !== updatedAt) {
|
|
22939
|
+
dirty = true;
|
|
22940
|
+
break;
|
|
22941
|
+
}
|
|
22942
|
+
}
|
|
22943
|
+
}
|
|
22944
|
+
if (!dirty) {
|
|
22945
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22946
|
+
return Array.from(cached2.values());
|
|
22947
|
+
}
|
|
22948
|
+
} catch {
|
|
22949
|
+
}
|
|
22950
|
+
}
|
|
22951
|
+
}
|
|
22887
22952
|
const { data, errors } = await this.executeGraphQL(LIST_BEANS_QUERY, { filter });
|
|
22888
22953
|
if (errors && errors.length > 0) {
|
|
22889
22954
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22890
22955
|
}
|
|
22956
|
+
if (isCacheable) {
|
|
22957
|
+
const byId = new Map(data.beans.map((b) => [b.id, b]));
|
|
22958
|
+
this._cache.set(cacheKey, byId);
|
|
22959
|
+
this._cacheTime.set(cacheKey, Date.now());
|
|
22960
|
+
}
|
|
22891
22961
|
return data.beans;
|
|
22892
22962
|
}
|
|
22893
22963
|
async create(input) {
|
|
@@ -22896,7 +22966,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22896
22966
|
type: input.type,
|
|
22897
22967
|
status: input.status,
|
|
22898
22968
|
priority: input.priority,
|
|
22899
|
-
body: input.description,
|
|
22969
|
+
body: input.body ?? input.description,
|
|
22900
22970
|
parent: input.parent
|
|
22901
22971
|
};
|
|
22902
22972
|
const { data, errors } = await this.executeGraphQL(CREATE_BEAN_MUTATION, {
|
|
@@ -22905,6 +22975,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22905
22975
|
if (errors && errors.length > 0) {
|
|
22906
22976
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22907
22977
|
}
|
|
22978
|
+
this.invalidateCache();
|
|
22908
22979
|
return data.createBean;
|
|
22909
22980
|
}
|
|
22910
22981
|
async update(beanId, updates) {
|
|
@@ -22974,6 +23045,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22974
23045
|
if (errors && errors.length > 0) {
|
|
22975
23046
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22976
23047
|
}
|
|
23048
|
+
this.invalidateCache();
|
|
22977
23049
|
return data.updateBean;
|
|
22978
23050
|
}
|
|
22979
23051
|
async delete(beanId) {
|
|
@@ -22983,8 +23055,37 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
22983
23055
|
if (errors && errors.length > 0) {
|
|
22984
23056
|
throw new Error(`GraphQL error: ${errors.map((e) => e.message).join(", ")}`);
|
|
22985
23057
|
}
|
|
23058
|
+
this.invalidateCache();
|
|
22986
23059
|
return { deleted: true, beanId };
|
|
22987
23060
|
}
|
|
23061
|
+
async bulkCreate(beans, defaultParent) {
|
|
23062
|
+
const results = [];
|
|
23063
|
+
for (const item of beans) {
|
|
23064
|
+
try {
|
|
23065
|
+
const bean = await this.create({
|
|
23066
|
+
...item,
|
|
23067
|
+
parent: item.parent ?? defaultParent
|
|
23068
|
+
});
|
|
23069
|
+
results.push({ bean });
|
|
23070
|
+
} catch (error48) {
|
|
23071
|
+
results.push({ error: error48.message });
|
|
23072
|
+
}
|
|
23073
|
+
}
|
|
23074
|
+
return results;
|
|
23075
|
+
}
|
|
23076
|
+
async bulkUpdate(beans, defaultParent) {
|
|
23077
|
+
const results = [];
|
|
23078
|
+
for (const { beanId, ...updates } of beans) {
|
|
23079
|
+
try {
|
|
23080
|
+
const resolvedParent = updates.parent ?? (updates.clearParent ? void 0 : defaultParent);
|
|
23081
|
+
const bean = await this.update(beanId, { ...updates, parent: resolvedParent });
|
|
23082
|
+
results.push({ beanId, bean });
|
|
23083
|
+
} catch (error48) {
|
|
23084
|
+
results.push({ beanId, error: error48.message });
|
|
23085
|
+
}
|
|
23086
|
+
}
|
|
23087
|
+
return results;
|
|
23088
|
+
}
|
|
22988
23089
|
async openConfig() {
|
|
22989
23090
|
const configPath = (0, import_node_path2.join)(this.workspaceRoot, ".beans.yml");
|
|
22990
23091
|
const content = await (0, import_promises.readFile)(configPath, "utf8");
|
|
@@ -23043,6 +23144,120 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23043
23144
|
linesReturned: ringBuffer.length
|
|
23044
23145
|
};
|
|
23045
23146
|
}
|
|
23147
|
+
/**
|
|
23148
|
+
* Split a YAML scalar value from any trailing inline comment.
|
|
23149
|
+
* Understands single-quoted and double-quoted YAML strings so it won't
|
|
23150
|
+
* mistake a `#` inside a quoted value for a comment delimiter.
|
|
23151
|
+
*/
|
|
23152
|
+
splitYamlInlineComment(value) {
|
|
23153
|
+
let inSingle = false;
|
|
23154
|
+
let inDouble = false;
|
|
23155
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
23156
|
+
const char = value[i];
|
|
23157
|
+
if (inSingle) {
|
|
23158
|
+
if (char === "'") {
|
|
23159
|
+
if (value[i + 1] === "'") {
|
|
23160
|
+
i += 1;
|
|
23161
|
+
} else {
|
|
23162
|
+
inSingle = false;
|
|
23163
|
+
}
|
|
23164
|
+
}
|
|
23165
|
+
continue;
|
|
23166
|
+
}
|
|
23167
|
+
if (inDouble) {
|
|
23168
|
+
if (char === "\\") {
|
|
23169
|
+
i += 1;
|
|
23170
|
+
continue;
|
|
23171
|
+
}
|
|
23172
|
+
if (char === '"') {
|
|
23173
|
+
inDouble = false;
|
|
23174
|
+
}
|
|
23175
|
+
continue;
|
|
23176
|
+
}
|
|
23177
|
+
if (char === "'") {
|
|
23178
|
+
inSingle = true;
|
|
23179
|
+
continue;
|
|
23180
|
+
}
|
|
23181
|
+
if (char === '"') {
|
|
23182
|
+
inDouble = true;
|
|
23183
|
+
continue;
|
|
23184
|
+
}
|
|
23185
|
+
if (char === "#" && i > 0 && /\s/.test(value[i - 1])) {
|
|
23186
|
+
const valuePart = value.slice(0, i).trimEnd();
|
|
23187
|
+
return {
|
|
23188
|
+
valuePart,
|
|
23189
|
+
commentPart: value.slice(valuePart.length)
|
|
23190
|
+
};
|
|
23191
|
+
}
|
|
23192
|
+
}
|
|
23193
|
+
return { valuePart: value, commentPart: "" };
|
|
23194
|
+
}
|
|
23195
|
+
/** Returns true when `value` looks like a YAML block scalar indicator (`>`, `|`, `>-`, `|-`, etc.) */
|
|
23196
|
+
isYamlBlockScalarIndicator(value) {
|
|
23197
|
+
return /^[>|][+-]?[0-9]*$/.test(value) || /^[>|][0-9]*[+-]?$/.test(value);
|
|
23198
|
+
}
|
|
23199
|
+
/** Escape a plain string for use inside a YAML double-quoted scalar. */
|
|
23200
|
+
escapeForYamlDoubleQuoted(value) {
|
|
23201
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
23202
|
+
}
|
|
23203
|
+
/**
|
|
23204
|
+
* Normalise a raw YAML title value to a double-quoted scalar.
|
|
23205
|
+
* Handles: empty, already double-quoted, single-quoted (unescaping `''`),
|
|
23206
|
+
* block-scalar indicators, and plain unquoted values.
|
|
23207
|
+
*/
|
|
23208
|
+
normalizeFrontmatterTitleValue(value) {
|
|
23209
|
+
const trimmed = value.trim();
|
|
23210
|
+
if (trimmed === "") {
|
|
23211
|
+
return '""';
|
|
23212
|
+
}
|
|
23213
|
+
if (this.isYamlBlockScalarIndicator(trimmed)) {
|
|
23214
|
+
return value;
|
|
23215
|
+
}
|
|
23216
|
+
if (/^"(?:[^"\\]|\\[\s\S])*"$/.test(trimmed)) {
|
|
23217
|
+
return trimmed;
|
|
23218
|
+
}
|
|
23219
|
+
if (/^'(?:[^']|'')*'$/.test(trimmed)) {
|
|
23220
|
+
const inner = trimmed.slice(1, -1).replace(/''/g, "'");
|
|
23221
|
+
return `"${this.escapeForYamlDoubleQuoted(inner)}"`;
|
|
23222
|
+
}
|
|
23223
|
+
return `"${this.escapeForYamlDoubleQuoted(trimmed)}"`;
|
|
23224
|
+
}
|
|
23225
|
+
/**
|
|
23226
|
+
* Ensure every `title:` line in YAML frontmatter is double-quoted.
|
|
23227
|
+
* Handles already-quoted (single or double), multi-word, and special-char values.
|
|
23228
|
+
* Preserves inline comments and handles both LF and CRLF line endings.
|
|
23229
|
+
*/
|
|
23230
|
+
quoteFrontmatterTitles(content) {
|
|
23231
|
+
const crlfOpen = content.startsWith("---\r\n");
|
|
23232
|
+
const lfOpen = content.startsWith("---\n");
|
|
23233
|
+
if (!crlfOpen && !lfOpen) {
|
|
23234
|
+
return content;
|
|
23235
|
+
}
|
|
23236
|
+
const eol = crlfOpen ? "\r\n" : "\n";
|
|
23237
|
+
const openEnd = `---${eol}`.length;
|
|
23238
|
+
const closeMarker = `${eol}---`;
|
|
23239
|
+
const closeIdx = content.indexOf(closeMarker, openEnd);
|
|
23240
|
+
if (closeIdx === -1) {
|
|
23241
|
+
return content;
|
|
23242
|
+
}
|
|
23243
|
+
const frontmatter = content.slice(openEnd, closeIdx);
|
|
23244
|
+
const rest = content.slice(closeIdx);
|
|
23245
|
+
const lines = frontmatter.split(eol);
|
|
23246
|
+
const fixedLines = lines.map((line) => {
|
|
23247
|
+
if (!line.startsWith("title:")) {
|
|
23248
|
+
return line;
|
|
23249
|
+
}
|
|
23250
|
+
const colonIdx = line.indexOf(":");
|
|
23251
|
+
const afterColon = line.slice(colonIdx + 1);
|
|
23252
|
+
const leadingSpace = afterColon.length - afterColon.trimStart().length;
|
|
23253
|
+
const raw = afterColon.trimStart();
|
|
23254
|
+
const { valuePart, commentPart } = this.splitYamlInlineComment(raw);
|
|
23255
|
+
const normalized = this.normalizeFrontmatterTitleValue(valuePart);
|
|
23256
|
+
const prefix = `title:${" ".repeat(Math.max(1, leadingSpace))}`;
|
|
23257
|
+
return `${prefix}${normalized}${commentPart}`;
|
|
23258
|
+
});
|
|
23259
|
+
return `---${eol}${fixedLines.join(eol)}${rest}`;
|
|
23260
|
+
}
|
|
23046
23261
|
async readBeanFile(relativePath) {
|
|
23047
23262
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23048
23263
|
const content = await (0, import_promises.readFile)(absolutePath, "utf8");
|
|
@@ -23050,20 +23265,22 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23050
23265
|
}
|
|
23051
23266
|
async editBeanFile(relativePath, content) {
|
|
23052
23267
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23268
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23053
23269
|
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(absolutePath), { recursive: true });
|
|
23054
|
-
await (0, import_promises.writeFile)(absolutePath,
|
|
23055
|
-
return { path: absolutePath, bytes: Buffer.byteLength(
|
|
23270
|
+
await (0, import_promises.writeFile)(absolutePath, fixed, "utf8");
|
|
23271
|
+
return { path: absolutePath, bytes: Buffer.byteLength(fixed, "utf8") };
|
|
23056
23272
|
}
|
|
23057
23273
|
async createBeanFile(relativePath, content, options) {
|
|
23058
23274
|
const absolutePath = this.resolveBeanFilePath(relativePath);
|
|
23275
|
+
const fixed = this.quoteFrontmatterTitles(content);
|
|
23059
23276
|
await (0, import_promises.mkdir)((0, import_node_path2.dirname)(absolutePath), { recursive: true });
|
|
23060
|
-
await (0, import_promises.writeFile)(absolutePath,
|
|
23277
|
+
await (0, import_promises.writeFile)(absolutePath, fixed, {
|
|
23061
23278
|
encoding: "utf8",
|
|
23062
23279
|
flag: options?.overwrite ? "w" : "wx"
|
|
23063
23280
|
});
|
|
23064
23281
|
return {
|
|
23065
23282
|
path: absolutePath,
|
|
23066
|
-
bytes: Buffer.byteLength(
|
|
23283
|
+
bytes: Buffer.byteLength(fixed, "utf8"),
|
|
23067
23284
|
created: true
|
|
23068
23285
|
};
|
|
23069
23286
|
}
|
|
@@ -23076,7 +23293,7 @@ Output: ${stdout.slice(0, 1e3)}`
|
|
|
23076
23293
|
}
|
|
23077
23294
|
});
|
|
23078
23295
|
|
|
23079
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23296
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
23080
23297
|
function deserializeMessage(line) {
|
|
23081
23298
|
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
23082
23299
|
}
|
|
@@ -23085,7 +23302,7 @@ function serializeMessage(message) {
|
|
|
23085
23302
|
}
|
|
23086
23303
|
var ReadBuffer;
|
|
23087
23304
|
var init_stdio = __esm({
|
|
23088
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23305
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
23089
23306
|
"use strict";
|
|
23090
23307
|
init_types();
|
|
23091
23308
|
ReadBuffer = class {
|
|
@@ -23111,14 +23328,14 @@ var init_stdio = __esm({
|
|
|
23111
23328
|
}
|
|
23112
23329
|
});
|
|
23113
23330
|
|
|
23114
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23331
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
23115
23332
|
var stdio_exports = {};
|
|
23116
23333
|
__export(stdio_exports, {
|
|
23117
23334
|
StdioServerTransport: () => StdioServerTransport
|
|
23118
23335
|
});
|
|
23119
23336
|
var import_node_process, StdioServerTransport;
|
|
23120
23337
|
var init_stdio2 = __esm({
|
|
23121
|
-
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
23338
|
+
"node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js"() {
|
|
23122
23339
|
"use strict";
|
|
23123
23340
|
import_node_process = __toESM(require("process"), 1);
|
|
23124
23341
|
init_stdio();
|
|
@@ -27143,7 +27360,7 @@ init_core2();
|
|
|
27143
27360
|
// node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/mini/coerce.js
|
|
27144
27361
|
init_core2();
|
|
27145
27362
|
|
|
27146
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27363
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
27147
27364
|
function isZ4Schema(s) {
|
|
27148
27365
|
const schema = s;
|
|
27149
27366
|
return !!schema._zod;
|
|
@@ -27287,10 +27504,10 @@ function getLiteralValue(schema) {
|
|
|
27287
27504
|
return void 0;
|
|
27288
27505
|
}
|
|
27289
27506
|
|
|
27290
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27507
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
27291
27508
|
init_types();
|
|
27292
27509
|
|
|
27293
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
27510
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
27294
27511
|
function isTerminal(status) {
|
|
27295
27512
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
27296
27513
|
}
|
|
@@ -28579,7 +28796,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
28579
28796
|
return combined;
|
|
28580
28797
|
};
|
|
28581
28798
|
|
|
28582
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28799
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
28583
28800
|
function mapMiniTarget(t) {
|
|
28584
28801
|
if (!t)
|
|
28585
28802
|
return "draft-7";
|
|
@@ -28621,7 +28838,7 @@ function parseWithCompat(schema, data) {
|
|
|
28621
28838
|
return result.data;
|
|
28622
28839
|
}
|
|
28623
28840
|
|
|
28624
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
28841
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
28625
28842
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
28626
28843
|
var Protocol = class {
|
|
28627
28844
|
constructor(_options) {
|
|
@@ -28833,6 +29050,10 @@ var Protocol = class {
|
|
|
28833
29050
|
this._progressHandlers.clear();
|
|
28834
29051
|
this._taskProgressTokens.clear();
|
|
28835
29052
|
this._pendingDebouncedNotifications.clear();
|
|
29053
|
+
for (const info of this._timeoutInfo.values()) {
|
|
29054
|
+
clearTimeout(info.timeoutId);
|
|
29055
|
+
}
|
|
29056
|
+
this._timeoutInfo.clear();
|
|
28836
29057
|
for (const controller of this._requestHandlerAbortControllers.values()) {
|
|
28837
29058
|
controller.abort();
|
|
28838
29059
|
}
|
|
@@ -28963,7 +29184,9 @@ var Protocol = class {
|
|
|
28963
29184
|
await capturedTransport?.send(errorResponse);
|
|
28964
29185
|
}
|
|
28965
29186
|
}).catch((error48) => this._onerror(new Error(`Failed to send response: ${error48}`))).finally(() => {
|
|
28966
|
-
this._requestHandlerAbortControllers.
|
|
29187
|
+
if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
|
|
29188
|
+
this._requestHandlerAbortControllers.delete(request.id);
|
|
29189
|
+
}
|
|
28967
29190
|
});
|
|
28968
29191
|
}
|
|
28969
29192
|
_onprogress(notification) {
|
|
@@ -29569,10 +29792,10 @@ function mergeCapabilities(base, additional) {
|
|
|
29569
29792
|
return result;
|
|
29570
29793
|
}
|
|
29571
29794
|
|
|
29572
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29795
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29573
29796
|
init_types();
|
|
29574
29797
|
|
|
29575
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29798
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
29576
29799
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
29577
29800
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
29578
29801
|
function createDefaultAjvInstance() {
|
|
@@ -29640,7 +29863,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
29640
29863
|
}
|
|
29641
29864
|
};
|
|
29642
29865
|
|
|
29643
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
29866
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
29644
29867
|
init_types();
|
|
29645
29868
|
var ExperimentalServerTasks = class {
|
|
29646
29869
|
constructor(_server) {
|
|
@@ -29854,7 +30077,7 @@ var ExperimentalServerTasks = class {
|
|
|
29854
30077
|
}
|
|
29855
30078
|
};
|
|
29856
30079
|
|
|
29857
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30080
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
29858
30081
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
29859
30082
|
if (!requests) {
|
|
29860
30083
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -29889,7 +30112,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
29889
30112
|
}
|
|
29890
30113
|
}
|
|
29891
30114
|
|
|
29892
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30115
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
29893
30116
|
var Server = class extends Protocol {
|
|
29894
30117
|
/**
|
|
29895
30118
|
* Initializes this server with the given name and version information.
|
|
@@ -30269,10 +30492,10 @@ var Server = class extends Protocol {
|
|
|
30269
30492
|
}
|
|
30270
30493
|
};
|
|
30271
30494
|
|
|
30272
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30495
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30273
30496
|
init_types();
|
|
30274
30497
|
|
|
30275
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30498
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
30276
30499
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
30277
30500
|
function isCompletable(schema) {
|
|
30278
30501
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -30286,7 +30509,7 @@ var McpZodTypeKind;
|
|
|
30286
30509
|
McpZodTypeKind2["Completable"] = "McpCompletable";
|
|
30287
30510
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
30288
30511
|
|
|
30289
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30512
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
30290
30513
|
var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
|
|
30291
30514
|
function validateToolName(name) {
|
|
30292
30515
|
const warnings = [];
|
|
@@ -30344,7 +30567,7 @@ function validateAndWarnToolName(name) {
|
|
|
30344
30567
|
return result.isValid;
|
|
30345
30568
|
}
|
|
30346
30569
|
|
|
30347
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30570
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
30348
30571
|
var ExperimentalMcpServerTasks = class {
|
|
30349
30572
|
constructor(_mcpServer) {
|
|
30350
30573
|
this._mcpServer = _mcpServer;
|
|
@@ -30363,7 +30586,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
30363
30586
|
init_external();
|
|
30364
30587
|
init_external();
|
|
30365
30588
|
|
|
30366
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30589
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
30367
30590
|
var McpServer = class {
|
|
30368
30591
|
constructor(serverInfo, options) {
|
|
30369
30592
|
this._registeredResources = {};
|
|
@@ -30987,6 +31210,9 @@ var McpServer = class {
|
|
|
30987
31210
|
annotations = rest.shift();
|
|
30988
31211
|
}
|
|
30989
31212
|
} else if (typeof firstArg === "object" && firstArg !== null) {
|
|
31213
|
+
if (Object.values(firstArg).some((v) => typeof v === "object" && v !== null)) {
|
|
31214
|
+
throw new Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);
|
|
31215
|
+
}
|
|
30990
31216
|
annotations = rest.shift();
|
|
30991
31217
|
}
|
|
30992
31218
|
}
|
|
@@ -31105,6 +31331,9 @@ function getZodSchemaObject(schema) {
|
|
|
31105
31331
|
if (isZodRawShapeCompat(schema)) {
|
|
31106
31332
|
return objectFromShape(schema);
|
|
31107
31333
|
}
|
|
31334
|
+
if (!isZodSchemaInstance(schema)) {
|
|
31335
|
+
throw new Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");
|
|
31336
|
+
}
|
|
31108
31337
|
return schema;
|
|
31109
31338
|
}
|
|
31110
31339
|
function promptArgumentsFromSchema(schema) {
|
|
@@ -31153,6 +31382,90 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
31153
31382
|
var import_node_child_process2 = require("child_process");
|
|
31154
31383
|
var import_node_util2 = require("util");
|
|
31155
31384
|
|
|
31385
|
+
// package.json
|
|
31386
|
+
var package_default = {
|
|
31387
|
+
name: "@selfagency/beans-mcp",
|
|
31388
|
+
version: "0.5.0",
|
|
31389
|
+
private: false,
|
|
31390
|
+
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31391
|
+
author: {
|
|
31392
|
+
name: "Daniel Sieradski",
|
|
31393
|
+
email: "daniel@self.agency",
|
|
31394
|
+
url: "https://self.agency"
|
|
31395
|
+
},
|
|
31396
|
+
homepage: "https://github.com/selfagency/beans-mcp",
|
|
31397
|
+
bugs: {
|
|
31398
|
+
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31399
|
+
},
|
|
31400
|
+
repository: {
|
|
31401
|
+
type: "git",
|
|
31402
|
+
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31403
|
+
},
|
|
31404
|
+
mcpName: "io.github.selfagency/beans-mcp",
|
|
31405
|
+
keywords: [
|
|
31406
|
+
"beans",
|
|
31407
|
+
"mcp",
|
|
31408
|
+
"model-context-protocol",
|
|
31409
|
+
"issue-tracker",
|
|
31410
|
+
"ai"
|
|
31411
|
+
],
|
|
31412
|
+
license: "MIT",
|
|
31413
|
+
type: "module",
|
|
31414
|
+
exports: {
|
|
31415
|
+
".": {
|
|
31416
|
+
types: "./dist/index.d.ts",
|
|
31417
|
+
import: "./dist/index.js",
|
|
31418
|
+
require: "./dist/index.cjs"
|
|
31419
|
+
}
|
|
31420
|
+
},
|
|
31421
|
+
main: "./dist/index.cjs",
|
|
31422
|
+
module: "./dist/index.js",
|
|
31423
|
+
types: "./dist/index.d.ts",
|
|
31424
|
+
bin: {
|
|
31425
|
+
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31426
|
+
},
|
|
31427
|
+
scripts: {
|
|
31428
|
+
build: "tsup",
|
|
31429
|
+
format: "oxfmt",
|
|
31430
|
+
"lint:fix": "oxlint --fix",
|
|
31431
|
+
lint: "oxlint",
|
|
31432
|
+
postbuild: "node ./scripts/write-dist-package.js",
|
|
31433
|
+
prepare: "husky",
|
|
31434
|
+
release: "zx ./scripts/release.js",
|
|
31435
|
+
"test:coverage": "vitest run --coverage",
|
|
31436
|
+
"test:watch": "vitest",
|
|
31437
|
+
test: "vitest run",
|
|
31438
|
+
"type-check": "tsc --noEmit"
|
|
31439
|
+
},
|
|
31440
|
+
devDependencies: {
|
|
31441
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
31442
|
+
"@octokit/rest": "^22.0.1",
|
|
31443
|
+
"@types/node": "25.5.2",
|
|
31444
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
31445
|
+
"@vitest/ui": "4.1.2",
|
|
31446
|
+
husky: "^9.1.7",
|
|
31447
|
+
"lint-staged": "^16.4.0",
|
|
31448
|
+
ora: "^9.3.0",
|
|
31449
|
+
oxfmt: "^0.43.0",
|
|
31450
|
+
oxlint: "^1.58.0",
|
|
31451
|
+
"oxlint-tsgolint": "^0.20.0",
|
|
31452
|
+
tsup: "8.5.1",
|
|
31453
|
+
typescript: "6.0.2",
|
|
31454
|
+
vitest: "4.1.2",
|
|
31455
|
+
zod: "4.3.6",
|
|
31456
|
+
zx: "^8.8.5"
|
|
31457
|
+
},
|
|
31458
|
+
engines: {
|
|
31459
|
+
node: ">=18"
|
|
31460
|
+
},
|
|
31461
|
+
"lint-staged": {
|
|
31462
|
+
"src/**/*.ts": [
|
|
31463
|
+
"pnpm run lint:fix",
|
|
31464
|
+
"pnpm run format"
|
|
31465
|
+
]
|
|
31466
|
+
}
|
|
31467
|
+
};
|
|
31468
|
+
|
|
31156
31469
|
// src/internal/queryHelpers.ts
|
|
31157
31470
|
function sortBeansInternal(beans, mode) {
|
|
31158
31471
|
const sorted = [...beans];
|
|
@@ -31313,92 +31626,6 @@ var MAX_PATH_LENGTH = 1024;
|
|
|
31313
31626
|
|
|
31314
31627
|
// src/server/BeansMcpServer.ts
|
|
31315
31628
|
init_utils();
|
|
31316
|
-
|
|
31317
|
-
// package.json
|
|
31318
|
-
var package_default = {
|
|
31319
|
-
name: "@selfagency/beans-mcp",
|
|
31320
|
-
version: "0.4.2",
|
|
31321
|
-
private: false,
|
|
31322
|
-
description: "MCP (Model Context Protocol) server for Beans issue tracker",
|
|
31323
|
-
author: {
|
|
31324
|
-
name: "Daniel Sieradski",
|
|
31325
|
-
email: "daniel@self.agency",
|
|
31326
|
-
url: "https://self.agency"
|
|
31327
|
-
},
|
|
31328
|
-
homepage: "https://github.com/hmans/beans",
|
|
31329
|
-
bugs: {
|
|
31330
|
-
url: "https://github.com/selfagency/beans-mcp/issues"
|
|
31331
|
-
},
|
|
31332
|
-
repository: {
|
|
31333
|
-
type: "git",
|
|
31334
|
-
url: "git+https://github.com/selfagency/beans-mcp.git"
|
|
31335
|
-
},
|
|
31336
|
-
mcpName: "io.github.selfagency/beans-mcp",
|
|
31337
|
-
keywords: [
|
|
31338
|
-
"beans",
|
|
31339
|
-
"mcp",
|
|
31340
|
-
"model-context-protocol",
|
|
31341
|
-
"issue-tracker",
|
|
31342
|
-
"ai"
|
|
31343
|
-
],
|
|
31344
|
-
license: "MIT",
|
|
31345
|
-
type: "module",
|
|
31346
|
-
exports: {
|
|
31347
|
-
".": {
|
|
31348
|
-
types: "./dist/index.d.ts",
|
|
31349
|
-
import: "./dist/index.js",
|
|
31350
|
-
require: "./dist/index.cjs"
|
|
31351
|
-
}
|
|
31352
|
-
},
|
|
31353
|
-
main: "./dist/index.cjs",
|
|
31354
|
-
module: "./dist/index.js",
|
|
31355
|
-
types: "./dist/index.d.ts",
|
|
31356
|
-
bin: {
|
|
31357
|
-
"beans-mcp": "dist/beans-mcp-server.cjs"
|
|
31358
|
-
},
|
|
31359
|
-
scripts: {
|
|
31360
|
-
build: "tsup",
|
|
31361
|
-
format: "oxfmt",
|
|
31362
|
-
"lint:fix": "oxlint --fix",
|
|
31363
|
-
lint: "oxlint",
|
|
31364
|
-
postbuild: "node ./scripts/write-dist-package.js",
|
|
31365
|
-
prepare: "husky",
|
|
31366
|
-
release: "zx ./scripts/release.js",
|
|
31367
|
-
"test:coverage": "vitest run --coverage",
|
|
31368
|
-
"test:watch": "vitest",
|
|
31369
|
-
test: "vitest run",
|
|
31370
|
-
"type-check": "tsc --noEmit"
|
|
31371
|
-
},
|
|
31372
|
-
devDependencies: {
|
|
31373
|
-
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
31374
|
-
"@octokit/rest": "^22.0.1",
|
|
31375
|
-
"@types/node": "25.5.0",
|
|
31376
|
-
"@vitest/coverage-v8": "^4.1.0",
|
|
31377
|
-
"@vitest/ui": "4.1.0",
|
|
31378
|
-
husky: "^9.1.7",
|
|
31379
|
-
"lint-staged": "^16.3.3",
|
|
31380
|
-
ora: "^9.3.0",
|
|
31381
|
-
oxfmt: "^0.40.0",
|
|
31382
|
-
oxlint: "^1.55.0",
|
|
31383
|
-
"oxlint-tsgolint": "^0.16.0",
|
|
31384
|
-
tsup: "8.5.1",
|
|
31385
|
-
typescript: "^5.9.3",
|
|
31386
|
-
vitest: "4.1.0",
|
|
31387
|
-
zod: "4.3.6",
|
|
31388
|
-
zx: "^8.8.5"
|
|
31389
|
-
},
|
|
31390
|
-
engines: {
|
|
31391
|
-
node: ">=18"
|
|
31392
|
-
},
|
|
31393
|
-
"lint-staged": {
|
|
31394
|
-
"src/**/*.ts": [
|
|
31395
|
-
"pnpm run lint:fix",
|
|
31396
|
-
"pnpm run format"
|
|
31397
|
-
]
|
|
31398
|
-
}
|
|
31399
|
-
};
|
|
31400
|
-
|
|
31401
|
-
// src/server/BeansMcpServer.ts
|
|
31402
31629
|
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
|
|
31403
31630
|
var PACKAGE_VERSION = package_default.version ?? "0.0.0-dev";
|
|
31404
31631
|
function getSafeCliEnv(env) {
|
|
@@ -31470,7 +31697,12 @@ function viewHandler(backend) {
|
|
|
31470
31697
|
const byId = new Map(beans.map((b) => [b.id, b]));
|
|
31471
31698
|
const found = ids.map((id) => byId.get(id)).filter(Boolean);
|
|
31472
31699
|
const missingBeanIds = ids.filter((id) => !byId.has(id));
|
|
31473
|
-
return makeTextAndStructured({
|
|
31700
|
+
return makeTextAndStructured({
|
|
31701
|
+
beans: found,
|
|
31702
|
+
missingBeanIds,
|
|
31703
|
+
count: found.length,
|
|
31704
|
+
requestedCount: ids.length
|
|
31705
|
+
});
|
|
31474
31706
|
};
|
|
31475
31707
|
}
|
|
31476
31708
|
async function checkVersionCompatibility(cliPath, workspaceRoot, detector) {
|
|
@@ -31562,7 +31794,11 @@ function deleteHandler(backend) {
|
|
|
31562
31794
|
await backend.delete(id);
|
|
31563
31795
|
results.push({ beanId: id, deleted: true });
|
|
31564
31796
|
} catch (error48) {
|
|
31565
|
-
results.push({
|
|
31797
|
+
results.push({
|
|
31798
|
+
beanId: id,
|
|
31799
|
+
deleted: false,
|
|
31800
|
+
error: error48.message
|
|
31801
|
+
});
|
|
31566
31802
|
}
|
|
31567
31803
|
}
|
|
31568
31804
|
return makeTextAndStructured({
|
|
@@ -31573,6 +31809,28 @@ function deleteHandler(backend) {
|
|
|
31573
31809
|
});
|
|
31574
31810
|
};
|
|
31575
31811
|
}
|
|
31812
|
+
function bulkCreateHandler(backend) {
|
|
31813
|
+
return async (input) => {
|
|
31814
|
+
const results = await backend.bulkCreate(input.beans, input.parent);
|
|
31815
|
+
return makeTextAndStructured({
|
|
31816
|
+
results,
|
|
31817
|
+
requestedCount: input.beans.length,
|
|
31818
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31819
|
+
failedCount: results.filter((r) => r.error).length
|
|
31820
|
+
});
|
|
31821
|
+
};
|
|
31822
|
+
}
|
|
31823
|
+
function bulkUpdateHandler(backend) {
|
|
31824
|
+
return async (input) => {
|
|
31825
|
+
const results = await backend.bulkUpdate(input.beans, input.parent);
|
|
31826
|
+
return makeTextAndStructured({
|
|
31827
|
+
results,
|
|
31828
|
+
requestedCount: input.beans.length,
|
|
31829
|
+
successCount: results.filter((r) => r.bean).length,
|
|
31830
|
+
failedCount: results.filter((r) => r.error).length
|
|
31831
|
+
});
|
|
31832
|
+
};
|
|
31833
|
+
}
|
|
31576
31834
|
function queryHandler(backend) {
|
|
31577
31835
|
return async (opts) => handleQueryOperation(backend, opts);
|
|
31578
31836
|
}
|
|
@@ -31656,7 +31914,8 @@ function registerTools(server, backend) {
|
|
|
31656
31914
|
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
31657
31915
|
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31658
31916
|
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
31659
|
-
|
|
31917
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
31918
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
31660
31919
|
parent: external_exports3.string().max(MAX_ID_LENGTH).optional()
|
|
31661
31920
|
}),
|
|
31662
31921
|
annotations: {
|
|
@@ -31770,6 +32029,68 @@ function registerTools(server, backend) {
|
|
|
31770
32029
|
},
|
|
31771
32030
|
deleteHandler(backend)
|
|
31772
32031
|
);
|
|
32032
|
+
const beanCreateItemSchema = external_exports3.object({
|
|
32033
|
+
title: external_exports3.string().min(1).max(MAX_TITLE_LENGTH),
|
|
32034
|
+
type: external_exports3.string().min(1).max(MAX_METADATA_LENGTH),
|
|
32035
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32036
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32037
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Body markdown content"),
|
|
32038
|
+
description: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("Deprecated alias for body"),
|
|
32039
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item")
|
|
32040
|
+
});
|
|
32041
|
+
server.registerTool(
|
|
32042
|
+
"beans_bulk_create",
|
|
32043
|
+
{
|
|
32044
|
+
title: "Bulk Create Beans",
|
|
32045
|
+
description: "Create multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32046
|
+
inputSchema: external_exports3.object({
|
|
32047
|
+
beans: external_exports3.array(beanCreateItemSchema).min(1),
|
|
32048
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32049
|
+
}),
|
|
32050
|
+
annotations: {
|
|
32051
|
+
readOnlyHint: false,
|
|
32052
|
+
destructiveHint: false,
|
|
32053
|
+
idempotentHint: false,
|
|
32054
|
+
openWorldHint: false
|
|
32055
|
+
}
|
|
32056
|
+
},
|
|
32057
|
+
bulkCreateHandler(backend)
|
|
32058
|
+
);
|
|
32059
|
+
const beanUpdateItemSchema = external_exports3.object({
|
|
32060
|
+
beanId: external_exports3.string().min(1).max(MAX_ID_LENGTH),
|
|
32061
|
+
status: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32062
|
+
type: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32063
|
+
priority: external_exports3.string().max(MAX_METADATA_LENGTH).optional(),
|
|
32064
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Override the top-level parent for this item"),
|
|
32065
|
+
clearParent: external_exports3.boolean().optional(),
|
|
32066
|
+
blocking: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32067
|
+
blockedBy: external_exports3.array(external_exports3.string().max(MAX_ID_LENGTH)).optional(),
|
|
32068
|
+
body: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32069
|
+
bodyAppend: external_exports3.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
32070
|
+
bodyReplace: external_exports3.array(external_exports3.object({ old: external_exports3.string().max(MAX_DESCRIPTION_LENGTH), new: external_exports3.string().max(MAX_DESCRIPTION_LENGTH) })).optional(),
|
|
32071
|
+
ifMatch: external_exports3.string().max(MAX_METADATA_LENGTH).optional()
|
|
32072
|
+
}).refine(
|
|
32073
|
+
(input) => !(input.body !== void 0 && (input.bodyAppend !== void 0 || input.bodyReplace !== void 0)),
|
|
32074
|
+
{ message: "body cannot be combined with bodyAppend/bodyReplace" }
|
|
32075
|
+
);
|
|
32076
|
+
server.registerTool(
|
|
32077
|
+
"beans_bulk_update",
|
|
32078
|
+
{
|
|
32079
|
+
title: "Bulk Update Beans",
|
|
32080
|
+
description: "Update multiple beans in one call. Optionally assign all of them (or a subset) to a shared parent.",
|
|
32081
|
+
inputSchema: external_exports3.object({
|
|
32082
|
+
beans: external_exports3.array(beanUpdateItemSchema).min(1),
|
|
32083
|
+
parent: external_exports3.string().max(MAX_ID_LENGTH).optional().describe("Default parent ID applied to any bean that does not specify its own parent")
|
|
32084
|
+
}),
|
|
32085
|
+
annotations: {
|
|
32086
|
+
readOnlyHint: false,
|
|
32087
|
+
destructiveHint: false,
|
|
32088
|
+
idempotentHint: false,
|
|
32089
|
+
openWorldHint: false
|
|
32090
|
+
}
|
|
32091
|
+
},
|
|
32092
|
+
bulkUpdateHandler(backend)
|
|
32093
|
+
);
|
|
31773
32094
|
server.registerTool(
|
|
31774
32095
|
"beans_query",
|
|
31775
32096
|
{
|
|
@@ -31855,6 +32176,12 @@ var MutableBackend = class {
|
|
|
31855
32176
|
delete(id) {
|
|
31856
32177
|
return this.inner.delete(id);
|
|
31857
32178
|
}
|
|
32179
|
+
bulkCreate(beans, defaultParent) {
|
|
32180
|
+
return this.inner.bulkCreate(beans, defaultParent);
|
|
32181
|
+
}
|
|
32182
|
+
bulkUpdate(beans, defaultParent) {
|
|
32183
|
+
return this.inner.bulkUpdate(beans, defaultParent);
|
|
32184
|
+
}
|
|
31858
32185
|
openConfig() {
|
|
31859
32186
|
return this.inner.openConfig();
|
|
31860
32187
|
}
|