postfast-mcp 0.1.24 → 0.2.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 (61) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +7 -1
  4. package/dist/core/backend-port.d.ts +97 -0
  5. package/dist/core/backend-port.js +2 -0
  6. package/dist/core/backend-port.js.map +1 -0
  7. package/dist/core/build-tools.d.ts +32 -0
  8. package/dist/core/build-tools.js +73 -0
  9. package/dist/core/build-tools.js.map +1 -0
  10. package/dist/core/index.d.ts +12 -0
  11. package/dist/core/index.js +12 -0
  12. package/dist/core/index.js.map +1 -0
  13. package/dist/core/instructions.d.ts +3 -0
  14. package/dist/core/instructions.js +63 -0
  15. package/dist/core/instructions.js.map +1 -0
  16. package/dist/core/shared.d.ts +21 -0
  17. package/dist/core/shared.js +58 -0
  18. package/dist/core/shared.js.map +1 -0
  19. package/dist/core/tool-def.d.ts +47 -0
  20. package/dist/core/tool-def.js +2 -0
  21. package/dist/core/tool-def.js.map +1 -0
  22. package/dist/core/tools/accounts.d.ts +2 -0
  23. package/dist/core/tools/accounts.js +112 -0
  24. package/dist/core/tools/accounts.js.map +1 -0
  25. package/dist/core/tools/index.d.ts +7 -0
  26. package/dist/core/tools/index.js +16 -0
  27. package/dist/core/tools/index.js.map +1 -0
  28. package/dist/core/tools/posts.d.ts +2 -0
  29. package/dist/core/tools/posts.js +264 -0
  30. package/dist/core/tools/posts.js.map +1 -0
  31. package/dist/core/tools/uploads.d.ts +8 -0
  32. package/dist/core/tools/uploads.js +102 -0
  33. package/dist/core/tools/uploads.js.map +1 -0
  34. package/dist/core/tools/workspaces.d.ts +2 -0
  35. package/dist/core/tools/workspaces.js +15 -0
  36. package/dist/core/tools/workspaces.js.map +1 -0
  37. package/dist/core/types.js.map +1 -0
  38. package/dist/stdio/index.js +15 -0
  39. package/dist/stdio/index.js.map +1 -0
  40. package/dist/stdio/rest-adapter.d.ts +27 -0
  41. package/dist/stdio/rest-adapter.js +170 -0
  42. package/dist/stdio/rest-adapter.js.map +1 -0
  43. package/package.json +21 -7
  44. package/dist/client.d.ts +0 -9
  45. package/dist/client.js +0 -57
  46. package/dist/client.js.map +0 -1
  47. package/dist/index.js +0 -18
  48. package/dist/index.js.map +0 -1
  49. package/dist/tools/accounts.d.ts +0 -3
  50. package/dist/tools/accounts.js +0 -118
  51. package/dist/tools/accounts.js.map +0 -1
  52. package/dist/tools/files.d.ts +0 -3
  53. package/dist/tools/files.js +0 -87
  54. package/dist/tools/files.js.map +0 -1
  55. package/dist/tools/posts.d.ts +0 -3
  56. package/dist/tools/posts.js +0 -228
  57. package/dist/tools/posts.js.map +0 -1
  58. package/dist/types.js.map +0 -1
  59. /package/dist/{types.d.ts → core/types.d.ts} +0 -0
  60. /package/dist/{types.js → core/types.js} +0 -0
  61. /package/dist/{index.d.ts → stdio/index.d.ts} +0 -0
@@ -0,0 +1,170 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { extname } from 'node:path';
3
+ const DEFAULT_BASE_URL = 'https://api.postfa.st';
4
+ const MIME_MAP = {
5
+ '.jpg': 'image/jpeg',
6
+ '.jpeg': 'image/jpeg',
7
+ '.png': 'image/png',
8
+ '.gif': 'image/gif',
9
+ '.webp': 'image/webp',
10
+ '.mp4': 'video/mp4',
11
+ '.webm': 'video/webm',
12
+ '.mov': 'video/quicktime',
13
+ };
14
+ function detectContentType(filePath) {
15
+ const ext = extname(filePath).toLowerCase();
16
+ const mime = MIME_MAP[ext];
17
+ if (!mime) {
18
+ throw new Error(`Unsupported file extension "${ext}". Supported: ${Object.keys(MIME_MAP).join(', ')}`);
19
+ }
20
+ return mime;
21
+ }
22
+ /** The stdio bin's BackendPort: the public PostFast REST API over pf-api-key. */
23
+ export class RestAdapter {
24
+ baseUrl;
25
+ apiKey;
26
+ constructor() {
27
+ this.apiKey = process.env.POSTFAST_API_KEY ?? '';
28
+ this.baseUrl = (process.env.POSTFAST_API_URL ?? DEFAULT_BASE_URL).replace(/\/$/, '');
29
+ if (!this.apiKey) {
30
+ throw new Error('POSTFAST_API_KEY environment variable is required. Generate one in PostFast → Workspace Settings → API Key.');
31
+ }
32
+ }
33
+ async request(method, path, body, query) {
34
+ const url = new URL(`${this.baseUrl}${path}`);
35
+ if (query) {
36
+ for (const [key, value] of Object.entries(query)) {
37
+ if (value !== undefined && value !== '') {
38
+ url.searchParams.set(key, value);
39
+ }
40
+ }
41
+ }
42
+ const headers = {
43
+ 'pf-api-key': this.apiKey,
44
+ 'Content-Type': 'application/json',
45
+ };
46
+ const response = await fetch(url.toString(), {
47
+ method,
48
+ headers,
49
+ body: body ? JSON.stringify(body) : undefined,
50
+ });
51
+ if (!response.ok) {
52
+ const text = await response.text();
53
+ let message;
54
+ try {
55
+ const json = JSON.parse(text);
56
+ message = json.message ?? json.error ?? text;
57
+ }
58
+ catch {
59
+ message = text;
60
+ }
61
+ throw new Error(`PostFast API error (${response.status}): ${message}`);
62
+ }
63
+ const text = await response.text();
64
+ if (!text)
65
+ return undefined;
66
+ return JSON.parse(text);
67
+ }
68
+ get(path, query) {
69
+ return this.request('GET', path, undefined, query);
70
+ }
71
+ post(path, body) {
72
+ return this.request('POST', path, body);
73
+ }
74
+ listWorkspaces() {
75
+ throw new Error('list_workspaces is not available over the public REST API.');
76
+ }
77
+ listAccounts() {
78
+ return this.get('/social-media/my-social-accounts');
79
+ }
80
+ getFollowerHistory(args) {
81
+ return this.get(`/social-media/${args.socialMediaId}/follower-history`, {
82
+ from: args.from,
83
+ to: args.to,
84
+ });
85
+ }
86
+ listPinterestBoards(socialMediaId) {
87
+ return this.get(`/social-media/${socialMediaId}/pinterest-boards`);
88
+ }
89
+ listYoutubePlaylists(socialMediaId) {
90
+ return this.get(`/social-media/${socialMediaId}/youtube-playlists`);
91
+ }
92
+ listGbpLocations(socialMediaId) {
93
+ return this.get(`/social-media/${socialMediaId}/gbp-locations`);
94
+ }
95
+ searchPlaces(query) {
96
+ return this.get('/social-media/search-places', { q: query });
97
+ }
98
+ generateConnectLink(args) {
99
+ return this.post('/social-media/connect-link', {
100
+ expiryDays: args.expiryDays,
101
+ sendEmail: args.sendEmail,
102
+ email: args.email,
103
+ });
104
+ }
105
+ listPosts(args) {
106
+ return this.get('/social-posts', {
107
+ page: String(args.page),
108
+ limit: String(args.limit),
109
+ ids: args.ids?.join(','),
110
+ platforms: args.platforms?.join(','),
111
+ statuses: args.statuses?.join(','),
112
+ from: args.from,
113
+ to: args.to,
114
+ });
115
+ }
116
+ createPosts(args) {
117
+ return this.post('/social-posts', {
118
+ posts: args.posts,
119
+ status: args.status,
120
+ approvalStatus: args.approvalStatus,
121
+ controls: args.controls,
122
+ });
123
+ }
124
+ approvePosts(_args) {
125
+ throw new Error('approve_posts is not available over the public REST API.');
126
+ }
127
+ deletePost(id) {
128
+ return this.request('DELETE', `/social-posts/${id}`);
129
+ }
130
+ getPostAnalytics(args) {
131
+ return this.get('/social-posts/analytics', {
132
+ startDate: args.startDate,
133
+ endDate: args.endDate,
134
+ platforms: args.platforms?.join(','),
135
+ socialMediaIds: args.socialMediaIds?.join(','),
136
+ });
137
+ }
138
+ getUploadUrls(args) {
139
+ return this.post('/file/get-signed-upload-urls', {
140
+ contentType: args.contentType,
141
+ count: args.count,
142
+ });
143
+ }
144
+ async uploadLocalFile(filePath) {
145
+ const contentType = detectContentType(filePath);
146
+ const isVideo = contentType.startsWith('video/');
147
+ const [uploadUrl] = await this.post('/file/get-signed-upload-urls', { contentType, count: 1 });
148
+ const fileBuffer = await readFile(filePath);
149
+ const uploadResponse = await fetch(uploadUrl.signedUrl, {
150
+ method: 'PUT',
151
+ headers: { 'Content-Type': contentType },
152
+ body: fileBuffer,
153
+ });
154
+ if (!uploadResponse.ok) {
155
+ throw new Error(`Upload failed (${uploadResponse.status}): ${await uploadResponse.text()}`);
156
+ }
157
+ return {
158
+ key: uploadUrl.key,
159
+ type: isVideo ? 'VIDEO' : 'IMAGE',
160
+ contentType,
161
+ };
162
+ }
163
+ uploadFromUrl() {
164
+ throw new Error('upload_from_url is only available on the hosted PostFast MCP server.');
165
+ }
166
+ uploadMedia() {
167
+ throw new Error('Conversation-media upload is only available on the hosted PostFast MCP server.');
168
+ }
169
+ }
170
+ //# sourceMappingURL=rest-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-adapter.js","sourceRoot":"","sources":["../../src/stdio/rest-adapter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  "name": "postfast-mcp",
3
- "version": "0.1.24",
3
+ "version": "0.2.0",
4
4
  "mcpName": "io.github.peturgeorgievv-factory/postfast-mcp",
5
5
  "description": "MCP server for the PostFast API — schedule and manage social media posts via AI tools",
6
6
  "type": "module",
7
7
  "bin": {
8
- "postfast-mcp": "dist/index.js"
8
+ "postfast-mcp": "dist/stdio/index.js"
9
+ },
10
+ "main": "./dist/stdio/index.js",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/stdio/index.d.ts",
14
+ "default": "./dist/stdio/index.js"
15
+ },
16
+ "./core": {
17
+ "types": "./dist/core/index.d.ts",
18
+ "default": "./dist/core/index.js"
19
+ }
9
20
  },
10
- "main": "./dist/index.js",
11
21
  "files": [
12
22
  "dist",
13
23
  ".claude-plugin",
@@ -17,7 +27,9 @@
17
27
  "scripts": {
18
28
  "build": "tsc",
19
29
  "dev": "tsc --watch",
20
- "start": "node dist/index.js",
30
+ "start": "node dist/stdio/index.js",
31
+ "version": "changeset version && node scripts/stamp-versions.mjs",
32
+ "release": "npm run build && changeset publish",
21
33
  "prepublishOnly": "npm run build"
22
34
  },
23
35
  "keywords": [
@@ -39,10 +51,12 @@
39
51
  "node": ">=18"
40
52
  },
41
53
  "dependencies": {
42
- "@modelcontextprotocol/sdk": "^1.29.0"
54
+ "@modelcontextprotocol/sdk": "^1.29.0",
55
+ "zod": "^4.4.3"
43
56
  },
44
57
  "devDependencies": {
45
- "typescript": "^5.9.3",
46
- "@types/node": "^22.19.21"
58
+ "@changesets/cli": "^2.29.8",
59
+ "@types/node": "^22.19.21",
60
+ "typescript": "^5.9.3"
47
61
  }
48
62
  }
package/dist/client.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare class PostFastClient {
2
- private baseUrl;
3
- private apiKey;
4
- constructor();
5
- request<T>(method: string, path: string, body?: unknown, query?: Record<string, string | undefined>): Promise<T>;
6
- get<T>(path: string, query?: Record<string, string | undefined>): Promise<T>;
7
- post<T>(path: string, body?: unknown): Promise<T>;
8
- delete<T>(path: string): Promise<T>;
9
- }
package/dist/client.js DELETED
@@ -1,57 +0,0 @@
1
- const DEFAULT_BASE_URL = 'https://api.postfa.st';
2
- export class PostFastClient {
3
- baseUrl;
4
- apiKey;
5
- constructor() {
6
- this.apiKey = process.env.POSTFAST_API_KEY ?? '';
7
- this.baseUrl = (process.env.POSTFAST_API_URL ?? DEFAULT_BASE_URL).replace(/\/$/, '');
8
- if (!this.apiKey) {
9
- throw new Error('POSTFAST_API_KEY environment variable is required. Generate one in PostFast → Workspace Settings → API Key.');
10
- }
11
- }
12
- async request(method, path, body, query) {
13
- const url = new URL(`${this.baseUrl}${path}`);
14
- if (query) {
15
- for (const [key, value] of Object.entries(query)) {
16
- if (value !== undefined && value !== '') {
17
- url.searchParams.set(key, value);
18
- }
19
- }
20
- }
21
- const headers = {
22
- 'pf-api-key': this.apiKey,
23
- 'Content-Type': 'application/json',
24
- };
25
- const response = await fetch(url.toString(), {
26
- method,
27
- headers,
28
- body: body ? JSON.stringify(body) : undefined,
29
- });
30
- if (!response.ok) {
31
- const text = await response.text();
32
- let message;
33
- try {
34
- const json = JSON.parse(text);
35
- message = json.message ?? json.error ?? text;
36
- }
37
- catch {
38
- message = text;
39
- }
40
- throw new Error(`PostFast API error (${response.status}): ${message}`);
41
- }
42
- const text = await response.text();
43
- if (!text)
44
- return undefined;
45
- return JSON.parse(text);
46
- }
47
- get(path, query) {
48
- return this.request('GET', path, undefined, query);
49
- }
50
- post(path, body) {
51
- return this.request('POST', path, body);
52
- }
53
- delete(path) {
54
- return this.request('DELETE', path);
55
- }
56
- }
57
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD,MAAM,OAAO,cAAc;IACjB,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB;QACE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,OAAO,CACvE,KAAK,EACL,EAAE,CACH,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,6GAA6G,CAC9G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CACX,MAAc,EACd,IAAY,EACZ,IAAc,EACd,KAA0C;QAE1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC,CAAC;QAE9C,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;oBACxC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAA2B;YACtC,YAAY,EAAE,IAAI,CAAC,MAAM;YACzB,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,OAAe,CAAC;YAEpB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAc,CAAC;QAEjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAED,GAAG,CAAI,IAAY,EAAE,KAA0C;QAC7D,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAI,IAAY,EAAE,IAAc;QAClC,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAI,IAAY;QACpB,OAAO,IAAI,CAAC,OAAO,CAAI,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;CACF"}
package/dist/index.js DELETED
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { PostFastClient } from './client.js';
5
- import { registerPostTools } from './tools/posts.js';
6
- import { registerAccountTools } from './tools/accounts.js';
7
- import { registerFileTools } from './tools/files.js';
8
- const server = new McpServer({
9
- name: 'postfast',
10
- version: '0.1.24',
11
- });
12
- const client = new PostFastClient();
13
- registerPostTools(server, client);
14
- registerAccountTools(server, client);
15
- registerFileTools(server, client);
16
- const transport = new StdioServerTransport();
17
- await server.connect(transport);
18
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,QAAQ;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;AAEpC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { PostFastClient } from '../client.js';
3
- export declare function registerAccountTools(server: McpServer, client: PostFastClient): void;
@@ -1,118 +0,0 @@
1
- import { z } from 'zod';
2
- export function registerAccountTools(server, client) {
3
- server.registerTool('list_accounts', {
4
- description: 'List all social media accounts connected to the workspace. Each account includes connectionStatus (CONNECTED or DISABLED) and disabledReason (null unless DISABLED), plus followerCount (latest stored snapshot, a string; absent for platforms without follower data), followerCountUpdatedAt, and inboxCapable (whether the account can appear in the social inbox, i.e. comment ingestion is supported). If connectionStatus is DISABLED, the account will not publish until the user reconnects it. For a follower trend over time, use get_follower_history.',
5
- inputSchema: {},
6
- }, async () => {
7
- const data = await client.get('/social-media/my-social-accounts');
8
- return {
9
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
10
- };
11
- });
12
- server.registerTool('list_pinterest_boards', {
13
- description: 'List Pinterest boards for a connected Pinterest account',
14
- inputSchema: {
15
- socialMediaId: z
16
- .uuid()
17
- .describe('Pinterest account ID (from list_accounts)'),
18
- },
19
- }, async (input) => {
20
- const data = await client.get(`/social-media/${input.socialMediaId}/pinterest-boards`);
21
- return {
22
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
23
- };
24
- });
25
- server.registerTool('list_youtube_playlists', {
26
- description: 'List YouTube playlists for a connected YouTube account',
27
- inputSchema: {
28
- socialMediaId: z
29
- .uuid()
30
- .describe('YouTube account ID (from list_accounts)'),
31
- },
32
- }, async (input) => {
33
- const data = await client.get(`/social-media/${input.socialMediaId}/youtube-playlists`);
34
- return {
35
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
36
- };
37
- });
38
- server.registerTool('list_gbp_locations', {
39
- description: 'List Google Business Profile locations for a connected GBP account',
40
- inputSchema: {
41
- socialMediaId: z
42
- .uuid()
43
- .describe('GBP account ID (from list_accounts)'),
44
- },
45
- }, async (input) => {
46
- const data = await client.get(`/social-media/${input.socialMediaId}/gbp-locations`);
47
- return {
48
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
49
- };
50
- });
51
- server.registerTool('get_follower_history', {
52
- description: 'Daily follower-count snapshots for a connected account, plus the current count (currentFollowerCount) and the net change (delta) over the range. Date range via from/to (ISO 8601); defaults to the last 90 days, capped at 365. Tracking is forward-only: data starts at trackingStartedAt (when PostFast began recording this account), with no snapshots before then. All counts are strings (bigint); currentFollowerCount, delta, and trackingStartedAt may be absent until the account has its first snapshot. Coverage: Facebook Pages, Instagram, YouTube, Pinterest, Threads, Bluesky, Telegram, LinkedIn company pages, and TikTok. Not available: X, personal Facebook.',
53
- inputSchema: {
54
- socialMediaId: z
55
- .uuid()
56
- .describe('Account ID (from list_accounts)'),
57
- from: z
58
- .string()
59
- .optional()
60
- .describe('Range start (ISO 8601, e.g. 2026-03-01T00:00:00.000Z). Defaults to 90 days ago.'),
61
- to: z
62
- .string()
63
- .optional()
64
- .describe('Range end (ISO 8601). Defaults to now. Range is capped at 365 days.'),
65
- },
66
- }, async (input) => {
67
- const data = await client.get(`/social-media/${input.socialMediaId}/follower-history`, { from: input.from, to: input.to });
68
- return {
69
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
70
- };
71
- });
72
- server.registerTool('search_places', {
73
- description: 'Find a place to tag. The returned id works for both facebookPlaceId and instagramLocationId.',
74
- inputSchema: {
75
- query: z
76
- .string()
77
- .min(2)
78
- .describe('Place name to search, e.g. "Eiffel Tower"'),
79
- },
80
- }, async (input) => {
81
- const data = await client.get('/social-media/search-places', {
82
- q: input.query,
83
- });
84
- return {
85
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
86
- };
87
- });
88
- server.registerTool('generate_connect_link', {
89
- description: 'Generate a shareable link for external clients to connect their social accounts to the workspace',
90
- inputSchema: {
91
- expiryDays: z
92
- .number()
93
- .int()
94
- .min(1)
95
- .max(30)
96
- .default(7)
97
- .describe('Link expiry in days (1-30, default 7)'),
98
- sendEmail: z
99
- .boolean()
100
- .default(false)
101
- .describe('Send the link via email'),
102
- email: z
103
- .email()
104
- .optional()
105
- .describe('Recipient email (required if sendEmail is true)'),
106
- },
107
- }, async (input) => {
108
- const data = await client.post('/social-media/connect-link', {
109
- expiryDays: input.expiryDays,
110
- sendEmail: input.sendEmail,
111
- email: input.email,
112
- });
113
- return {
114
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
115
- };
116
- });
117
- }
118
- //# sourceMappingURL=accounts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { PostFastClient } from '../client.js';
3
- export declare function registerFileTools(server: McpServer, client: PostFastClient): void;
@@ -1,87 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { extname } from 'node:path';
3
- import { z } from 'zod';
4
- const MIME_MAP = {
5
- '.jpg': 'image/jpeg',
6
- '.jpeg': 'image/jpeg',
7
- '.png': 'image/png',
8
- '.gif': 'image/gif',
9
- '.webp': 'image/webp',
10
- '.mp4': 'video/mp4',
11
- '.webm': 'video/webm',
12
- '.mov': 'video/quicktime',
13
- };
14
- const IMAGE_TYPES = [
15
- 'image/jpeg',
16
- 'image/png',
17
- 'image/gif',
18
- 'image/webp',
19
- ];
20
- const VIDEO_TYPES = ['video/mp4', 'video/webm', 'video/quicktime'];
21
- function detectContentType(filePath) {
22
- const ext = extname(filePath).toLowerCase();
23
- const mime = MIME_MAP[ext];
24
- if (!mime) {
25
- throw new Error(`Unsupported file extension "${ext}". Supported: ${Object.keys(MIME_MAP).join(', ')}`);
26
- }
27
- return mime;
28
- }
29
- export function registerFileTools(server, client) {
30
- server.registerTool('get_upload_urls', {
31
- description: 'Get signed upload URLs for media files. Upload your file to the returned URL via PUT, then use the key in create_posts mediaItems.',
32
- inputSchema: {
33
- contentType: z
34
- .string()
35
- .describe(`MIME type of the file. Supported: ${[...IMAGE_TYPES, ...VIDEO_TYPES].join(', ')}`),
36
- count: z
37
- .number()
38
- .int()
39
- .min(1)
40
- .max(8)
41
- .default(1)
42
- .describe('Number of upload URLs (1-8 for images, 1 for videos)'),
43
- },
44
- }, async (input) => {
45
- const data = await client.post('/file/get-signed-upload-urls', {
46
- contentType: input.contentType,
47
- count: input.count,
48
- });
49
- return {
50
- content: [
51
- { type: 'text', text: JSON.stringify(data, null, 2) },
52
- ],
53
- };
54
- });
55
- server.registerTool('upload_media', {
56
- description: 'Upload a local file to PostFast and get back a media key for use in create_posts. Handles the full flow: detects content type, gets a signed URL, uploads the file, and returns the key and type.',
57
- inputSchema: {
58
- filePath: z
59
- .string()
60
- .describe('Absolute path to the local file (e.g. /Users/me/photo.jpg)'),
61
- },
62
- }, async (input) => {
63
- const contentType = detectContentType(input.filePath);
64
- const isVideo = contentType.startsWith('video/');
65
- const [uploadUrl] = await client.post('/file/get-signed-upload-urls', { contentType, count: 1 });
66
- const fileBuffer = await readFile(input.filePath);
67
- const uploadResponse = await fetch(uploadUrl.signedUrl, {
68
- method: 'PUT',
69
- headers: { 'Content-Type': contentType },
70
- body: fileBuffer,
71
- });
72
- if (!uploadResponse.ok) {
73
- throw new Error(`Upload failed (${uploadResponse.status}): ${await uploadResponse.text()}`);
74
- }
75
- const result = {
76
- key: uploadUrl.key,
77
- type: isVideo ? 'VIDEO' : 'IMAGE',
78
- contentType,
79
- };
80
- return {
81
- content: [
82
- { type: 'text', text: JSON.stringify(result, null, 2) },
83
- ],
84
- };
85
- });
86
- }
87
- //# sourceMappingURL=files.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/tools/files.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { PostFastClient } from '../client.js';
3
- export declare function registerPostTools(server: McpServer, client: PostFastClient): void;