outx-mcp-server 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.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/dist/client.d.ts +19 -0
- package/dist/client.js +91 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/engagement.d.ts +3 -0
- package/dist/tools/engagement.js +40 -0
- package/dist/tools/engagement.js.map +1 -0
- package/dist/tools/linkedin.d.ts +3 -0
- package/dist/tools/linkedin.js +57 -0
- package/dist/tools/linkedin.js.map +1 -0
- package/dist/tools/posts.d.ts +3 -0
- package/dist/tools/posts.js +32 -0
- package/dist/tools/posts.js.map +1 -0
- package/dist/tools/watchlists.d.ts +3 -0
- package/dist/tools/watchlists.js +177 -0
- package/dist/tools/watchlists.js.map +1 -0
- package/package.json +43 -0
- package/src/client.ts +105 -0
- package/src/index.ts +33 -0
- package/src/tools/engagement.ts +56 -0
- package/src/tools/linkedin.ts +98 -0
- package/src/tools/posts.ts +41 -0
- package/src/tools/watchlists.ts +246 -0
- package/tsconfig.json +17 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OutX AI
|
|
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,217 @@
|
|
|
1
|
+
# OutX MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/outx-mcp-server)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
MCP server for the [OutX](https://outx.ai) LinkedIn social listening and data API. Connect AI agents like Claude, Cursor, and Claude Code to LinkedIn — create watchlists, search posts, fetch profiles, and engage, all through natural language.
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<code>AI Agent ←→ MCP Protocol ←→ OutX MCP Server ←→ OutX API ←→ LinkedIn</code>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
## What You Can Do
|
|
13
|
+
|
|
14
|
+
- **Monitor LinkedIn** — Track posts by keywords, people, or companies with watchlists
|
|
15
|
+
- **Search & filter posts** — 15+ filters: keyword, date, seniority, trending, language
|
|
16
|
+
- **Fetch profiles** — Get full LinkedIn profiles: name, headline, experience, education, skills
|
|
17
|
+
- **Engage** — Like and comment on posts through your LinkedIn account
|
|
18
|
+
- **All via natural language** — Just tell your AI agent what you want
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
**1. Get an API key** at [mentions.outx.ai/api-doc](https://mentions.outx.ai/api-doc)
|
|
23
|
+
|
|
24
|
+
**2. Add to your AI tool** (pick one):
|
|
25
|
+
|
|
26
|
+
<details>
|
|
27
|
+
<summary><strong>Claude Desktop</strong></summary>
|
|
28
|
+
|
|
29
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"outx": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["-y", "outx-mcp-server"],
|
|
37
|
+
"env": {
|
|
38
|
+
"OUTX_API_KEY": "your-api-key"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
</details>
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary><strong>Cursor</strong></summary>
|
|
48
|
+
|
|
49
|
+
Add to `.cursor/mcp.json` in your project:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"outx": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["-y", "outx-mcp-server"],
|
|
57
|
+
"env": {
|
|
58
|
+
"OUTX_API_KEY": "your-api-key"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
<details>
|
|
67
|
+
<summary><strong>Claude Code</strong></summary>
|
|
68
|
+
|
|
69
|
+
Add to `.mcp.json` in your project:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"outx": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["-y", "outx-mcp-server"],
|
|
77
|
+
"env": {
|
|
78
|
+
"OUTX_API_KEY": "your-api-key"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
</details>
|
|
85
|
+
|
|
86
|
+
<details>
|
|
87
|
+
<summary><strong>Windsurf</strong></summary>
|
|
88
|
+
|
|
89
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"outx": {
|
|
95
|
+
"command": "npx",
|
|
96
|
+
"args": ["-y", "outx-mcp-server"],
|
|
97
|
+
"env": {
|
|
98
|
+
"OUTX_API_KEY": "your-api-key"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
</details>
|
|
105
|
+
|
|
106
|
+
**3. Start using it:**
|
|
107
|
+
|
|
108
|
+
> "Create a watchlist to monitor LinkedIn posts about AI startups raising Series A"
|
|
109
|
+
|
|
110
|
+
## Available Tools (20)
|
|
111
|
+
|
|
112
|
+
### Watchlist Management
|
|
113
|
+
|
|
114
|
+
| Tool | Description |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| `create_keyword_watchlist` | Monitor LinkedIn posts matching keywords with optional required/excluded terms |
|
|
117
|
+
| `list_keyword_watchlists` | List all keyword watchlists |
|
|
118
|
+
| `update_keyword_watchlist` | Update name, scan frequency, or pause/resume |
|
|
119
|
+
| `delete_keyword_watchlist` | Delete a keyword watchlist and all tracked data |
|
|
120
|
+
| `create_people_watchlist` | Track posts from specific LinkedIn profiles |
|
|
121
|
+
| `list_people_watchlists` | List all people watchlists |
|
|
122
|
+
| `update_people_watchlist` | Update name, scan frequency, or pause/resume |
|
|
123
|
+
| `delete_people_watchlist` | Delete a people watchlist |
|
|
124
|
+
| `create_company_watchlist` | Monitor posts from LinkedIn company pages |
|
|
125
|
+
| `list_company_watchlists` | List all company watchlists |
|
|
126
|
+
| `update_company_watchlist` | Update name, scan frequency, or pause/resume |
|
|
127
|
+
| `delete_company_watchlist` | Delete a company watchlist |
|
|
128
|
+
|
|
129
|
+
### Posts & Engagement
|
|
130
|
+
|
|
131
|
+
| Tool | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `get_posts` | Search and filter posts from watchlists (keyword, date, seniority, trending, language, etc.) |
|
|
134
|
+
| `like_post` | Like a post from your watchlist results |
|
|
135
|
+
| `comment_on_post` | Comment on a post from your watchlist results |
|
|
136
|
+
|
|
137
|
+
### LinkedIn Data API
|
|
138
|
+
|
|
139
|
+
These tools use the async LinkedIn Data API. The MCP server handles polling automatically — you get the result directly.
|
|
140
|
+
|
|
141
|
+
| Tool | Description |
|
|
142
|
+
|------|-------------|
|
|
143
|
+
| `fetch_linkedin_profile` | Fetch full LinkedIn profile by slug (name, headline, experience, education, skills) |
|
|
144
|
+
| `fetch_linkedin_posts` | Fetch recent posts from profiles by URN |
|
|
145
|
+
| `linkedin_like_post` | Like a post by activity URN |
|
|
146
|
+
| `linkedin_comment_on_post` | Comment on a post by activity URN |
|
|
147
|
+
| `get_task_status` | Check status of an async task manually |
|
|
148
|
+
|
|
149
|
+
> **Note:** LinkedIn Data tools require the [OutX Chrome extension](https://outx.ai/docs/resources/chrome-extension) to be active within the last 48 hours.
|
|
150
|
+
|
|
151
|
+
## Example Prompts
|
|
152
|
+
|
|
153
|
+
Once connected, try these with your AI agent:
|
|
154
|
+
|
|
155
|
+
**Social listening:**
|
|
156
|
+
- "Create a watchlist to monitor LinkedIn posts about AI startups raising Series A"
|
|
157
|
+
- "Show me trending posts from my watchlists this week"
|
|
158
|
+
- "What are VPs and Directors posting about machine learning?"
|
|
159
|
+
- "Find posts mentioning our competitor from the last 7 days"
|
|
160
|
+
|
|
161
|
+
**Profile research:**
|
|
162
|
+
- "Fetch the LinkedIn profile for williamhgates"
|
|
163
|
+
- "Get recent posts from this prospect's profile"
|
|
164
|
+
|
|
165
|
+
**Engagement:**
|
|
166
|
+
- "Like the top 3 most engaging posts about product management"
|
|
167
|
+
- "Comment on this post with a thoughtful response"
|
|
168
|
+
|
|
169
|
+
**Workflows:**
|
|
170
|
+
- "Set up a watchlist for 'looking for a CRM' and check it every 6 hours"
|
|
171
|
+
- "List all my watchlists and show me posts from the sales signals one"
|
|
172
|
+
|
|
173
|
+
## Prerequisites
|
|
174
|
+
|
|
175
|
+
- **Node.js 18+** — Required for the MCP server runtime
|
|
176
|
+
- **OutX account** — [Sign up free](https://mentions.outx.ai/login) and get your API key
|
|
177
|
+
- **OutX Chrome extension** — Required for LinkedIn Data API tools (profile fetching, direct engagement). [Install here](https://outx.ai/docs/resources/chrome-extension)
|
|
178
|
+
|
|
179
|
+
## How It Works
|
|
180
|
+
|
|
181
|
+
The OutX API has two surfaces:
|
|
182
|
+
|
|
183
|
+
1. **Watchlists & Engagement API** (sync) — Create watchlists to monitor LinkedIn by keywords, people, or companies. OutX scans on your schedule and stores posts. Query and engage via API.
|
|
184
|
+
|
|
185
|
+
2. **LinkedIn Data API** (async) — Direct LinkedIn proxy. Fetch profiles, get posts, like, comment. All endpoints return a task ID; the MCP server polls automatically until the result is ready.
|
|
186
|
+
|
|
187
|
+
The MCP server wraps both APIs into 20 tools that any MCP-compatible AI agent can call.
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
git clone https://github.com/outxai/outx-mcp-server.git
|
|
193
|
+
cd outx-mcp-server
|
|
194
|
+
npm install
|
|
195
|
+
npm run build
|
|
196
|
+
OUTX_API_KEY=your-key npm start
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
For development with auto-reload:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
OUTX_API_KEY=your-key npm run dev
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Links
|
|
206
|
+
|
|
207
|
+
- [OutX Platform](https://outx.ai) — Sign up and get started
|
|
208
|
+
- [API Documentation](https://outx.ai/docs/api-reference/introduction) — Full API reference
|
|
209
|
+
- [MCP Integration Guide](https://outx.ai/docs/integrations/mcp) — Detailed setup docs
|
|
210
|
+
- [Get API Key](https://mentions.outx.ai/api-doc) — Generate your key
|
|
211
|
+
- [Chrome Extension](https://outx.ai/docs/resources/chrome-extension) — Required for LinkedIn Data tools
|
|
212
|
+
- [Python SDK](https://outx.ai/docs/integrations/python-sdk) — Python wrapper for the API
|
|
213
|
+
- [LangChain Integration](https://outx.ai/docs/integrations/langchain) — Use OutX as a LangChain tool
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OutX API client — shared HTTP wrapper with auth, error handling, and async task polling.
|
|
3
|
+
*/
|
|
4
|
+
export declare class OutxClient {
|
|
5
|
+
private baseUrl;
|
|
6
|
+
private apiKey;
|
|
7
|
+
constructor(apiKey: string);
|
|
8
|
+
private headers;
|
|
9
|
+
private handleResponse;
|
|
10
|
+
get(path: string, params?: Record<string, string>): Promise<unknown>;
|
|
11
|
+
post(path: string, body: unknown): Promise<unknown>;
|
|
12
|
+
put(path: string, body: unknown): Promise<unknown>;
|
|
13
|
+
delete(path: string, body: unknown): Promise<unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* Poll an async LinkedIn Data API task until it completes or fails.
|
|
16
|
+
* Returns the task_output on success.
|
|
17
|
+
*/
|
|
18
|
+
pollTask(taskId: string, maxAttempts?: number, delayMs?: number): Promise<unknown>;
|
|
19
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OutX API client — shared HTTP wrapper with auth, error handling, and async task polling.
|
|
3
|
+
*/
|
|
4
|
+
export class OutxClient {
|
|
5
|
+
baseUrl = "https://api.outx.ai";
|
|
6
|
+
apiKey;
|
|
7
|
+
constructor(apiKey) {
|
|
8
|
+
this.apiKey = apiKey;
|
|
9
|
+
}
|
|
10
|
+
headers() {
|
|
11
|
+
return {
|
|
12
|
+
"x-api-key": this.apiKey,
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async handleResponse(res) {
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
let message = `HTTP ${res.status}`;
|
|
19
|
+
try {
|
|
20
|
+
const body = await res.json();
|
|
21
|
+
if (body.error)
|
|
22
|
+
message = body.error;
|
|
23
|
+
else if (body.message)
|
|
24
|
+
message = body.message;
|
|
25
|
+
else
|
|
26
|
+
message = JSON.stringify(body);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
message = await res.text().catch(() => message);
|
|
30
|
+
}
|
|
31
|
+
throw new Error(message);
|
|
32
|
+
}
|
|
33
|
+
return res.json();
|
|
34
|
+
}
|
|
35
|
+
async get(path, params) {
|
|
36
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
37
|
+
if (params) {
|
|
38
|
+
for (const [k, v] of Object.entries(params)) {
|
|
39
|
+
if (v !== undefined && v !== "")
|
|
40
|
+
url.searchParams.set(k, v);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const res = await fetch(url.toString(), { headers: this.headers() });
|
|
44
|
+
return this.handleResponse(res);
|
|
45
|
+
}
|
|
46
|
+
async post(path, body) {
|
|
47
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: this.headers(),
|
|
50
|
+
body: JSON.stringify(body),
|
|
51
|
+
});
|
|
52
|
+
return this.handleResponse(res);
|
|
53
|
+
}
|
|
54
|
+
async put(path, body) {
|
|
55
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
56
|
+
method: "PUT",
|
|
57
|
+
headers: this.headers(),
|
|
58
|
+
body: JSON.stringify(body),
|
|
59
|
+
});
|
|
60
|
+
return this.handleResponse(res);
|
|
61
|
+
}
|
|
62
|
+
async delete(path, body) {
|
|
63
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
64
|
+
method: "DELETE",
|
|
65
|
+
headers: this.headers(),
|
|
66
|
+
body: JSON.stringify(body),
|
|
67
|
+
});
|
|
68
|
+
return this.handleResponse(res);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Poll an async LinkedIn Data API task until it completes or fails.
|
|
72
|
+
* Returns the task_output on success.
|
|
73
|
+
*/
|
|
74
|
+
async pollTask(taskId, maxAttempts = 30, delayMs = 5000) {
|
|
75
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
76
|
+
const result = (await this.get("/linkedin-agent/get-task-status", {
|
|
77
|
+
api_agent_task_id: taskId,
|
|
78
|
+
}));
|
|
79
|
+
const { status, task_output } = result.data;
|
|
80
|
+
if (status === "completed")
|
|
81
|
+
return task_output;
|
|
82
|
+
if (status === "failed") {
|
|
83
|
+
throw new Error(`Task failed: ${task_output ? JSON.stringify(task_output) : "unknown error"}`);
|
|
84
|
+
}
|
|
85
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Task ${taskId} did not complete within ${(maxAttempts * delayMs) / 1000}s. ` +
|
|
88
|
+
`Use get_task_status to check manually.`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
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 { OutxClient } from "./client.js";
|
|
5
|
+
import { registerWatchlistTools } from "./tools/watchlists.js";
|
|
6
|
+
import { registerPostTools } from "./tools/posts.js";
|
|
7
|
+
import { registerEngagementTools } from "./tools/engagement.js";
|
|
8
|
+
import { registerLinkedInTools } from "./tools/linkedin.js";
|
|
9
|
+
const apiKey = process.env.OUTX_API_KEY;
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
console.error("Error: OUTX_API_KEY environment variable is required.\n" +
|
|
12
|
+
"Get your key at https://mentions.outx.ai/api-doc");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const client = new OutxClient(apiKey);
|
|
16
|
+
const server = new McpServer({
|
|
17
|
+
name: "outx",
|
|
18
|
+
version: "1.0.0",
|
|
19
|
+
});
|
|
20
|
+
registerWatchlistTools(server, client);
|
|
21
|
+
registerPostTools(server, client);
|
|
22
|
+
registerEngagementTools(server, client);
|
|
23
|
+
registerLinkedInTools(server, client);
|
|
24
|
+
const transport = new StdioServerTransport();
|
|
25
|
+
await server.connect(transport);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;AACxC,IAAI,CAAC,MAAM,EAAE,CAAC;IACZ,OAAO,CAAC,KAAK,CACX,yDAAyD;QACvD,kDAAkD,CACrD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAEtC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerEngagementTools(server, client) {
|
|
3
|
+
server.tool("like_post", "Like a LinkedIn post from your watchlist. Requires the post ID from get_posts results.", {
|
|
4
|
+
post_id: z.string().describe("Post ID from get_posts results"),
|
|
5
|
+
user_email: z.string().describe("Email of the LinkedIn account to like from"),
|
|
6
|
+
actor_type: z
|
|
7
|
+
.enum(["user", "company"])
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Like as user or company page (default: user)"),
|
|
10
|
+
}, async (params) => {
|
|
11
|
+
const body = {
|
|
12
|
+
post_id: params.post_id,
|
|
13
|
+
user_email: params.user_email,
|
|
14
|
+
};
|
|
15
|
+
if (params.actor_type)
|
|
16
|
+
body.actor_type = params.actor_type;
|
|
17
|
+
const result = await client.post("/api-like", body);
|
|
18
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
19
|
+
});
|
|
20
|
+
server.tool("comment_on_post", "Comment on a LinkedIn post from your watchlist. Requires the post ID from get_posts results.", {
|
|
21
|
+
post_id: z.string().describe("Post ID from get_posts results"),
|
|
22
|
+
user_email: z.string().describe("Email of the LinkedIn account to comment from"),
|
|
23
|
+
comment_text: z.string().describe("The comment text to post"),
|
|
24
|
+
actor_type: z
|
|
25
|
+
.enum(["user", "company"])
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Comment as user or company page (default: user)"),
|
|
28
|
+
}, async (params) => {
|
|
29
|
+
const body = {
|
|
30
|
+
post_id: params.post_id,
|
|
31
|
+
user_email: params.user_email,
|
|
32
|
+
comment_text: params.comment_text,
|
|
33
|
+
};
|
|
34
|
+
if (params.actor_type)
|
|
35
|
+
body.actor_type = params.actor_type;
|
|
36
|
+
const result = await client.post("/api-comment", body);
|
|
37
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=engagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engagement.js","sourceRoot":"","sources":["../../src/tools/engagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,MAAkB;IAElB,MAAM,CAAC,IAAI,CACT,WAAW,EACX,wFAAwF,EACxF;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC9D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QAC7E,UAAU,EAAE,CAAC;aACV,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;aACzB,QAAQ,EAAE;aACV,QAAQ,CAAC,8CAA8C,CAAC;KAC5D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,IAAI,GAA4B;YACpC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC;QACF,IAAI,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,8FAA8F,EAC9F;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC9D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QAChF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QAC7D,UAAU,EAAE,CAAC;aACV,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;aACzB,QAAQ,EAAE;aACV,QAAQ,CAAC,iDAAiD,CAAC;KAC/D,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,IAAI,GAA4B;YACpC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC;QACF,IAAI,MAAM,CAAC,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACvD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerLinkedInTools(server, client) {
|
|
3
|
+
server.tool("fetch_linkedin_profile", "Fetch a LinkedIn profile by slug. Returns full profile data including name, headline, experience, education, and skills. Requires the OutX Chrome extension to be active within the last 48 hours. This tool handles async polling automatically.", {
|
|
4
|
+
profile_slug: z
|
|
5
|
+
.string()
|
|
6
|
+
.describe("LinkedIn profile slug (e.g. 'williamhgates' from linkedin.com/in/williamhgates)"),
|
|
7
|
+
}, async (params) => {
|
|
8
|
+
const response = (await client.post("/linkedin-agent/fetch-profile", {
|
|
9
|
+
profile_slug: params.profile_slug,
|
|
10
|
+
}));
|
|
11
|
+
const result = await client.pollTask(response.api_agent_task_id);
|
|
12
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
13
|
+
});
|
|
14
|
+
server.tool("fetch_linkedin_posts", "Fetch recent posts from LinkedIn profiles by URN. Use fetch_linkedin_profile first to get the profile URN. Requires the OutX Chrome extension to be active. This tool handles async polling automatically.", {
|
|
15
|
+
profile_urns: z
|
|
16
|
+
.array(z.string())
|
|
17
|
+
.min(1)
|
|
18
|
+
.describe("LinkedIn profile URNs (e.g. ['urn:li:fsd_profile:ABC123'])"),
|
|
19
|
+
}, async (params) => {
|
|
20
|
+
const response = (await client.post("/linkedin-agent/fetch-profiles-posts", { profile_urns: params.profile_urns }));
|
|
21
|
+
const result = await client.pollTask(response.api_agent_task_id);
|
|
22
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
23
|
+
});
|
|
24
|
+
server.tool("linkedin_like_post", "Like a LinkedIn post by its activity URN. This uses the LinkedIn Data API (direct LinkedIn action). Requires the OutX Chrome extension to be active. This tool handles async polling automatically.", {
|
|
25
|
+
social_urn: z
|
|
26
|
+
.string()
|
|
27
|
+
.describe("LinkedIn activity URN of the post to like"),
|
|
28
|
+
}, async (params) => {
|
|
29
|
+
const response = (await client.post("/linkedin-agent/like-post", {
|
|
30
|
+
social_urn: params.social_urn,
|
|
31
|
+
}));
|
|
32
|
+
const result = await client.pollTask(response.api_agent_task_id);
|
|
33
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
34
|
+
});
|
|
35
|
+
server.tool("linkedin_comment_on_post", "Comment on a LinkedIn post by its activity URN. This uses the LinkedIn Data API (direct LinkedIn action). Requires the OutX Chrome extension to be active. This tool handles async polling automatically.", {
|
|
36
|
+
social_urn: z
|
|
37
|
+
.string()
|
|
38
|
+
.describe("LinkedIn activity URN of the post to comment on"),
|
|
39
|
+
comment_text: z.string().describe("The comment text to post"),
|
|
40
|
+
}, async (params) => {
|
|
41
|
+
const response = (await client.post("/linkedin-agent/comment-post", {
|
|
42
|
+
social_urn: params.social_urn,
|
|
43
|
+
comment_text: params.comment_text,
|
|
44
|
+
}));
|
|
45
|
+
const result = await client.pollTask(response.api_agent_task_id);
|
|
46
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
47
|
+
});
|
|
48
|
+
server.tool("get_task_status", "Check the status of an async LinkedIn Data API task. Use this to manually check tasks that timed out. Status values: pending, processing, completed, failed.", {
|
|
49
|
+
task_id: z.string().describe("The api_agent_task_id to check"),
|
|
50
|
+
}, async (params) => {
|
|
51
|
+
const result = await client.get("/linkedin-agent/get-task-status", {
|
|
52
|
+
api_agent_task_id: params.task_id,
|
|
53
|
+
});
|
|
54
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=linkedin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkedin.js","sourceRoot":"","sources":["../../src/tools/linkedin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPostTools(server, client) {
|
|
3
|
+
server.tool("get_posts", "Search and filter LinkedIn posts from your watchlists. Supports keyword search, date range, seniority, trending, language, and more. Returns 20 posts per page.", {
|
|
4
|
+
watchlist_id: z.string().optional().describe("Filter by watchlist ID (omit for all)"),
|
|
5
|
+
search_term: z.string().optional().describe("Search within post content"),
|
|
6
|
+
sort_by: z
|
|
7
|
+
.enum(["recent_first", "oldest_first", "engagement"])
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Sort order (default: recent_first)"),
|
|
10
|
+
page: z.string().optional().describe("Page number (default: 1)"),
|
|
11
|
+
start_date: z.string().optional().describe("Filter posts after this date (ISO 8601)"),
|
|
12
|
+
end_date: z.string().optional().describe("Filter posts before this date (ISO 8601)"),
|
|
13
|
+
seniority_level: z.string().optional().describe("Filter by author seniority (e.g. 'Director', 'VP')"),
|
|
14
|
+
trending: z.string().optional().describe("Set to 'true' to show only trending posts"),
|
|
15
|
+
lang: z.string().optional().describe("Filter by language code (e.g. 'en', 'es')"),
|
|
16
|
+
post_type: z.string().optional().describe("Filter by post type"),
|
|
17
|
+
labels: z.string().optional().describe("Filter by label"),
|
|
18
|
+
people_slug: z.string().optional().describe("Filter by author's LinkedIn slug"),
|
|
19
|
+
company_slug: z.string().optional().describe("Filter by company's LinkedIn slug"),
|
|
20
|
+
interacted: z.string().optional().describe("Set to 'true' to show only posts you've interacted with"),
|
|
21
|
+
linkedin_post_slug: z.string().optional().describe("Get a specific post by its LinkedIn slug"),
|
|
22
|
+
}, async (params) => {
|
|
23
|
+
const queryParams = {};
|
|
24
|
+
for (const [k, v] of Object.entries(params)) {
|
|
25
|
+
if (v !== undefined)
|
|
26
|
+
queryParams[k] = v;
|
|
27
|
+
}
|
|
28
|
+
const result = await client.get("/api-posts", queryParams);
|
|
29
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=posts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posts.js","sourceRoot":"","sources":["../../src/tools/posts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,MAAkB;IAElB,MAAM,CAAC,IAAI,CACT,WAAW,EACX,iKAAiK,EACjK;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;QACrF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACzE,OAAO,EAAE,CAAC;aACP,IAAI,CAAC,CAAC,cAAc,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;aACpD,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,CAAC;QACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACrF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QACpF,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QACrG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACrF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACjF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAChE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACzD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QAC/E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACjF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;QACrG,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KAC/F,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,WAAW,GAA2B,EAAE,CAAC;QAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,SAAS;gBAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;AACJ,CAAC"}
|