@pegasusheavy/threads-mcp 1.0.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.
Files changed (44) hide show
  1. package/.cursorrules/no-summaries.mdc +1 -0
  2. package/.cursorrules/update-website.mdc +8 -0
  3. package/.husky/README.md +37 -0
  4. package/.husky/commit-msg +3 -0
  5. package/.husky/pre-commit +12 -0
  6. package/.husky/pre-push +31 -0
  7. package/CHANGELOG.md +49 -0
  8. package/LICENSE +22 -0
  9. package/README.md +336 -0
  10. package/commitlint.config.js +27 -0
  11. package/dist/client/enhanced-threads-client.d.ts +49 -0
  12. package/dist/client/enhanced-threads-client.d.ts.map +1 -0
  13. package/dist/client/enhanced-threads-client.js +175 -0
  14. package/dist/client/enhanced-threads-client.js.map +1 -0
  15. package/dist/client/threads-client.d.ts +23 -0
  16. package/dist/client/threads-client.d.ts.map +1 -0
  17. package/dist/client/threads-client.js +208 -0
  18. package/dist/client/threads-client.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +41 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/server.d.ts +10 -0
  24. package/dist/server.d.ts.map +1 -0
  25. package/dist/server.js +382 -0
  26. package/dist/server.js.map +1 -0
  27. package/dist/types/threads.d.ts +298 -0
  28. package/dist/types/threads.d.ts.map +1 -0
  29. package/dist/types/threads.js +76 -0
  30. package/dist/types/threads.js.map +1 -0
  31. package/dist/utils/cache.d.ts +42 -0
  32. package/dist/utils/cache.d.ts.map +1 -0
  33. package/dist/utils/cache.js +147 -0
  34. package/dist/utils/cache.js.map +1 -0
  35. package/dist/utils/rate-limiter.d.ts +31 -0
  36. package/dist/utils/rate-limiter.d.ts.map +1 -0
  37. package/dist/utils/rate-limiter.js +99 -0
  38. package/dist/utils/rate-limiter.js.map +1 -0
  39. package/dist/utils/webhook.d.ts +67 -0
  40. package/dist/utils/webhook.d.ts.map +1 -0
  41. package/dist/utils/webhook.js +187 -0
  42. package/dist/utils/webhook.js.map +1 -0
  43. package/llms.txt +197 -0
  44. package/package.json +65 -0
@@ -0,0 +1,99 @@
1
+ export class RateLimiter {
2
+ tokens;
3
+ lastRefill;
4
+ maxTokens;
5
+ refillRate;
6
+ refillInterval;
7
+ constructor(options) {
8
+ this.maxTokens = options.maxTokens;
9
+ this.refillRate = options.refillRate;
10
+ this.refillInterval = options.refillInterval || 1000;
11
+ this.tokens = this.maxTokens;
12
+ this.lastRefill = Date.now();
13
+ }
14
+ refill() {
15
+ const now = Date.now();
16
+ const elapsed = now - this.lastRefill;
17
+ const intervalsElapsed = elapsed / this.refillInterval;
18
+ const tokensToAdd = intervalsElapsed * this.refillRate;
19
+ this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
20
+ this.lastRefill = now;
21
+ }
22
+ tryConsume(tokens = 1) {
23
+ this.refill();
24
+ if (this.tokens >= tokens) {
25
+ this.tokens -= tokens;
26
+ return true;
27
+ }
28
+ return false;
29
+ }
30
+ async consume(tokens = 1) {
31
+ while (!this.tryConsume(tokens)) {
32
+ const waitTime = this.getWaitTime(tokens);
33
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
34
+ }
35
+ }
36
+ getWaitTime(tokens = 1) {
37
+ this.refill();
38
+ if (this.tokens >= tokens) {
39
+ return 0;
40
+ }
41
+ const tokensNeeded = tokens - this.tokens;
42
+ const intervalsNeeded = Math.ceil(tokensNeeded / this.refillRate);
43
+ return intervalsNeeded * this.refillInterval;
44
+ }
45
+ getTokens() {
46
+ this.refill();
47
+ return this.tokens;
48
+ }
49
+ reset() {
50
+ this.tokens = this.maxTokens;
51
+ this.lastRefill = Date.now();
52
+ }
53
+ }
54
+ export class RateLimiterManager {
55
+ limiters;
56
+ constructor() {
57
+ this.limiters = new Map();
58
+ }
59
+ register(endpoint, options) {
60
+ this.limiters.set(endpoint, new RateLimiter(options));
61
+ }
62
+ tryConsume(endpoint, tokens = 1) {
63
+ const limiter = this.limiters.get(endpoint);
64
+ if (!limiter) {
65
+ return true;
66
+ }
67
+ return limiter.tryConsume(tokens);
68
+ }
69
+ async consume(endpoint, tokens = 1) {
70
+ const limiter = this.limiters.get(endpoint);
71
+ if (limiter) {
72
+ await limiter.consume(tokens);
73
+ }
74
+ }
75
+ getWaitTime(endpoint, tokens = 1) {
76
+ const limiter = this.limiters.get(endpoint);
77
+ return limiter ? limiter.getWaitTime(tokens) : 0;
78
+ }
79
+ reset(endpoint) {
80
+ const limiter = this.limiters.get(endpoint);
81
+ if (limiter) {
82
+ limiter.reset();
83
+ }
84
+ }
85
+ resetAll() {
86
+ this.limiters.forEach((limiter) => limiter.reset());
87
+ }
88
+ }
89
+ export function RateLimited(limiter, tokens = 1) {
90
+ return function (_target, _propertyKey, descriptor) {
91
+ const originalMethod = descriptor.value;
92
+ descriptor.value = async function (...args) {
93
+ await limiter.consume(tokens);
94
+ return originalMethod.apply(this, args);
95
+ };
96
+ return descriptor;
97
+ };
98
+ }
99
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,WAAW;IACd,MAAM,CAAS;IACf,UAAU,CAAS;IACV,SAAS,CAAS;IAClB,UAAU,CAAS;IACnB,cAAc,CAAS;IAExC,YAAY,OAA2B;QACrC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,CAAC;IAKO,MAAM;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;QACtC,MAAM,gBAAgB,GAAG,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;QACvD,MAAM,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC;QAEvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;IACxB,CAAC;IAOD,UAAU,CAAC,SAAiB,CAAC;QAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QAEd,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAMD,KAAK,CAAC,OAAO,CAAC,SAAiB,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAOD,WAAW,CAAC,SAAiB,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QAEd,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAClE,OAAO,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC;IAC/C,CAAC;IAKD,SAAS;QACP,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAKD,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,CAAC;CACF;AAKD,MAAM,OAAO,kBAAkB;IACrB,QAAQ,CAA2B;IAE3C;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;IAC5B,CAAC;IAKD,QAAQ,CAAC,QAAgB,EAAE,OAA2B;QACpD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAKD,UAAU,CAAC,QAAgB,EAAE,SAAiB,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAKD,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,SAAiB,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAKD,WAAW,CAAC,QAAgB,EAAE,SAAiB,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAKD,KAAK,CAAC,QAAgB;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAKD,QAAQ;QACN,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;CACF;AAKD,MAAM,UAAU,WAAW,CAAC,OAAoB,EAAE,SAAiB,CAAC;IAClE,OAAO,UACL,OAAY,EACZ,YAAoB,EACpB,UAA8B;QAE9B,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAW;YAC/C,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { EventEmitter } from 'events';
2
+ export interface WebhookSubscription {
3
+ id: string;
4
+ url: string;
5
+ events: string[];
6
+ secret?: string;
7
+ active: boolean;
8
+ createdAt: Date;
9
+ lastTriggered?: Date;
10
+ }
11
+ export interface WebhookPayload {
12
+ event: string;
13
+ timestamp: Date;
14
+ data: any;
15
+ subscriptionId: string;
16
+ }
17
+ export interface WebhookDelivery {
18
+ id: string;
19
+ subscriptionId: string;
20
+ event: string;
21
+ payload: WebhookPayload;
22
+ status: 'pending' | 'success' | 'failed';
23
+ attempts: number;
24
+ lastAttempt?: Date;
25
+ response?: {
26
+ status: number;
27
+ body: string;
28
+ };
29
+ }
30
+ export interface WebhookOptions {
31
+ maxRetries?: number;
32
+ retryDelay?: number;
33
+ timeout?: number;
34
+ }
35
+ export declare class WebhookManager extends EventEmitter {
36
+ private subscriptions;
37
+ private deliveries;
38
+ private readonly maxRetries;
39
+ private readonly retryDelay;
40
+ private readonly timeout;
41
+ constructor(options?: WebhookOptions);
42
+ subscribe(url: string, events: string[], secret?: string): WebhookSubscription;
43
+ unsubscribe(subscriptionId: string): boolean;
44
+ updateSubscription(subscriptionId: string, updates: Partial<Pick<WebhookSubscription, 'url' | 'events' | 'secret' | 'active'>>): WebhookSubscription | null;
45
+ getSubscription(subscriptionId: string): WebhookSubscription | undefined;
46
+ getSubscriptions(): WebhookSubscription[];
47
+ getSubscriptionsForEvent(event: string): WebhookSubscription[];
48
+ trigger(event: string, data: any): Promise<WebhookDelivery[]>;
49
+ private deliverWebhook;
50
+ private attemptDelivery;
51
+ private sendWebhook;
52
+ private generateSignature;
53
+ static verifySignature(payload: string, signature: string, secret: string): boolean;
54
+ getDelivery(deliveryId: string): WebhookDelivery | undefined;
55
+ getDeliveriesForSubscription(subscriptionId: string): WebhookDelivery[];
56
+ cleanDeliveries(olderThan: Date): number;
57
+ private generateId;
58
+ private delay;
59
+ stats(): {
60
+ subscriptions: number;
61
+ activeSubscriptions: number;
62
+ deliveries: number;
63
+ successfulDeliveries: number;
64
+ failedDeliveries: number;
65
+ };
66
+ }
67
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/utils/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,187 @@
1
+ import crypto from 'crypto';
2
+ import { EventEmitter } from 'events';
3
+ export class WebhookManager extends EventEmitter {
4
+ subscriptions;
5
+ deliveries;
6
+ maxRetries;
7
+ retryDelay;
8
+ timeout;
9
+ constructor(options = {}) {
10
+ super();
11
+ this.subscriptions = new Map();
12
+ this.deliveries = new Map();
13
+ this.maxRetries = options.maxRetries || 3;
14
+ this.retryDelay = options.retryDelay || 1000;
15
+ this.timeout = options.timeout || 5000;
16
+ }
17
+ subscribe(url, events, secret) {
18
+ const subscription = {
19
+ id: this.generateId(),
20
+ url,
21
+ events,
22
+ secret,
23
+ active: true,
24
+ createdAt: new Date(),
25
+ };
26
+ this.subscriptions.set(subscription.id, subscription);
27
+ this.emit('subscription:created', subscription);
28
+ return subscription;
29
+ }
30
+ unsubscribe(subscriptionId) {
31
+ const subscription = this.subscriptions.get(subscriptionId);
32
+ if (!subscription) {
33
+ return false;
34
+ }
35
+ this.subscriptions.delete(subscriptionId);
36
+ this.emit('subscription:deleted', subscription);
37
+ return true;
38
+ }
39
+ updateSubscription(subscriptionId, updates) {
40
+ const subscription = this.subscriptions.get(subscriptionId);
41
+ if (!subscription) {
42
+ return null;
43
+ }
44
+ Object.assign(subscription, updates);
45
+ this.emit('subscription:updated', subscription);
46
+ return subscription;
47
+ }
48
+ getSubscription(subscriptionId) {
49
+ return this.subscriptions.get(subscriptionId);
50
+ }
51
+ getSubscriptions() {
52
+ return Array.from(this.subscriptions.values());
53
+ }
54
+ getSubscriptionsForEvent(event) {
55
+ return Array.from(this.subscriptions.values()).filter((sub) => sub.active && (sub.events.includes('*') || sub.events.includes(event)));
56
+ }
57
+ async trigger(event, data) {
58
+ const subscriptions = this.getSubscriptionsForEvent(event);
59
+ const deliveries = [];
60
+ for (const subscription of subscriptions) {
61
+ const delivery = await this.deliverWebhook(subscription, event, data);
62
+ deliveries.push(delivery);
63
+ }
64
+ return deliveries;
65
+ }
66
+ async deliverWebhook(subscription, event, data) {
67
+ const payload = {
68
+ event,
69
+ timestamp: new Date(),
70
+ data,
71
+ subscriptionId: subscription.id,
72
+ };
73
+ const delivery = {
74
+ id: this.generateId(),
75
+ subscriptionId: subscription.id,
76
+ event,
77
+ payload,
78
+ status: 'pending',
79
+ attempts: 0,
80
+ };
81
+ this.deliveries.set(delivery.id, delivery);
82
+ await this.attemptDelivery(subscription, delivery);
83
+ return delivery;
84
+ }
85
+ async attemptDelivery(subscription, delivery) {
86
+ for (let attempt = 0; attempt < this.maxRetries; attempt++) {
87
+ delivery.attempts = attempt + 1;
88
+ delivery.lastAttempt = new Date();
89
+ try {
90
+ const response = await this.sendWebhook(subscription, delivery.payload);
91
+ delivery.status = 'success';
92
+ delivery.response = response;
93
+ subscription.lastTriggered = new Date();
94
+ this.emit('delivery:success', delivery);
95
+ return;
96
+ }
97
+ catch (error) {
98
+ delivery.status = 'failed';
99
+ delivery.response = {
100
+ status: 0,
101
+ body: error instanceof Error ? error.message : 'Unknown error',
102
+ };
103
+ this.emit('delivery:failed', delivery, error);
104
+ if (attempt < this.maxRetries - 1) {
105
+ await this.delay(this.retryDelay * Math.pow(2, attempt));
106
+ }
107
+ }
108
+ }
109
+ }
110
+ async sendWebhook(subscription, payload) {
111
+ const body = JSON.stringify(payload);
112
+ const signature = subscription.secret
113
+ ? this.generateSignature(body, subscription.secret)
114
+ : undefined;
115
+ const controller = new AbortController();
116
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
117
+ try {
118
+ const response = await fetch(subscription.url, {
119
+ method: 'POST',
120
+ headers: {
121
+ 'Content-Type': 'application/json',
122
+ 'User-Agent': 'Threads-MCP-Webhook/1.0',
123
+ ...(signature && { 'X-Webhook-Signature': signature }),
124
+ },
125
+ body,
126
+ signal: controller.signal,
127
+ });
128
+ const responseBody = await response.text();
129
+ if (!response.ok) {
130
+ throw new Error(`HTTP ${response.status}: ${responseBody}`);
131
+ }
132
+ return {
133
+ status: response.status,
134
+ body: responseBody,
135
+ };
136
+ }
137
+ finally {
138
+ clearTimeout(timeoutId);
139
+ }
140
+ }
141
+ generateSignature(payload, secret) {
142
+ return crypto.createHmac('sha256', secret).update(payload).digest('hex');
143
+ }
144
+ static verifySignature(payload, signature, secret) {
145
+ const expectedSignature = crypto
146
+ .createHmac('sha256', secret)
147
+ .update(payload)
148
+ .digest('hex');
149
+ if (signature.length !== expectedSignature.length) {
150
+ return false;
151
+ }
152
+ return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
153
+ }
154
+ getDelivery(deliveryId) {
155
+ return this.deliveries.get(deliveryId);
156
+ }
157
+ getDeliveriesForSubscription(subscriptionId) {
158
+ return Array.from(this.deliveries.values()).filter((delivery) => delivery.subscriptionId === subscriptionId);
159
+ }
160
+ cleanDeliveries(olderThan) {
161
+ let cleaned = 0;
162
+ this.deliveries.forEach((delivery, id) => {
163
+ if (delivery.lastAttempt && delivery.lastAttempt < olderThan) {
164
+ this.deliveries.delete(id);
165
+ cleaned++;
166
+ }
167
+ });
168
+ return cleaned;
169
+ }
170
+ generateId() {
171
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
172
+ }
173
+ delay(ms) {
174
+ return new Promise((resolve) => setTimeout(resolve, ms));
175
+ }
176
+ stats() {
177
+ const deliveryArray = Array.from(this.deliveries.values());
178
+ return {
179
+ subscriptions: this.subscriptions.size,
180
+ activeSubscriptions: Array.from(this.subscriptions.values()).filter((sub) => sub.active).length,
181
+ deliveries: this.deliveries.size,
182
+ successfulDeliveries: deliveryArray.filter((d) => d.status === 'success').length,
183
+ failedDeliveries: deliveryArray.filter((d) => d.status === 'failed').length,
184
+ };
185
+ }
186
+ }
187
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/utils/webhook.ts"],"names":[],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,197 @@
1
+ # Threads MCP Server
2
+
3
+ > Production-ready Model Context Protocol server for Threads.com API
4
+
5
+ ## Overview
6
+
7
+ Threads MCP Server enables AI assistants like Claude and ChatGPT to interact with the Threads.com API through the Model Context Protocol. Built with TypeScript, featuring rate limiting, caching, and webhooks.
8
+
9
+ ## Repository
10
+
11
+ - GitHub: https://github.com/pegasusheavy/threads-mcp
12
+ - Website: https://pegasusheavy.github.io/threads-mcp/
13
+ - License: MIT (Pegasus Heavy Industries LLC)
14
+
15
+ ## Key Features
16
+
17
+ - Complete Threads.com API integration
18
+ - Rate limiting with token bucket algorithm
19
+ - In-memory caching with TTL and LRU eviction
20
+ - Webhook support with HMAC signature verification
21
+ - Full TypeScript support with Zod validation
22
+ - 90%+ test coverage with Vitest
23
+ - Claude Desktop integration ready
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install threads-mcp
29
+ # or
30
+ pnpm add threads-mcp
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ Set environment variables:
36
+ ```bash
37
+ THREADS_ACCESS_TOKEN="your-access-token"
38
+ THREADS_USER_ID="your-user-id"
39
+ ```
40
+
41
+ Add to Claude Desktop config (`claude_desktop_config.json`):
42
+ ```json
43
+ {
44
+ "mcpServers": {
45
+ "threads": {
46
+ "command": "threads-mcp",
47
+ "env": {
48
+ "THREADS_ACCESS_TOKEN": "your-token",
49
+ "THREADS_USER_ID": "your-user-id"
50
+ }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## Available MCP Tools
57
+
58
+ - `threads_get_profile` - Get authenticated user's profile
59
+ - `threads_get_threads` - List user's threads with pagination
60
+ - `threads_get_thread` - Get specific thread by ID
61
+ - `threads_create_thread` - Create text, image, or video threads
62
+ - `threads_reply_to_thread` - Reply to existing threads
63
+ - `threads_get_insights` - Get thread analytics and metrics
64
+ - `threads_get_replies` - Get all replies to a thread
65
+ - `threads_get_conversation` - Get full conversation thread
66
+
67
+ ## Usage Examples
68
+
69
+ ### Basic Client Usage
70
+ ```typescript
71
+ import { ThreadsClient } from 'threads-mcp';
72
+
73
+ const client = new ThreadsClient({
74
+ accessToken: process.env.THREADS_ACCESS_TOKEN,
75
+ userId: process.env.THREADS_USER_ID,
76
+ });
77
+
78
+ // Create a thread
79
+ const thread = await client.createThread({
80
+ text: 'Hello from Threads MCP! 🚀',
81
+ });
82
+
83
+ // Get profile
84
+ const profile = await client.getProfile(['id', 'username', 'threads_profile_picture_url']);
85
+ ```
86
+
87
+ ### Enhanced Client with Rate Limiting & Caching
88
+ ```typescript
89
+ import { EnhancedThreadsClient } from 'threads-mcp';
90
+
91
+ const client = new EnhancedThreadsClient({
92
+ accessToken: process.env.THREADS_ACCESS_TOKEN,
93
+ userId: process.env.THREADS_USER_ID,
94
+ rateLimit: {
95
+ maxRequests: 100,
96
+ windowMs: 60000,
97
+ },
98
+ cache: {
99
+ ttl: 300000,
100
+ maxSize: 100,
101
+ },
102
+ });
103
+ ```
104
+
105
+ ## Claude Prompts
106
+
107
+ Try these with Claude Desktop after installing:
108
+ - "Show me my Threads profile information"
109
+ - "Post a thread saying 'Hello from Claude! 👋'"
110
+ - "Get analytics for my most recent thread"
111
+ - "Show me my last 10 threads"
112
+ - "Reply to thread ID xyz with 'Great post!'"
113
+
114
+ ## Project Structure
115
+
116
+ ```
117
+ src/
118
+ ├── client/ # API client implementation
119
+ │ ├── threads-client.ts
120
+ │ └── enhanced-threads-client.ts
121
+ ├── server.ts # MCP server implementation
122
+ ├── types/ # TypeScript types and Zod schemas
123
+ ├── utils/ # Rate limiting, caching, webhooks
124
+ └── index.ts # Entry point
125
+
126
+ docs/ # GitHub Pages site (Threads-style)
127
+ examples/ # Usage examples
128
+ ```
129
+
130
+ ## Testing
131
+
132
+ ```bash
133
+ pnpm test # Run all tests
134
+ pnpm test:coverage # Generate coverage report
135
+ pnpm build # Build for production
136
+ pnpm lint # Run ESLint
137
+ ```
138
+
139
+ ## Technical Stack
140
+
141
+ - **Language**: TypeScript
142
+ - **Runtime**: Node.js
143
+ - **Protocol**: Model Context Protocol (MCP)
144
+ - **Validation**: Zod
145
+ - **HTTP Client**: Axios
146
+ - **Testing**: Vitest
147
+ - **Coverage**: 90%+ (statements, branches, functions, lines)
148
+
149
+ ## API Coverage
150
+
151
+ Implements full Threads API including:
152
+ - Profile management
153
+ - Thread creation (text, images, videos)
154
+ - Thread replies and conversations
155
+ - Analytics and insights
156
+ - Media handling
157
+ - Rate limiting compliance
158
+
159
+ ## Advanced Features
160
+
161
+ ### Rate Limiting
162
+ - Token bucket algorithm
163
+ - Configurable limits per endpoint
164
+ - Automatic retry with backoff
165
+ - Request queuing
166
+
167
+ ### Caching
168
+ - In-memory cache with TTL
169
+ - LRU eviction policy
170
+ - Automatic cleanup
171
+ - Cache invalidation
172
+
173
+ ### Webhooks
174
+ - Event subscription
175
+ - HMAC-SHA256 signature verification
176
+ - Automatic retries with exponential backoff
177
+ - Event filtering
178
+
179
+ ## Documentation
180
+
181
+ - Full API Reference: https://pegasusheavy.github.io/threads-mcp/API.html
182
+ - Usage Examples: https://pegasusheavy.github.io/threads-mcp/EXAMPLES.html
183
+ - GitHub: https://github.com/pegasusheavy/threads-mcp
184
+
185
+ ## Contributing
186
+
187
+ See CONTRIBUTING.md for guidelines.
188
+
189
+ ## License
190
+
191
+ MIT License - Copyright (c) 2025 Pegasus Heavy Industries LLC
192
+
193
+ ## Contact
194
+
195
+ - GitHub Issues: https://github.com/pegasusheavy/threads-mcp/issues
196
+ - Repository: https://github.com/pegasusheavy/threads-mcp
197
+
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@pegasusheavy/threads-mcp",
3
+ "version": "1.0.0",
4
+ "description": "A powerful MCP server for Threads.com API integration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "threads-mcp": "dist/index.js"
9
+ },
10
+ "keywords": [
11
+ "mcp",
12
+ "threads",
13
+ "meta",
14
+ "social-media",
15
+ "api"
16
+ ],
17
+ "author": "Pegasus Heavy Industries LLC",
18
+ "license": "MIT",
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^1.0.4",
24
+ "axios": "^1.7.9",
25
+ "zod": "^3.24.1"
26
+ },
27
+ "devDependencies": {
28
+ "@commitlint/cli": "^20.2.0",
29
+ "@commitlint/config-conventional": "^20.2.0",
30
+ "@types/node": "^22.10.2",
31
+ "@typescript-eslint/eslint-plugin": "^8.18.2",
32
+ "@typescript-eslint/parser": "^8.18.2",
33
+ "@vitest/coverage-v8": "^2.1.8",
34
+ "eslint": "^9.17.0",
35
+ "husky": "^9.1.7",
36
+ "lint-staged": "^16.2.7",
37
+ "prettier": "^3.4.2",
38
+ "tsx": "^4.19.2",
39
+ "typescript": "^5.7.2",
40
+ "vitest": "^2.1.8"
41
+ },
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "lint-staged": {
46
+ "*.ts": [
47
+ "eslint --fix",
48
+ "prettier --write"
49
+ ],
50
+ "*.{json,md}": [
51
+ "prettier --write"
52
+ ]
53
+ },
54
+ "scripts": {
55
+ "build": "tsc",
56
+ "dev": "tsx src/index.ts",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest",
59
+ "test:coverage": "vitest run --coverage",
60
+ "lint": "eslint src --ext .ts",
61
+ "lint:fix": "eslint src --ext .ts --fix",
62
+ "format": "prettier --write \"src/**/*.ts\"",
63
+ "format:check": "prettier --check \"src/**/*.ts\""
64
+ }
65
+ }