bn-facebook-mcp-server 0.0.1

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 (51) hide show
  1. package/README.md +245 -0
  2. package/dist/debug-middleware.d.ts +12 -0
  3. package/dist/debug-middleware.d.ts.map +1 -0
  4. package/dist/debug-middleware.js +36 -0
  5. package/dist/debug-middleware.js.map +1 -0
  6. package/dist/facebook-api-client.d.ts +68 -0
  7. package/dist/facebook-api-client.d.ts.map +1 -0
  8. package/dist/facebook-api-client.js +206 -0
  9. package/dist/facebook-api-client.js.map +1 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +132 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/schemas.d.ts +81 -0
  15. package/dist/schemas.d.ts.map +1 -0
  16. package/dist/schemas.js +170 -0
  17. package/dist/schemas.js.map +1 -0
  18. package/dist/tool-loader.d.ts +35 -0
  19. package/dist/tool-loader.d.ts.map +1 -0
  20. package/dist/tool-loader.js +125 -0
  21. package/dist/tool-loader.js.map +1 -0
  22. package/dist/tool-registry.d.ts +44 -0
  23. package/dist/tool-registry.d.ts.map +1 -0
  24. package/dist/tool-registry.js +54 -0
  25. package/dist/tool-registry.js.map +1 -0
  26. package/dist/tools/index.d.ts +5 -0
  27. package/dist/tools/index.d.ts.map +1 -0
  28. package/dist/tools/index.js +6 -0
  29. package/dist/tools/index.js.map +1 -0
  30. package/dist/tools/instagram.d.ts +9 -0
  31. package/dist/tools/instagram.d.ts.map +1 -0
  32. package/dist/tools/instagram.js +9 -0
  33. package/dist/tools/instagram.js.map +1 -0
  34. package/dist/tools/pages.d.ts +8 -0
  35. package/dist/tools/pages.d.ts.map +1 -0
  36. package/dist/tools/pages.js +8 -0
  37. package/dist/tools/pages.js.map +1 -0
  38. package/dist/tools/system.d.ts +7 -0
  39. package/dist/tools/system.d.ts.map +1 -0
  40. package/dist/tools/system.js +7 -0
  41. package/dist/tools/system.js.map +1 -0
  42. package/dist/tools/user.d.ts +105 -0
  43. package/dist/tools/user.d.ts.map +1 -0
  44. package/dist/tools/user.js +139 -0
  45. package/dist/tools/user.js.map +1 -0
  46. package/dist/types.d.ts +111 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +5 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +46 -0
  51. package/tools.json +108 -0
package/README.md ADDED
@@ -0,0 +1,245 @@
1
+ # Facebook MCP Server
2
+
3
+ A stateless Model Context Protocol (MCP) server for Facebook Graph API integration with user profile, social data, and content access capabilities.
4
+
5
+ ## Features
6
+
7
+ - **7 User Data Tools**: Access to Facebook user profile and social data
8
+ - **Page-Based Pagination**: Navigate through data using page numbers (page 1, 2, 3...)
9
+ - **Enhanced Descriptions**: LLM-friendly parameter descriptions for better tool usage
10
+ - **Stateless Architecture**: Each request is independent with no session management
11
+ - **Bearer Token Auth**: Per-request authentication via Authorization header
12
+ - **Facebook Graph API v22.0**: Latest stable API version
13
+
14
+ ## Quick Start
15
+
16
+ ### Prerequisites
17
+
18
+ - Node.js 18+
19
+ - pnpm (recommended) or npm
20
+ - Facebook Access Token with appropriate scopes
21
+
22
+ ### Installation
23
+
24
+ ```bash
25
+ # Install dependencies
26
+ pnpm install
27
+
28
+ # Build TypeScript
29
+ pnpm run build
30
+
31
+ # Start production server
32
+ pnpm start
33
+
34
+ # Start development server with hot reload
35
+ pnpm run dev
36
+ ```
37
+
38
+ ### Docker
39
+
40
+ ```bash
41
+ # Build image
42
+ docker build -t facebook-mcp-server .
43
+
44
+ # Run container
45
+ docker run -p 30003:30003 facebook-mcp-server
46
+ ```
47
+
48
+ ### Endpoints
49
+
50
+ - **`POST /mcp`** - Main MCP endpoint for tool execution
51
+ - **`GET /health`** - Health check endpoint
52
+
53
+ Default port: **30003**
54
+
55
+ ### Authentication
56
+
57
+ All requests require a Facebook Access Token via Authorization header:
58
+
59
+ ```bash
60
+ Authorization: Bearer <facebook-access-token>
61
+ ```
62
+
63
+ [Create a Facebook App](https://developers.facebook.com/apps) and get a User Access Token with these scopes:
64
+ - `public_profile` - Basic profile info (always granted)
65
+ - `email` - User's email address
66
+ - `user_friends` - Friends who also use the app
67
+ - `user_photos` - User's uploaded photos
68
+ - `user_posts` - User's timeline posts
69
+ - `user_videos` - User's uploaded videos
70
+ - `user_likes` - Pages/things the user has liked
71
+
72
+ **Note:** Only `public_profile` and `email` are available without Facebook App Review. Other scopes require approval.
73
+
74
+ ## Tools (7 total)
75
+
76
+ ### User Tools (7)
77
+
78
+ | Tool | Description | Required Scope |
79
+ |------|-------------|----------------|
80
+ | `get_me` | Get current user's profile information | `public_profile` |
81
+ | `get_friends` | Get user's friends who also use the app | `user_friends` |
82
+ | `get_photos` | Get user's uploaded photos | `user_photos` |
83
+ | `get_user_posts` | Get user's timeline posts | `user_posts` |
84
+ | `get_videos` | Get user's uploaded videos | `user_videos` |
85
+ | `get_likes` | Get pages/things the user has liked | `user_likes` |
86
+ | `get_permissions` | Get permissions granted to the access token | `public_profile` |
87
+
88
+ ## Usage Examples
89
+
90
+ ### Get user profile
91
+
92
+ ```bash
93
+ curl -X POST http://localhost:30003/mcp \
94
+ -H "Content-Type: application/json" \
95
+ -H "Accept: application/json, text/event-stream" \
96
+ -H "Authorization: Bearer <facebook-access-token>" \
97
+ -d '{
98
+ "jsonrpc": "2.0",
99
+ "id": "1",
100
+ "method": "tools/call",
101
+ "params": {
102
+ "name": "get_me",
103
+ "arguments": {}
104
+ }
105
+ }'
106
+ ```
107
+
108
+ ### Get user's posts
109
+
110
+ ```bash
111
+ curl -X POST http://localhost:30003/mcp \
112
+ -H "Content-Type: application/json" \
113
+ -H "Accept: application/json, text/event-stream" \
114
+ -H "Authorization: Bearer <facebook-access-token>" \
115
+ -d '{
116
+ "jsonrpc": "2.0",
117
+ "id": "2",
118
+ "method": "tools/call",
119
+ "params": {
120
+ "name": "get_user_posts",
121
+ "arguments": {
122
+ "limit": 10
123
+ }
124
+ }
125
+ }'
126
+ ```
127
+
128
+ ### Pagination example
129
+
130
+ The following tools support pagination: `get_friends`, `get_photos`, `get_user_posts`, `get_videos`, `get_likes`
131
+
132
+ ```bash
133
+ # Page 1 (first 25 posts)
134
+ curl -X POST http://localhost:30003/mcp \
135
+ -H "Content-Type: application/json" \
136
+ -H "Accept: application/json, text/event-stream" \
137
+ -H "Authorization: Bearer <facebook-access-token>" \
138
+ -d '{
139
+ "jsonrpc": "2.0",
140
+ "id": "1",
141
+ "method": "tools/call",
142
+ "params": {
143
+ "name": "get_user_posts",
144
+ "arguments": {
145
+ "page": 1,
146
+ "limit": 25
147
+ }
148
+ }
149
+ }'
150
+
151
+ # Response includes pagination info:
152
+ # {
153
+ # "success": true,
154
+ # "posts": [...],
155
+ # "pagination": {
156
+ # "page": 1,
157
+ # "limit": 25,
158
+ # "total": 150,
159
+ # "pages": 6,
160
+ # "hasNext": true,
161
+ # "hasPrev": false
162
+ # }
163
+ # }
164
+
165
+ # Page 2 (posts 26-50)
166
+ curl -X POST http://localhost:30003/mcp \
167
+ -H "Content-Type: application/json" \
168
+ -H "Accept: application/json, text/event-stream" \
169
+ -H "Authorization: Bearer <facebook-access-token>" \
170
+ -d '{
171
+ "jsonrpc": "2.0",
172
+ "id": "2",
173
+ "method": "tools/call",
174
+ "params": {
175
+ "name": "get_user_posts",
176
+ "arguments": {
177
+ "page": 2,
178
+ "limit": 25
179
+ }
180
+ }
181
+ }'
182
+
183
+ # Jump to page 5 (posts 101-125)
184
+ curl -X POST http://localhost:30003/mcp \
185
+ -H "Content-Type: application/json" \
186
+ -H "Accept: application/json, text/event-stream" \
187
+ -H "Authorization: Bearer <facebook-access-token>" \
188
+ -d '{
189
+ "jsonrpc": "2.0",
190
+ "id": "3",
191
+ "method": "tools/call",
192
+ "params": {
193
+ "name": "get_user_posts",
194
+ "arguments": {
195
+ "page": 5,
196
+ "limit": 25
197
+ }
198
+ }
199
+ }'
200
+ ```
201
+
202
+ ### Check token permissions
203
+
204
+ ```bash
205
+ curl -X POST http://localhost:30003/mcp \
206
+ -H "Content-Type: application/json" \
207
+ -H "Accept: application/json, text/event-stream" \
208
+ -H "Authorization: Bearer <facebook-access-token>" \
209
+ -d '{
210
+ "jsonrpc": "2.0",
211
+ "id": "3",
212
+ "method": "tools/call",
213
+ "params": {
214
+ "name": "get_permissions",
215
+ "arguments": {}
216
+ }
217
+ }'
218
+ ```
219
+
220
+ ## Environment Variables
221
+
222
+ | Variable | Description | Default |
223
+ |----------|-------------|---------|
224
+ | `PORT` | Server port | 30003 |
225
+ | `DEBUG` | Enable debug output | false |
226
+
227
+ ## Development
228
+
229
+ ```bash
230
+ # Run with hot reload
231
+ pnpm run dev
232
+
233
+ # Run with debug logging
234
+ DEBUG=true pnpm run dev
235
+
236
+ # Type check
237
+ pnpm run build
238
+
239
+ # Run tests
240
+ pnpm test
241
+ ```
242
+
243
+ ## License
244
+
245
+ PROPRIETARY - BlueNexus AI
@@ -0,0 +1,12 @@
1
+ import type { ToolResponse } from "./types.js";
2
+ export declare const DEBUG_MODE: boolean;
3
+ /**
4
+ * Wraps a tool execution with debug metadata when DEBUG mode is enabled.
5
+ *
6
+ * @param toolName - Name of the tool being executed
7
+ * @param toolInput - Input arguments passed to the tool
8
+ * @param executeToolFn - Async function that executes the tool and returns data
9
+ * @returns ToolResponse with data and optional debug metadata
10
+ */
11
+ export declare function wrapWithDebug<T>(toolName: string, toolInput: unknown, executeToolFn: () => Promise<T>): Promise<ToolResponse<T>>;
12
+ //# sourceMappingURL=debug-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-middleware.d.ts","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAA;AAG7D,eAAO,MAAM,UAAU,SAA+B,CAAA;AAEtD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA0B1B"}
@@ -0,0 +1,36 @@
1
+ // Check if DEBUG mode is enabled via environment variable
2
+ export const DEBUG_MODE = process.env.DEBUG === "true";
3
+ /**
4
+ * Wraps a tool execution with debug metadata when DEBUG mode is enabled.
5
+ *
6
+ * @param toolName - Name of the tool being executed
7
+ * @param toolInput - Input arguments passed to the tool
8
+ * @param executeToolFn - Async function that executes the tool and returns data
9
+ * @returns ToolResponse with data and optional debug metadata
10
+ */
11
+ export async function wrapWithDebug(toolName, toolInput, executeToolFn) {
12
+ const startTime = performance.now();
13
+ try {
14
+ const data = await executeToolFn();
15
+ const endTime = performance.now();
16
+ const toolCallTime = endTime - startTime;
17
+ if (DEBUG_MODE) {
18
+ return {
19
+ data,
20
+ debug: {
21
+ toolName,
22
+ toolInput,
23
+ toolCallTime,
24
+ timestamp: new Date().toISOString(),
25
+ },
26
+ };
27
+ }
28
+ // In non-debug mode, return just the data wrapped
29
+ return { data };
30
+ }
31
+ catch (error) {
32
+ // Re-throw the error to be handled by caller
33
+ throw error;
34
+ }
35
+ }
36
+ //# sourceMappingURL=debug-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-middleware.js","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAA;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,SAAkB,EAClB,aAA+B;IAE/B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;IAEnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAA;QAClC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QACjC,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAA;QAExC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE;oBACL,QAAQ;oBACR,SAAS;oBACT,YAAY;oBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF,CAAA;QACH,CAAC;QAED,kDAAkD;QAClD,OAAO,EAAE,IAAI,EAAE,CAAA;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6CAA6C;QAC7C,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Facebook Graph API Client
3
+ *
4
+ * Stateless HTTP client for Facebook Graph API with Bearer token authentication.
5
+ * Extracts token from Express request headers for per-request auth.
6
+ */
7
+ import type { Request } from "express";
8
+ import type { FacebookUser, FacebookPost, PaginatedResponse } from "./types.js";
9
+ /**
10
+ * Extract Bearer token from request Authorization header
11
+ */
12
+ export declare function getTokenFromRequest(req: Request): string;
13
+ /**
14
+ * Facebook/Instagram Graph API client class
15
+ */
16
+ export declare class FacebookClient {
17
+ private token;
18
+ private headers;
19
+ constructor(token: string);
20
+ /**
21
+ * Make GET request to Graph API
22
+ */
23
+ makeRequest<T = unknown>(endpoint: string, params?: Record<string, string | number | boolean>): Promise<T>;
24
+ /**
25
+ * Make POST request to Graph API
26
+ */
27
+ postRequest<T = unknown>(endpoint: string, body?: Record<string, unknown>): Promise<T>;
28
+ /**
29
+ * Get current user profile
30
+ */
31
+ getMe(fields?: string): Promise<FacebookUser>;
32
+ /**
33
+ * Get user permissions
34
+ */
35
+ getPermissions(): Promise<Array<{
36
+ permission: string;
37
+ status: string;
38
+ }>>;
39
+ /**
40
+ * Get user's friends (requires user_friends permission)
41
+ */
42
+ getFriends(page?: number, limit?: number, fields?: string): Promise<PaginatedResponse<{
43
+ id: string;
44
+ name: string;
45
+ picture?: unknown;
46
+ }>>;
47
+ /**
48
+ * Get user's photos (requires user_photos permission)
49
+ */
50
+ getPhotos(page?: number, limit?: number, fields?: string): Promise<PaginatedResponse<unknown>>;
51
+ /**
52
+ * Get user's posts (requires user_posts permission)
53
+ */
54
+ getPosts(page?: number, limit?: number, fields?: string): Promise<PaginatedResponse<FacebookPost>>;
55
+ /**
56
+ * Get user's videos (requires user_videos permission)
57
+ */
58
+ getVideos(page?: number, limit?: number, fields?: string): Promise<PaginatedResponse<unknown>>;
59
+ /**
60
+ * Get user's likes (requires user_likes permission)
61
+ */
62
+ getLikes(page?: number, limit?: number, fields?: string): Promise<PaginatedResponse<unknown>>;
63
+ }
64
+ /**
65
+ * Get Facebook client from Express request
66
+ */
67
+ export declare function getFacebookClient(req: Request): FacebookClient;
68
+ //# sourceMappingURL=facebook-api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facebook-api-client.d.ts","sourceRoot":"","sources":["../src/facebook-api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EAElB,MAAM,YAAY,CAAA;AAKnB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAQxD;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAwB;gBAE3B,KAAK,EAAE,MAAM;IAQzB;;OAEG;IACG,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAM,GACrD,OAAO,CAAC,CAAC,CAAC;IA6Bb;;OAEG;IACG,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC;IAyBb;;OAEG;IACG,KAAK,CACT,MAAM,SAAsE,GAC3E,OAAO,CAAC,YAAY,CAAC;IAIxB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAO9E;;OAEG;IACG,UAAU,CACd,IAAI,SAAI,EACR,KAAK,SAAK,EACV,MAAM,SAAoB,GACzB,OAAO,CAAC,iBAAiB,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IA2B9E;;OAEG;IACG,SAAS,CACb,IAAI,SAAI,EACR,KAAK,SAAK,EACV,MAAM,SAA6C,GAClD,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IA4BtC;;OAEG;IACG,QAAQ,CACZ,IAAI,SAAI,EACR,KAAK,SAAK,EACV,MAAM,SAA+G,GACpH,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IA4B3C;;OAEG;IACG,SAAS,CACb,IAAI,SAAI,EACR,KAAK,SAAK,EACV,MAAM,SAAsE,GAC3E,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IA4BtC;;OAEG;IACG,QAAQ,CACZ,IAAI,SAAI,EACR,KAAK,SAAK,EACV,MAAM,SAAuC,GAC5C,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;CA4BvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAG9D"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Facebook Graph API Client
3
+ *
4
+ * Stateless HTTP client for Facebook Graph API with Bearer token authentication.
5
+ * Extracts token from Express request headers for per-request auth.
6
+ */
7
+ const GRAPH_API_VERSION = "v22.0";
8
+ const GRAPH_API_BASE = `https://graph.facebook.com/${GRAPH_API_VERSION}`;
9
+ /**
10
+ * Extract Bearer token from request Authorization header
11
+ */
12
+ export function getTokenFromRequest(req) {
13
+ const authHeader = req.headers.authorization;
14
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
15
+ throw new Error("Authentication required. Please provide Authorization: Bearer <token> header");
16
+ }
17
+ return authHeader.slice(7);
18
+ }
19
+ /**
20
+ * Facebook/Instagram Graph API client class
21
+ */
22
+ export class FacebookClient {
23
+ token;
24
+ headers;
25
+ constructor(token) {
26
+ this.token = token;
27
+ this.headers = {
28
+ Authorization: `Bearer ${token}`,
29
+ "Content-Type": "application/json",
30
+ };
31
+ }
32
+ /**
33
+ * Make GET request to Graph API
34
+ */
35
+ async makeRequest(endpoint, params = {}) {
36
+ const url = new URL(`${GRAPH_API_BASE}/${endpoint}`);
37
+ // Add query parameters
38
+ for (const [key, value] of Object.entries(params)) {
39
+ if (value !== undefined && value !== null) {
40
+ url.searchParams.append(key, String(value));
41
+ }
42
+ }
43
+ // Add access token
44
+ url.searchParams.append("access_token", this.token);
45
+ const response = await fetch(url.toString(), {
46
+ method: "GET",
47
+ headers: this.headers,
48
+ });
49
+ const data = (await response.json());
50
+ if (data.error) {
51
+ throw new Error(`Facebook Graph API error: ${data.error.message} (code: ${data.error.code})`);
52
+ }
53
+ return data;
54
+ }
55
+ /**
56
+ * Make POST request to Graph API
57
+ */
58
+ async postRequest(endpoint, body = {}) {
59
+ const url = new URL(`${GRAPH_API_BASE}/${endpoint}`);
60
+ url.searchParams.append("access_token", this.token);
61
+ const response = await fetch(url.toString(), {
62
+ method: "POST",
63
+ headers: this.headers,
64
+ body: JSON.stringify(body),
65
+ });
66
+ const data = (await response.json());
67
+ if (data.error) {
68
+ throw new Error(`Facebook Graph API error: ${data.error.message} (code: ${data.error.code})`);
69
+ }
70
+ return data;
71
+ }
72
+ // ============================================================================
73
+ // Facebook User Methods
74
+ // ============================================================================
75
+ /**
76
+ * Get current user profile
77
+ */
78
+ async getMe(fields = "id,name,email,first_name,last_name,picture.width(200).height(200)") {
79
+ return this.makeRequest("me", { fields });
80
+ }
81
+ /**
82
+ * Get user permissions
83
+ */
84
+ async getPermissions() {
85
+ const result = await this.makeRequest("me/permissions");
86
+ return result.data || [];
87
+ }
88
+ /**
89
+ * Get user's friends (requires user_friends permission)
90
+ */
91
+ async getFriends(page = 1, limit = 25, fields = "id,name,picture") {
92
+ const offset = (page - 1) * limit;
93
+ const params = { fields, limit, offset };
94
+ const result = await this.makeRequest("me/friends", params);
95
+ const data = result.data || [];
96
+ const hasNext = !!result.paging?.next || !!result.paging?.cursors?.after;
97
+ // Facebook doesn't provide total count, so we estimate based on current data
98
+ const total = hasNext ? offset + data.length + 1 : offset + data.length;
99
+ const pages = Math.ceil(total / limit);
100
+ const pagination = {
101
+ page,
102
+ limit,
103
+ total,
104
+ pages,
105
+ hasNext,
106
+ hasPrev: page > 1,
107
+ };
108
+ return { data, pagination };
109
+ }
110
+ /**
111
+ * Get user's photos (requires user_photos permission)
112
+ */
113
+ async getPhotos(page = 1, limit = 25, fields = "id,name,picture,created_time,link,images") {
114
+ const offset = (page - 1) * limit;
115
+ const params = { fields, limit, offset };
116
+ const result = await this.makeRequest("me/photos", params);
117
+ const data = result.data || [];
118
+ const hasNext = !!result.paging?.next || !!result.paging?.cursors?.after;
119
+ // Facebook doesn't provide total count, so we estimate based on current data
120
+ const total = hasNext ? offset + data.length + 1 : offset + data.length;
121
+ const pages = Math.ceil(total / limit);
122
+ const pagination = {
123
+ page,
124
+ limit,
125
+ total,
126
+ pages,
127
+ hasNext,
128
+ hasPrev: page > 1,
129
+ };
130
+ return { data, pagination };
131
+ }
132
+ /**
133
+ * Get user's posts (requires user_posts permission)
134
+ */
135
+ async getPosts(page = 1, limit = 25, fields = "id,message,story,created_time,full_picture,permalink_url,shares,likes.summary(true),comments.summary(true)") {
136
+ const offset = (page - 1) * limit;
137
+ const params = { fields, limit, offset };
138
+ const result = await this.makeRequest("me/posts", params);
139
+ const data = result.data || [];
140
+ const hasNext = !!result.paging?.next || !!result.paging?.cursors?.after;
141
+ // Facebook doesn't provide total count, so we estimate based on current data
142
+ const total = hasNext ? offset + data.length + 1 : offset + data.length;
143
+ const pages = Math.ceil(total / limit);
144
+ const pagination = {
145
+ page,
146
+ limit,
147
+ total,
148
+ pages,
149
+ hasNext,
150
+ hasPrev: page > 1,
151
+ };
152
+ return { data, pagination };
153
+ }
154
+ /**
155
+ * Get user's videos (requires user_videos permission)
156
+ */
157
+ async getVideos(page = 1, limit = 25, fields = "id,title,description,created_time,permalink_url,thumbnails,length") {
158
+ const offset = (page - 1) * limit;
159
+ const params = { fields, limit, offset };
160
+ const result = await this.makeRequest("me/videos", params);
161
+ const data = result.data || [];
162
+ const hasNext = !!result.paging?.next || !!result.paging?.cursors?.after;
163
+ // Facebook doesn't provide total count, so we estimate based on current data
164
+ const total = hasNext ? offset + data.length + 1 : offset + data.length;
165
+ const pages = Math.ceil(total / limit);
166
+ const pagination = {
167
+ page,
168
+ limit,
169
+ total,
170
+ pages,
171
+ hasNext,
172
+ hasPrev: page > 1,
173
+ };
174
+ return { data, pagination };
175
+ }
176
+ /**
177
+ * Get user's likes (requires user_likes permission)
178
+ */
179
+ async getLikes(page = 1, limit = 25, fields = "id,name,category,picture,fan_count") {
180
+ const offset = (page - 1) * limit;
181
+ const params = { fields, limit, offset };
182
+ const result = await this.makeRequest("me/likes", params);
183
+ const data = result.data || [];
184
+ const hasNext = !!result.paging?.next || !!result.paging?.cursors?.after;
185
+ // Facebook doesn't provide total count, so we estimate based on current data
186
+ const total = hasNext ? offset + data.length + 1 : offset + data.length;
187
+ const pages = Math.ceil(total / limit);
188
+ const pagination = {
189
+ page,
190
+ limit,
191
+ total,
192
+ pages,
193
+ hasNext,
194
+ hasPrev: page > 1,
195
+ };
196
+ return { data, pagination };
197
+ }
198
+ }
199
+ /**
200
+ * Get Facebook client from Express request
201
+ */
202
+ export function getFacebookClient(req) {
203
+ const token = getTokenFromRequest(req);
204
+ return new FacebookClient(token);
205
+ }
206
+ //# sourceMappingURL=facebook-api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facebook-api-client.js","sourceRoot":"","sources":["../src/facebook-api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Facebook MCP Server
4
+ *
5
+ * A stateless Model Context Protocol server for Facebook Graph API
6
+ * using Bearer token authentication.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}