@selfagency/beans-mcp 0.1.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/index.d.ts ADDED
@@ -0,0 +1,219 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+
3
+ /**
4
+ * Public types for beans-mcp-server
5
+ */
6
+ type SortMode = "status-priority-type-title" | "updated" | "created" | "id";
7
+ type BeanRecord = {
8
+ id: string;
9
+ slug: string;
10
+ path: string;
11
+ title: string;
12
+ body: string;
13
+ status: string;
14
+ type: string;
15
+ description?: string;
16
+ priority?: string;
17
+ tags?: string[];
18
+ parentId?: string;
19
+ blockingIds?: string[];
20
+ blockedByIds?: string[];
21
+ createdAt?: string;
22
+ updatedAt?: string;
23
+ etag?: string;
24
+ };
25
+ /**
26
+ * GraphQL error shape as returned by the Beans CLI GraphQL endpoint.
27
+ */
28
+ type GraphQLError = {
29
+ message: string;
30
+ locations?: Array<{
31
+ line: number;
32
+ column: number;
33
+ }>;
34
+ path?: Array<string | number>;
35
+ extensions?: Record<string, unknown>;
36
+ };
37
+ declare const DEFAULT_MCP_PORT = 39173;
38
+ declare const MAX_ID_LENGTH = 128;
39
+ declare const MAX_TITLE_LENGTH = 1024;
40
+ declare const MAX_METADATA_LENGTH = 128;
41
+
42
+ declare function sortBeansInternal(beans: BeanRecord[], mode: SortMode): BeanRecord[];
43
+
44
+ /**
45
+ * Interface for backend implementations.
46
+ * Allows for alternative implementations (e.g., test harnesses).
47
+ */
48
+ interface BackendInterface {
49
+ init(prefix?: string): Promise<Record<string, unknown>>;
50
+ list(options?: {
51
+ status?: string[];
52
+ type?: string[];
53
+ search?: string;
54
+ }): Promise<BeanRecord[]>;
55
+ create(input: {
56
+ title: string;
57
+ type: string;
58
+ status?: string;
59
+ priority?: string;
60
+ description?: string;
61
+ parent?: string;
62
+ }): Promise<BeanRecord>;
63
+ update(beanId: string, updates: {
64
+ status?: string;
65
+ type?: string;
66
+ priority?: string;
67
+ parent?: string;
68
+ clearParent?: boolean;
69
+ blocking?: string[];
70
+ blockedBy?: string[];
71
+ }): Promise<BeanRecord>;
72
+ delete(beanId: string): Promise<Record<string, unknown>>;
73
+ openConfig(): Promise<{
74
+ configPath: string;
75
+ content: string;
76
+ }>;
77
+ graphqlSchema(): Promise<string>;
78
+ readOutputLog(options?: {
79
+ lines?: number;
80
+ }): Promise<{
81
+ path: string;
82
+ content: string;
83
+ linesReturned: number;
84
+ }>;
85
+ readBeanFile(relativePath: string): Promise<{
86
+ path: string;
87
+ content: string;
88
+ }>;
89
+ editBeanFile(relativePath: string, content: string): Promise<{
90
+ path: string;
91
+ bytes: number;
92
+ }>;
93
+ createBeanFile(relativePath: string, content: string, options?: {
94
+ overwrite?: boolean;
95
+ }): Promise<{
96
+ path: string;
97
+ bytes: number;
98
+ created: boolean;
99
+ }>;
100
+ deleteBeanFile(relativePath: string): Promise<{
101
+ path: string;
102
+ deleted: boolean;
103
+ }>;
104
+ }
105
+ /**
106
+ * Beans CLI backend implementation.
107
+ * Wraps the Beans CLI and provides a typed interface for MCP tools.
108
+ */
109
+ declare class BeansCliBackend implements BackendInterface {
110
+ private readonly workspaceRoot;
111
+ private readonly cliPath;
112
+ private readonly logDir?;
113
+ constructor(workspaceRoot: string, cliPath: string, logDir?: string | undefined);
114
+ /**
115
+ * Returns a safe environment for executing the Beans CLI,
116
+ * whitelisting only necessary variables.
117
+ */
118
+ private getSafeEnv;
119
+ private getBeansRoot;
120
+ private resolveBeanFilePath;
121
+ /**
122
+ * Execute a GraphQL query via the Beans CLI.
123
+ */
124
+ private executeGraphQL;
125
+ init(prefix?: string): Promise<Record<string, unknown>>;
126
+ list(options?: {
127
+ status?: string[];
128
+ type?: string[];
129
+ search?: string;
130
+ }): Promise<BeanRecord[]>;
131
+ create(input: {
132
+ title: string;
133
+ type: string;
134
+ status?: string;
135
+ priority?: string;
136
+ description?: string;
137
+ parent?: string;
138
+ }): Promise<BeanRecord>;
139
+ update(beanId: string, updates: {
140
+ status?: string;
141
+ type?: string;
142
+ priority?: string;
143
+ parent?: string;
144
+ clearParent?: boolean;
145
+ blocking?: string[];
146
+ blockedBy?: string[];
147
+ }): Promise<BeanRecord>;
148
+ delete(beanId: string): Promise<Record<string, unknown>>;
149
+ openConfig(): Promise<{
150
+ configPath: string;
151
+ content: string;
152
+ }>;
153
+ graphqlSchema(): Promise<string>;
154
+ readOutputLog(options?: {
155
+ lines?: number;
156
+ }): Promise<{
157
+ path: string;
158
+ content: string;
159
+ linesReturned: number;
160
+ }>;
161
+ readBeanFile(relativePath: string): Promise<{
162
+ path: string;
163
+ content: string;
164
+ }>;
165
+ editBeanFile(relativePath: string, content: string): Promise<{
166
+ path: string;
167
+ bytes: number;
168
+ }>;
169
+ createBeanFile(relativePath: string, content: string, options?: {
170
+ overwrite?: boolean;
171
+ }): Promise<{
172
+ path: string;
173
+ bytes: number;
174
+ created: boolean;
175
+ }>;
176
+ deleteBeanFile(relativePath: string): Promise<{
177
+ path: string;
178
+ deleted: boolean;
179
+ }>;
180
+ }
181
+
182
+ declare function createBeansMcpServer(opts: {
183
+ workspaceRoot: string;
184
+ cliPath?: string;
185
+ name?: string;
186
+ version?: string;
187
+ logDir?: string;
188
+ backend?: BackendInterface;
189
+ }): Promise<{
190
+ server: McpServer;
191
+ backend: BackendInterface;
192
+ }>;
193
+ declare function parseCliArgs(argv: string[]): {
194
+ workspaceRoot: string;
195
+ /** True when the caller explicitly supplied --workspace-root (or the positional arg). */
196
+ workspaceExplicit: boolean;
197
+ cliPath: string;
198
+ port: number;
199
+ logDir?: string;
200
+ };
201
+ declare function startBeansMcpServer(argv: string[],
202
+ /** For testing only: override the roots resolver so tests can cover the setInner branch. */
203
+ _resolveRoots?: (server: McpServer) => Promise<string | null>): Promise<void>;
204
+
205
+ /**
206
+ * Check whether `target` is contained within `root` after resolving both paths.
207
+ * Guards against the Windows cross-drive bypass where `path.relative(root, target)`
208
+ * returns an absolute path (e.g. `D:\evil`) that does not start with `..`.
209
+ */
210
+ declare function isPathWithinRoot(root: string, target: string): boolean;
211
+ declare function makeTextAndStructured<T extends Record<string, unknown>>(value: T): {
212
+ content: {
213
+ type: "text";
214
+ text: string;
215
+ }[];
216
+ structuredContent: T;
217
+ };
218
+
219
+ export { type BackendInterface, type BeanRecord, BeansCliBackend, DEFAULT_MCP_PORT, type GraphQLError, MAX_ID_LENGTH, MAX_METADATA_LENGTH, MAX_TITLE_LENGTH, type SortMode, createBeansMcpServer, isPathWithinRoot, makeTextAndStructured, parseCliArgs, sortBeansInternal as sortBeans, startBeansMcpServer };