@lucianfialho/build-in-public-mcp 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lucian Fialho
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # Build in Public MCP Server
2
+
3
+ > โœ… **v0.3.0 - AI-Powered Tweet Suggestions!**
4
+
5
+ MCP (Model Context Protocol) server for Build in Public - automatically share your dev progress on Twitter directly from Claude Code.
6
+
7
+ ## ๐ŸŽฏ What is this?
8
+
9
+ **The idea is simple:** If Claude Code is already helping you build, why not use it to document the journey too?
10
+
11
+ This MCP server analyzes your coding sessions and generates intelligent tweet suggestions about what you accomplished. Share your dev journey without breaking flow!
12
+
13
+ **Features:**
14
+ - ๐Ÿค– **AI-powered tweet suggestions** - Analyzes your coding session and suggests tweets
15
+ - ๐Ÿ”„ **Retrospective mode** (`/bp retro`) - Review entire session and extract achievements
16
+ - ๐Ÿฆ Post tweets immediately with `/bp` command
17
+ - ๐Ÿงต Create threads about your dev progress
18
+ - ๐Ÿ” OAuth authentication (tokens stored locally)
19
+ - ๐Ÿ’ฏ 100% local - no external servers needed
20
+ - โšก Fast STDIO transport
21
+
22
+ ## ๐Ÿ“ฆ Installation
23
+
24
+ ### Method 1: NPX (Recommended)
25
+
26
+ ```bash
27
+ claude mcp add --transport stdio build-in-public npx -y @lucianfialho/build-in-public-mcp
28
+ ```
29
+
30
+ ### Method 2: Global Install
31
+
32
+ ```bash
33
+ npm install -g @lucianfialho/build-in-public-mcp
34
+ claude mcp add --transport stdio build-in-public build-in-public-mcp
35
+ ```
36
+
37
+ ## ๐Ÿ“– How It Works
38
+
39
+ **The Philosophy:** If Claude Code is already helping you code, why not help you share your journey too?
40
+
41
+ 1. **You code** - Claude Code assists you with development
42
+ 2. **Context is captured** - Files changed, commands run, achievements unlocked
43
+ 3. **AI analyzes** - When you run `/bp retro`, AI extracts meaningful insights
44
+ 4. **Suggestions generated** - Get tweet ideas about what you actually accomplished
45
+ 5. **One-click post** - Choose a suggestion and post to Twitter instantly
46
+
47
+ ## ๐Ÿš€ Quick Start
48
+
49
+ ### 1. Setup Twitter Authentication
50
+
51
+ You have **two options** for authentication:
52
+
53
+ #### Option A: Interactive OAuth (Recommended)
54
+
55
+ First time only:
56
+ ```
57
+ You: How do I setup build in public?
58
+ Claude: Let me help you setup Twitter authentication
59
+ > Calls: mcp__bip__setup_auth
60
+ > Opens browser for OAuth
61
+ > You authorize the app
62
+ > Copy PIN from Twitter
63
+ > Paste in terminal
64
+ โœ… Done! Tokens saved to ~/.build-in-public/auth.json
65
+ ```
66
+
67
+ #### Option B: Environment Variables
68
+
69
+ Set these environment variables before starting Claude Code:
70
+
71
+ ```bash
72
+ export TWITTER_API_KEY="your_api_key"
73
+ export TWITTER_API_SECRET="your_api_secret"
74
+ export TWITTER_ACCESS_TOKEN="your_access_token"
75
+ export TWITTER_ACCESS_SECRET="your_access_secret"
76
+ ```
77
+
78
+ **Where to get these credentials:**
79
+ 1. Go to [Twitter Developer Portal](https://developer.twitter.com/en/portal/dashboard)
80
+ 2. Create an app (or use existing)
81
+ 3. Go to "Keys and tokens"
82
+ 4. Copy API Key & Secret (Consumer Keys)
83
+ 5. Generate Access Token & Secret
84
+
85
+ **Priority:** If both methods are configured, environment variables take precedence over `~/.build-in-public/auth.json`.
86
+
87
+ ### 2. Start Posting!
88
+
89
+ #### Option 1: Quick Tweet
90
+ Post immediately with a custom message:
91
+ ```
92
+ /bp Just launched my new feature! ๐Ÿš€
93
+ ```
94
+
95
+ #### Option 2: AI-Powered Retro (Recommended!)
96
+ Let AI analyze your entire coding session and suggest tweets:
97
+ ```
98
+ /bp retro
99
+ ```
100
+
101
+ Claude will:
102
+ - Review everything you did this session
103
+ - Extract achievements, learnings, and challenges
104
+ - Generate multiple tweet suggestions with confidence scores
105
+ - Let you choose or customize before posting
106
+
107
+ **Example output:**
108
+ ```
109
+ ๐Ÿ“Š Session Analysis Complete!
110
+
111
+ Achievements:
112
+ โœ… Implemented OAuth authentication system
113
+ โœ… Fixed 3 critical bugs
114
+ โœ… Shipped v2.0 with new dashboard
115
+
116
+ Based on your session, here are tweet suggestions:
117
+
118
+ 1. [85% confidence] "Just shipped v2.0! ๐Ÿš€
119
+ New features: OAuth login, redesigned dashboard, 3 bugs squashed.
120
+ 4 hours of flow state โ†’ production ready โœจ #BuildInPublic"
121
+
122
+ 2. [75% confidence] "๐Ÿ’ก TIL: OAuth token refresh is trickier than I thought..."
123
+
124
+ Which one would you like to post? (1-2, or provide custom message)
125
+ ```
126
+
127
+ #### Option 3: AI Suggestions from Current Context
128
+ ```
129
+ /bp
130
+ ```
131
+ Gets suggestions based on what the hooks have captured so far.
132
+
133
+ ## ๐Ÿ› ๏ธ Architecture
134
+
135
+ ```
136
+ Claude Code โ†’ STDIO โ†’ MCP Server (local) โ†’ HTTPS โ†’ Twitter API
137
+ โ†“
138
+ ~/.build-in-public/
139
+ - auth.json (OAuth tokens)
140
+ - context.json (Session context)
141
+ - history.json (Tweet history)
142
+ ```
143
+
144
+ **100% local, zero external infrastructure!**
145
+
146
+ ## ๐Ÿ“š Available Tools
147
+
148
+ ### `mcp__bip__tweet`
149
+ Post a tweet immediately.
150
+
151
+ **Input:**
152
+ ```json
153
+ {
154
+ "message": "Your tweet message here (max 280 chars)"
155
+ }
156
+ ```
157
+
158
+ **Returns:** Tweet URL
159
+
160
+ ### `mcp__bip__thread`
161
+ Create a Twitter thread from multiple messages. Posts tweets in reply chain.
162
+
163
+ **Input:**
164
+ ```json
165
+ {
166
+ "messages": ["Tweet 1", "Tweet 2", "Tweet 3"]
167
+ }
168
+ ```
169
+
170
+ **Returns:** Array of tweet URLs
171
+
172
+ ### `mcp__bip__setup_auth`
173
+ Setup Twitter OAuth authentication via PIN-based flow.
174
+
175
+ **Input:** None (interactive flow)
176
+
177
+ **Returns:** Auth status and username
178
+
179
+ ### `mcp__bip__status`
180
+ Check authentication status and show storage location.
181
+
182
+ **Input:** None
183
+
184
+ **Returns:** Status info including authenticated user
185
+
186
+ ## ๐Ÿ” Privacy & Security
187
+
188
+ - โœ… OAuth tokens stored locally in `~/.build-in-public/auth.json`
189
+ - โœ… Never sent to external servers (except Twitter API)
190
+ - โœ… No analytics, no tracking, no telemetry
191
+ - โœ… Open source - inspect the code yourself
192
+
193
+ ## ๐Ÿ—บ๏ธ Roadmap
194
+
195
+ - [x] v0.1.0 - Basic MCP server + STDIO transport
196
+ - [x] v0.2.0 - Twitter OAuth + tweet posting + thread creation โœ…
197
+ - [ ] v0.3.0 - MCP prompts + better error handling
198
+ - [ ] v1.0.0 - Production ready + comprehensive docs
199
+ - [ ] v1.1.0 - Skill for automatic context tracking
200
+ - [ ] v2.0.0 - Optional Apify backend for analytics
201
+
202
+ ## ๐Ÿค Contributing
203
+
204
+ This is an early alpha! Contributions, issues, and feedback welcome.
205
+
206
+ **Repository:** [github.com/lucianfialho/build-in-public-mcp](https://github.com/lucianfialho/build-in-public-mcp)
207
+
208
+ ## ๐Ÿ“„ License
209
+
210
+ MIT License - see LICENSE file for details
211
+
212
+ ## ๐Ÿ™ Credits
213
+
214
+ Built with [Claude Code](https://claude.com/code) and inspired by the #BuildInPublic community.
215
+
216
+ ---
217
+
218
+ **Made with โค๏ธ for developers who build in public**
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Build in Public MCP Server
4
+ * Entry point for STDIO transport
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,425 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Build in Public MCP Server
5
+ * Entry point for STDIO transport
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
9
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
10
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
11
+ const oauth_js_1 = require("./utils/oauth.js");
12
+ const twitter_js_1 = require("./services/twitter.js");
13
+ const storage_js_1 = require("./services/storage.js");
14
+ const suggestion_engine_js_1 = require("./services/suggestion-engine.js");
15
+ // MCP Server instance
16
+ const server = new index_js_1.Server({
17
+ name: 'build-in-public',
18
+ version: '0.3.0',
19
+ }, {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ });
24
+ /**
25
+ * List available tools
26
+ */
27
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
28
+ return {
29
+ tools: [
30
+ {
31
+ name: 'mcp__bip__tweet',
32
+ description: 'Post a tweet immediately for build in public. Requires authentication.',
33
+ inputSchema: {
34
+ type: 'object',
35
+ properties: {
36
+ message: {
37
+ type: 'string',
38
+ description: 'The tweet message to post (max 280 characters)',
39
+ },
40
+ },
41
+ required: ['message'],
42
+ },
43
+ },
44
+ {
45
+ name: 'mcp__bip__thread',
46
+ description: 'Create a Twitter thread from multiple messages. Posts tweets in reply chain.',
47
+ inputSchema: {
48
+ type: 'object',
49
+ properties: {
50
+ messages: {
51
+ type: 'array',
52
+ items: { type: 'string' },
53
+ description: 'Array of tweet messages for the thread',
54
+ },
55
+ replyToTweetId: {
56
+ type: 'string',
57
+ description: 'Optional: Tweet ID to reply to (creates thread as replies to this tweet)',
58
+ },
59
+ },
60
+ required: ['messages'],
61
+ },
62
+ },
63
+ {
64
+ name: 'mcp__bip__setup_auth',
65
+ description: 'Setup Twitter authentication via OAuth 1.0a (PIN-based flow)',
66
+ inputSchema: {
67
+ type: 'object',
68
+ properties: {},
69
+ },
70
+ },
71
+ {
72
+ name: 'mcp__bip__status',
73
+ description: 'Check authentication status and storage location',
74
+ inputSchema: {
75
+ type: 'object',
76
+ properties: {},
77
+ },
78
+ },
79
+ {
80
+ name: 'mcp__bip__suggest',
81
+ description: 'Generate intelligent tweet suggestions based on session context',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ contextId: {
86
+ type: 'string',
87
+ description: 'Optional context ID (uses current session if not provided)',
88
+ },
89
+ },
90
+ },
91
+ },
92
+ {
93
+ name: 'mcp__bip__save_context',
94
+ description: 'Save session context for later analysis and suggestions',
95
+ inputSchema: {
96
+ type: 'object',
97
+ properties: {
98
+ context: {
99
+ type: 'object',
100
+ description: 'Session context data',
101
+ },
102
+ },
103
+ required: ['context'],
104
+ },
105
+ },
106
+ {
107
+ name: 'mcp__bip__get_context',
108
+ description: 'Retrieve current session context',
109
+ inputSchema: {
110
+ type: 'object',
111
+ properties: {
112
+ contextId: {
113
+ type: 'string',
114
+ description: 'Optional context ID (uses current session if not provided)',
115
+ },
116
+ },
117
+ },
118
+ },
119
+ ],
120
+ };
121
+ });
122
+ /**
123
+ * Handle tool calls
124
+ */
125
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
126
+ const { name, arguments: args } = request.params;
127
+ try {
128
+ switch (name) {
129
+ case 'mcp__bip__tweet': {
130
+ const { message } = args;
131
+ if (!message) {
132
+ throw new Error('Message is required');
133
+ }
134
+ if (message.length > 280) {
135
+ throw new Error(`Tweet is too long (${message.length} characters, max 280)`);
136
+ }
137
+ // Check authentication
138
+ if (!(0, twitter_js_1.isAuthenticated)()) {
139
+ return {
140
+ content: [
141
+ {
142
+ type: 'text',
143
+ text: 'โŒ Not authenticated\n\n' +
144
+ 'Please run mcp__bip__setup_auth first to authenticate with Twitter.',
145
+ },
146
+ ],
147
+ isError: true,
148
+ };
149
+ }
150
+ // Post tweet
151
+ const result = await (0, twitter_js_1.postTweet)(message);
152
+ return {
153
+ content: [
154
+ {
155
+ type: 'text',
156
+ text: `โœ… Tweet posted successfully!\n\n` +
157
+ `๐Ÿ”— ${result.url}\n\n` +
158
+ `Message: "${message}"`,
159
+ },
160
+ ],
161
+ };
162
+ }
163
+ case 'mcp__bip__thread': {
164
+ const { messages, replyToTweetId } = args;
165
+ if (!messages || messages.length === 0) {
166
+ throw new Error('Thread must have at least one message');
167
+ }
168
+ // Validate message lengths
169
+ for (let i = 0; i < messages.length; i++) {
170
+ if (messages[i].length > 280) {
171
+ throw new Error(`Message ${i + 1} is too long (${messages[i].length} characters, max 280)`);
172
+ }
173
+ }
174
+ // Check authentication
175
+ if (!(0, twitter_js_1.isAuthenticated)()) {
176
+ return {
177
+ content: [
178
+ {
179
+ type: 'text',
180
+ text: 'โŒ Not authenticated\n\n' +
181
+ 'Please run mcp__bip__setup_auth first to authenticate with Twitter.',
182
+ },
183
+ ],
184
+ isError: true,
185
+ };
186
+ }
187
+ // Post thread
188
+ const result = await (0, twitter_js_1.postThread)(messages, replyToTweetId);
189
+ return {
190
+ content: [
191
+ {
192
+ type: 'text',
193
+ text: `โœ… Thread posted successfully!\n\n` +
194
+ `๐Ÿงต ${messages.length} tweets in thread\n` +
195
+ `๐Ÿ”— Thread starts at: ${result.urls[0]}\n\n` +
196
+ `All tweet URLs:\n${result.urls.map((url, i) => ` ${i + 1}. ${url}`).join('\n')}`,
197
+ },
198
+ ],
199
+ };
200
+ }
201
+ case 'mcp__bip__setup_auth': {
202
+ console.error('\n๐Ÿ” Starting OAuth setup...\n');
203
+ console.error('โš ๏ธ IMPORTANT: This is an interactive flow.');
204
+ console.error(' Make sure you are running this in a terminal (not via Claude Code UI).\n');
205
+ try {
206
+ const tokens = await (0, oauth_js_1.performOAuthFlow)();
207
+ // Verify credentials
208
+ const user = await (0, twitter_js_1.verifyCredentials)();
209
+ return {
210
+ content: [
211
+ {
212
+ type: 'text',
213
+ text: `โœ… Authentication successful!\n\n` +
214
+ `๐Ÿ‘ค Authenticated as: @${user.username} (${user.name})\n` +
215
+ `๐Ÿ’พ Tokens saved to: ${(0, storage_js_1.getStorageDir)()}/auth.json\n\n` +
216
+ `You can now use:\n` +
217
+ ` - mcp__bip__tweet to post tweets\n` +
218
+ ` - mcp__bip__thread to create threads`,
219
+ },
220
+ ],
221
+ };
222
+ }
223
+ catch (error) {
224
+ const errorMessage = error instanceof Error ? error.message : String(error);
225
+ return {
226
+ content: [
227
+ {
228
+ type: 'text',
229
+ text: `โŒ OAuth setup failed\n\n` +
230
+ `Error: ${errorMessage}\n\n` +
231
+ `Make sure you:\n` +
232
+ ` 1. Have valid Twitter API credentials\n` +
233
+ ` 2. Authorized the app on Twitter\n` +
234
+ ` 3. Entered the correct PIN code`,
235
+ },
236
+ ],
237
+ isError: true,
238
+ };
239
+ }
240
+ }
241
+ case 'mcp__bip__status': {
242
+ const authenticated = (0, twitter_js_1.isAuthenticated)();
243
+ let statusText = `๐Ÿ“Š Build in Public MCP Server Status\n\n`;
244
+ statusText += `Version: 0.3.0\n`;
245
+ statusText += `Storage: ${(0, storage_js_1.getStorageDir)()}\n\n`;
246
+ // Debug: Show env vars status
247
+ statusText += `๐Ÿ” Environment Variables:\n`;
248
+ statusText += ` TWITTER_API_KEY: ${process.env.TWITTER_API_KEY ? 'โœ… Set' : 'โŒ Not set'}\n`;
249
+ statusText += ` TWITTER_API_SECRET: ${process.env.TWITTER_API_SECRET ? 'โœ… Set' : 'โŒ Not set'}\n`;
250
+ statusText += ` TWITTER_ACCESS_TOKEN: ${process.env.TWITTER_ACCESS_TOKEN ? 'โœ… Set' : 'โŒ Not set'}\n`;
251
+ statusText += ` TWITTER_ACCESS_SECRET: ${process.env.TWITTER_ACCESS_SECRET ? 'โœ… Set' : 'โŒ Not set'}\n\n`;
252
+ if (authenticated) {
253
+ try {
254
+ const user = await (0, twitter_js_1.verifyCredentials)();
255
+ statusText += `โœ… Authenticated as: @${user.username} (${user.name})\n\n`;
256
+ statusText += `Available tools:\n`;
257
+ statusText += ` - mcp__bip__tweet - Post immediate tweets\n`;
258
+ statusText += ` - mcp__bip__thread - Create Twitter threads\n`;
259
+ }
260
+ catch (error) {
261
+ statusText += `โš ๏ธ Authentication file exists but credentials are invalid\n`;
262
+ statusText += ` Run mcp__bip__setup_auth to re-authenticate\n`;
263
+ }
264
+ }
265
+ else {
266
+ statusText += `โŒ Not authenticated\n\n`;
267
+ statusText += `Run mcp__bip__setup_auth to authenticate with Twitter\n`;
268
+ }
269
+ return {
270
+ content: [
271
+ {
272
+ type: 'text',
273
+ text: statusText,
274
+ },
275
+ ],
276
+ };
277
+ }
278
+ case 'mcp__bip__suggest': {
279
+ // Load session context
280
+ const context = (0, storage_js_1.loadSessionContext)();
281
+ if (!context) {
282
+ return {
283
+ content: [
284
+ {
285
+ type: 'text',
286
+ text: 'โš ๏ธ No session context found\n\n' +
287
+ 'Start coding and the system will automatically track your session. ' +
288
+ 'Or save context manually using mcp__bip__save_context.',
289
+ },
290
+ ],
291
+ };
292
+ }
293
+ // Generate suggestions
294
+ const suggestions = (0, suggestion_engine_js_1.generateSuggestions)(context);
295
+ const confidence = (0, suggestion_engine_js_1.scoreConfidence)(context);
296
+ if (suggestions.length === 0) {
297
+ return {
298
+ content: [
299
+ {
300
+ type: 'text',
301
+ text: '๐Ÿ’ก No strong suggestions yet\n\n' +
302
+ `Session confidence: ${(confidence * 100).toFixed(0)}%\n\n` +
303
+ 'Keep working! Suggestions will appear when:\n' +
304
+ ' - You commit code to git\n' +
305
+ ' - You modify multiple files\n' +
306
+ ' - You log achievements or learnings',
307
+ },
308
+ ],
309
+ };
310
+ }
311
+ let responseText = `๐Ÿ’ก Tweet Suggestions (${suggestions.length})\n\n`;
312
+ responseText += `Overall confidence: ${(confidence * 100).toFixed(0)}%\n\n`;
313
+ suggestions.forEach((suggestion, index) => {
314
+ responseText += `${index + 1}. [${(suggestion.confidence * 100).toFixed(0)}% confidence] ${suggestion.type}\n`;
315
+ responseText += ` ${suggestion.reason}\n\n`;
316
+ responseText += ` "${suggestion.message}"\n\n`;
317
+ });
318
+ responseText += `\nUse mcp__bip__tweet to post any of these suggestions!`;
319
+ return {
320
+ content: [
321
+ {
322
+ type: 'text',
323
+ text: responseText,
324
+ },
325
+ ],
326
+ };
327
+ }
328
+ case 'mcp__bip__save_context': {
329
+ const { context } = args;
330
+ if (!context) {
331
+ throw new Error('Context is required');
332
+ }
333
+ // Save the context
334
+ (0, storage_js_1.saveSessionContext)(context);
335
+ return {
336
+ content: [
337
+ {
338
+ type: 'text',
339
+ text: '๐Ÿ’พ Session context saved successfully!\n\n' +
340
+ `Files modified: ${context.filesModified?.length || 0}\n` +
341
+ `Commands run: ${context.commandsRun?.length || 0}\n` +
342
+ `Commits: ${context.commits?.length || 0}\n\n` +
343
+ 'Use mcp__bip__suggest to generate tweet suggestions based on this context.',
344
+ },
345
+ ],
346
+ };
347
+ }
348
+ case 'mcp__bip__get_context': {
349
+ const context = (0, storage_js_1.loadSessionContext)();
350
+ if (!context) {
351
+ return {
352
+ content: [
353
+ {
354
+ type: 'text',
355
+ text: 'โš ๏ธ No session context found\n\n' +
356
+ 'Context will be automatically created as you work, or you can save context manually using mcp__bip__save_context.',
357
+ },
358
+ ],
359
+ };
360
+ }
361
+ let contextText = `๐Ÿ“Š Session Context\n\n`;
362
+ contextText += `Session ID: ${context.sessionId}\n`;
363
+ contextText += `Started: ${new Date(context.startTime).toLocaleString()}\n`;
364
+ if (context.lastUpdated) {
365
+ contextText += `Last updated: ${new Date(context.lastUpdated).toLocaleString()}\n`;
366
+ }
367
+ contextText += `\n`;
368
+ contextText += `๐Ÿ“ Files modified: ${context.filesModified?.length || 0}\n`;
369
+ contextText += `โš™๏ธ Commands run: ${context.commandsRun?.length || 0}\n`;
370
+ contextText += `๐Ÿ”ง Tools used: ${context.toolsUsed?.length || 0}\n`;
371
+ contextText += `๐Ÿ’ฌ User messages: ${context.userMessages?.length || 0}\n`;
372
+ contextText += `๐Ÿ“ Git commits: ${context.commits?.length || 0}\n`;
373
+ contextText += `โœ… Achievements: ${context.achievements?.length || 0}\n`;
374
+ contextText += `๐ŸŽฏ Challenges: ${context.challenges?.length || 0}\n`;
375
+ contextText += `๐Ÿ’ก Learnings: ${context.learnings?.length || 0}\n\n`;
376
+ if (context.shouldTweet) {
377
+ contextText += `๐Ÿฆ Ready to tweet: Yes\n`;
378
+ if (context.triggerMessage) {
379
+ contextText += `Trigger: "${context.triggerMessage}"\n`;
380
+ }
381
+ }
382
+ return {
383
+ content: [
384
+ {
385
+ type: 'text',
386
+ text: contextText,
387
+ },
388
+ ],
389
+ };
390
+ }
391
+ default:
392
+ throw new Error(`Unknown tool: ${name}`);
393
+ }
394
+ }
395
+ catch (error) {
396
+ const errorMessage = error instanceof Error ? error.message : String(error);
397
+ return {
398
+ content: [
399
+ {
400
+ type: 'text',
401
+ text: `โŒ Error: ${errorMessage}`,
402
+ },
403
+ ],
404
+ isError: true,
405
+ };
406
+ }
407
+ });
408
+ /**
409
+ * Start the server using STDIO transport
410
+ */
411
+ async function main() {
412
+ const transport = new stdio_js_1.StdioServerTransport();
413
+ await server.connect(transport);
414
+ // Log to stderr (stdout is used for MCP protocol)
415
+ console.error('๐Ÿš€ Build in Public MCP Server started');
416
+ console.error('๐Ÿ“ Version: 0.2.0');
417
+ console.error('๐Ÿ”— Transport: STDIO');
418
+ console.error('๐Ÿ’พ Storage:', (0, storage_js_1.getStorageDir)());
419
+ console.error('');
420
+ }
421
+ main().catch((error) => {
422
+ console.error('โŒ Failed to start server:', error);
423
+ process.exit(1);
424
+ });
425
+ //# sourceMappingURL=index.js.map