@linkedapi/mcp 0.3.11
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/.dockerignore +11 -0
- package/.github/workflows/merge-main.yaml +136 -0
- package/.github/workflows/pr-main.yaml +42 -0
- package/.husky/pre-commit +5 -0
- package/.prettierrc.js +21 -0
- package/.vscode/launch.json +19 -0
- package/Dockerfile +39 -0
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +189 -0
- package/dist/index.js.map +1 -0
- package/dist/linked-api-server.d.ts +13 -0
- package/dist/linked-api-server.d.ts.map +1 -0
- package/dist/linked-api-server.js +127 -0
- package/dist/linked-api-server.js.map +1 -0
- package/dist/linked-api-tools.d.ts +8 -0
- package/dist/linked-api-tools.d.ts.map +1 -0
- package/dist/linked-api-tools.js +72 -0
- package/dist/linked-api-tools.js.map +1 -0
- package/dist/prompts/index.d.ts +10 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +190 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/tools/check-connection-status.d.ts +13 -0
- package/dist/tools/check-connection-status.d.ts.map +1 -0
- package/dist/tools/check-connection-status.js +31 -0
- package/dist/tools/check-connection-status.js.map +1 -0
- package/dist/tools/comment-on-post.d.ts +15 -0
- package/dist/tools/comment-on-post.d.ts.map +1 -0
- package/dist/tools/comment-on-post.js +41 -0
- package/dist/tools/comment-on-post.js.map +1 -0
- package/dist/tools/create-post.d.ts +23 -0
- package/dist/tools/create-post.d.ts.map +1 -0
- package/dist/tools/create-post.js +67 -0
- package/dist/tools/create-post.js.map +1 -0
- package/dist/tools/execute-custom-workflow.d.ts +13 -0
- package/dist/tools/execute-custom-workflow.d.ts.map +1 -0
- package/dist/tools/execute-custom-workflow.js +26 -0
- package/dist/tools/execute-custom-workflow.js.map +1 -0
- package/dist/tools/fetch-company.d.ts +34 -0
- package/dist/tools/fetch-company.d.ts.map +1 -0
- package/dist/tools/fetch-company.js +139 -0
- package/dist/tools/fetch-company.js.map +1 -0
- package/dist/tools/fetch-person.d.ts +32 -0
- package/dist/tools/fetch-person.d.ts.map +1 -0
- package/dist/tools/fetch-person.js +129 -0
- package/dist/tools/fetch-person.js.map +1 -0
- package/dist/tools/fetch-post.d.ts +26 -0
- package/dist/tools/fetch-post.d.ts.map +1 -0
- package/dist/tools/fetch-post.js +82 -0
- package/dist/tools/fetch-post.js.map +1 -0
- package/dist/tools/get-api-usage-stats.d.ts +19 -0
- package/dist/tools/get-api-usage-stats.d.ts.map +1 -0
- package/dist/tools/get-api-usage-stats.js +40 -0
- package/dist/tools/get-api-usage-stats.js.map +1 -0
- package/dist/tools/get-conversation.d.ts +26 -0
- package/dist/tools/get-conversation.d.ts.map +1 -0
- package/dist/tools/get-conversation.js +59 -0
- package/dist/tools/get-conversation.js.map +1 -0
- package/dist/tools/get-workflow-result.d.ts +50 -0
- package/dist/tools/get-workflow-result.d.ts.map +1 -0
- package/dist/tools/get-workflow-result.js +46 -0
- package/dist/tools/get-workflow-result.js.map +1 -0
- package/dist/tools/nv-fetch-company.d.ts +30 -0
- package/dist/tools/nv-fetch-company.d.ts.map +1 -0
- package/dist/tools/nv-fetch-company.js +124 -0
- package/dist/tools/nv-fetch-company.js.map +1 -0
- package/dist/tools/nv-fetch-person.d.ts +13 -0
- package/dist/tools/nv-fetch-person.d.ts.map +1 -0
- package/dist/tools/nv-fetch-person.js +31 -0
- package/dist/tools/nv-fetch-person.js.map +1 -0
- package/dist/tools/nv-get-conversation.d.ts +26 -0
- package/dist/tools/nv-get-conversation.d.ts.map +1 -0
- package/dist/tools/nv-get-conversation.js +59 -0
- package/dist/tools/nv-get-conversation.js.map +1 -0
- package/dist/tools/nv-search-companies.d.ts +32 -0
- package/dist/tools/nv-search-companies.d.ts.map +1 -0
- package/dist/tools/nv-search-companies.js +106 -0
- package/dist/tools/nv-search-companies.js.map +1 -0
- package/dist/tools/nv-search-people.d.ts +25 -0
- package/dist/tools/nv-search-people.d.ts.map +1 -0
- package/dist/tools/nv-search-people.js +99 -0
- package/dist/tools/nv-search-people.js.map +1 -0
- package/dist/tools/nv-send-message.d.ts +15 -0
- package/dist/tools/nv-send-message.d.ts.map +1 -0
- package/dist/tools/nv-send-message.js +41 -0
- package/dist/tools/nv-send-message.js.map +1 -0
- package/dist/tools/nv-sync-conversation.d.ts +13 -0
- package/dist/tools/nv-sync-conversation.d.ts.map +1 -0
- package/dist/tools/nv-sync-conversation.js +31 -0
- package/dist/tools/nv-sync-conversation.js.map +1 -0
- package/dist/tools/react-to-post.d.ts +22 -0
- package/dist/tools/react-to-post.d.ts.map +1 -0
- package/dist/tools/react-to-post.js +42 -0
- package/dist/tools/react-to-post.js.map +1 -0
- package/dist/tools/remove-connection.d.ts +13 -0
- package/dist/tools/remove-connection.d.ts.map +1 -0
- package/dist/tools/remove-connection.js +31 -0
- package/dist/tools/remove-connection.js.map +1 -0
- package/dist/tools/retrieve-connections.d.ts +24 -0
- package/dist/tools/retrieve-connections.d.ts.map +1 -0
- package/dist/tools/retrieve-connections.js +90 -0
- package/dist/tools/retrieve-connections.js.map +1 -0
- package/dist/tools/retrieve-pending-requests.d.ts +10 -0
- package/dist/tools/retrieve-pending-requests.d.ts.map +1 -0
- package/dist/tools/retrieve-pending-requests.js +23 -0
- package/dist/tools/retrieve-pending-requests.js.map +1 -0
- package/dist/tools/retrieve-performance.d.ts +10 -0
- package/dist/tools/retrieve-performance.d.ts.map +1 -0
- package/dist/tools/retrieve-performance.js +23 -0
- package/dist/tools/retrieve-performance.js.map +1 -0
- package/dist/tools/retrieve-ssi.d.ts +10 -0
- package/dist/tools/retrieve-ssi.d.ts.map +1 -0
- package/dist/tools/retrieve-ssi.js +23 -0
- package/dist/tools/retrieve-ssi.js.map +1 -0
- package/dist/tools/search-companies.d.ts +28 -0
- package/dist/tools/search-companies.d.ts.map +1 -0
- package/dist/tools/search-companies.js +86 -0
- package/dist/tools/search-companies.js.map +1 -0
- package/dist/tools/search-people.d.ts +24 -0
- package/dist/tools/search-people.d.ts.map +1 -0
- package/dist/tools/search-people.js +90 -0
- package/dist/tools/search-people.js.map +1 -0
- package/dist/tools/send-connection-request.d.ts +15 -0
- package/dist/tools/send-connection-request.d.ts.map +1 -0
- package/dist/tools/send-connection-request.js +41 -0
- package/dist/tools/send-connection-request.js.map +1 -0
- package/dist/tools/send-message.d.ts +14 -0
- package/dist/tools/send-message.d.ts.map +1 -0
- package/dist/tools/send-message.js +36 -0
- package/dist/tools/send-message.js.map +1 -0
- package/dist/tools/sync-conversation.d.ts +13 -0
- package/dist/tools/sync-conversation.d.ts.map +1 -0
- package/dist/tools/sync-conversation.js +31 -0
- package/dist/tools/sync-conversation.js.map +1 -0
- package/dist/tools/withdraw-connection-request.d.ts +14 -0
- package/dist/tools/withdraw-connection-request.d.ts.map +1 -0
- package/dist/tools/withdraw-connection-request.js +36 -0
- package/dist/tools/withdraw-connection-request.js.map +1 -0
- package/dist/utils/define-request-timeout.d.ts +2 -0
- package/dist/utils/define-request-timeout.d.ts.map +1 -0
- package/dist/utils/define-request-timeout.js +20 -0
- package/dist/utils/define-request-timeout.js.map +1 -0
- package/dist/utils/execute-with-progress.d.ts +8 -0
- package/dist/utils/execute-with-progress.d.ts.map +1 -0
- package/dist/utils/execute-with-progress.js +75 -0
- package/dist/utils/execute-with-progress.js.map +1 -0
- package/dist/utils/handle-linked-api-error.d.ts +3 -0
- package/dist/utils/handle-linked-api-error.d.ts.map +1 -0
- package/dist/utils/handle-linked-api-error.js +29 -0
- package/dist/utils/handle-linked-api-error.js.map +1 -0
- package/dist/utils/json-http-transport.d.ts +26 -0
- package/dist/utils/json-http-transport.d.ts.map +1 -0
- package/dist/utils/json-http-transport.js +265 -0
- package/dist/utils/json-http-transport.js.map +1 -0
- package/dist/utils/linked-api-tool.d.ts +28 -0
- package/dist/utils/linked-api-tool.d.ts.map +1 -0
- package/dist/utils/linked-api-tool.js +25 -0
- package/dist/utils/linked-api-tool.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +81 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/types.d.ts +16 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +3 -0
- package/dist/utils/types.js.map +1 -0
- package/eslint.config.js +118 -0
- package/package.json +62 -0
- package/src/index.ts +212 -0
- package/src/linked-api-server.ts +159 -0
- package/src/linked-api-tools.ts +72 -0
- package/src/prompts/index.ts +190 -0
- package/src/tools/check-connection-status.ts +39 -0
- package/src/tools/comment-on-post.ts +42 -0
- package/src/tools/create-post.ts +71 -0
- package/src/tools/execute-custom-workflow.ts +28 -0
- package/src/tools/fetch-company.ts +154 -0
- package/src/tools/fetch-person.ts +145 -0
- package/src/tools/fetch-post.ts +90 -0
- package/src/tools/get-api-usage-stats.ts +48 -0
- package/src/tools/get-conversation.ts +76 -0
- package/src/tools/get-workflow-result.ts +62 -0
- package/src/tools/nv-fetch-company.ts +136 -0
- package/src/tools/nv-fetch-person.ts +31 -0
- package/src/tools/nv-get-conversation.ts +76 -0
- package/src/tools/nv-search-companies.ts +114 -0
- package/src/tools/nv-search-people.ts +107 -0
- package/src/tools/nv-send-message.ts +42 -0
- package/src/tools/nv-sync-conversation.ts +32 -0
- package/src/tools/react-to-post.ts +44 -0
- package/src/tools/remove-connection.ts +32 -0
- package/src/tools/retrieve-connections.ts +105 -0
- package/src/tools/retrieve-pending-requests.ts +23 -0
- package/src/tools/retrieve-performance.ts +23 -0
- package/src/tools/retrieve-ssi.ts +23 -0
- package/src/tools/search-companies.ts +93 -0
- package/src/tools/search-people.ts +97 -0
- package/src/tools/send-connection-request.ts +46 -0
- package/src/tools/send-message.ts +36 -0
- package/src/tools/sync-conversation.ts +32 -0
- package/src/tools/withdraw-connection-request.ts +41 -0
- package/src/utils/define-request-timeout.ts +17 -0
- package/src/utils/execute-with-progress.ts +93 -0
- package/src/utils/handle-linked-api-error.ts +27 -0
- package/src/utils/json-http-transport.ts +325 -0
- package/src/utils/linked-api-tool.ts +58 -0
- package/src/utils/logger.ts +84 -0
- package/src/utils/types.ts +17 -0
- package/tsconfig.json +36 -0
package/.dockerignore
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
name: PR Merged -> main
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ['main']
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
packages: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
linting:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout code
|
|
17
|
+
uses: actions/checkout@v4.1.1
|
|
18
|
+
|
|
19
|
+
- name: Set up Node.js
|
|
20
|
+
uses: actions/setup-node@v4.0.1
|
|
21
|
+
with:
|
|
22
|
+
node-version: 20
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: npm ci
|
|
26
|
+
|
|
27
|
+
- name: Run ESLint
|
|
28
|
+
run: npm run lint
|
|
29
|
+
|
|
30
|
+
build:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout code
|
|
35
|
+
uses: actions/checkout@v4.1.1
|
|
36
|
+
|
|
37
|
+
- name: Set up Node.js
|
|
38
|
+
uses: actions/setup-node@v4.0.1
|
|
39
|
+
with:
|
|
40
|
+
node-version: 20
|
|
41
|
+
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
run: npm ci
|
|
44
|
+
|
|
45
|
+
- name: Build
|
|
46
|
+
run: npm run build
|
|
47
|
+
|
|
48
|
+
npm-publish:
|
|
49
|
+
needs: [linting, build]
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
if: always() && needs.linting.result == 'success' && needs.build.result == 'success'
|
|
52
|
+
|
|
53
|
+
steps:
|
|
54
|
+
- name: Checkout code
|
|
55
|
+
uses: actions/checkout@v4.1.1
|
|
56
|
+
|
|
57
|
+
- name: Set up Node.js
|
|
58
|
+
uses: actions/setup-node@v4.0.1
|
|
59
|
+
with:
|
|
60
|
+
node-version: 20
|
|
61
|
+
registry-url: 'https://registry.npmjs.org'
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: npm ci
|
|
65
|
+
|
|
66
|
+
- name: Build
|
|
67
|
+
run: npm run build
|
|
68
|
+
|
|
69
|
+
- name: Check if version changed
|
|
70
|
+
id: version-check
|
|
71
|
+
run: |
|
|
72
|
+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
|
73
|
+
NPM_VERSION=$(npm view @linkedapi/mcp version 2>/dev/null || echo "0.0.0")
|
|
74
|
+
if [ "$PACKAGE_VERSION" != "$NPM_VERSION" ]; then
|
|
75
|
+
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
76
|
+
echo "Version changed: $NPM_VERSION -> $PACKAGE_VERSION"
|
|
77
|
+
else
|
|
78
|
+
echo "should_publish=false" >> $GITHUB_OUTPUT
|
|
79
|
+
echo "Version unchanged: $PACKAGE_VERSION"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
- name: Publish to npm
|
|
83
|
+
if: steps.version-check.outputs.should_publish == 'true'
|
|
84
|
+
run: npm publish --access public
|
|
85
|
+
env:
|
|
86
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
87
|
+
|
|
88
|
+
build-push:
|
|
89
|
+
needs: [linting]
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
if: always() && needs.linting.result == 'success'
|
|
92
|
+
|
|
93
|
+
steps:
|
|
94
|
+
- name: Checkout code
|
|
95
|
+
uses: actions/checkout@v4.1.1
|
|
96
|
+
|
|
97
|
+
- name: Log in to GitHub Container Registry
|
|
98
|
+
uses: docker/login-action@v3
|
|
99
|
+
with:
|
|
100
|
+
registry: ghcr.io
|
|
101
|
+
username: ${{ github.actor }}
|
|
102
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
103
|
+
|
|
104
|
+
- name: Set up Docker Buildx
|
|
105
|
+
uses: docker/setup-buildx-action@v2
|
|
106
|
+
|
|
107
|
+
- name: Set lowercase repository owner
|
|
108
|
+
id: lowercase
|
|
109
|
+
run: echo "repository_owner_lowercase=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
|
|
110
|
+
|
|
111
|
+
- name: Build and push
|
|
112
|
+
uses: docker/build-push-action@v4
|
|
113
|
+
with:
|
|
114
|
+
context: .
|
|
115
|
+
push: true
|
|
116
|
+
tags: |
|
|
117
|
+
ghcr.io/${{ steps.lowercase.outputs.repository_owner_lowercase }}/${{ secrets.DOCKER_IMAGE_NAME }}:prod
|
|
118
|
+
cache-from: type=registry,ref=ghcr.io/${{ steps.lowercase.outputs.repository_owner_lowercase }}/${{ secrets.DOCKER_IMAGE_NAME }}:prod
|
|
119
|
+
cache-to: type=inline
|
|
120
|
+
|
|
121
|
+
deployment:
|
|
122
|
+
needs: [build-push]
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
if: always() && needs.build-push.result == 'success'
|
|
125
|
+
|
|
126
|
+
steps:
|
|
127
|
+
- name: Trigger PaaS deployment
|
|
128
|
+
run: |
|
|
129
|
+
curl -X 'POST' \
|
|
130
|
+
'${{ secrets.PAAS_API_URL }}/application.deploy' \
|
|
131
|
+
-H 'accept: application/json' \
|
|
132
|
+
-H 'Content-Type: application/json' \
|
|
133
|
+
-H 'x-api-key: ${{ secrets.PAAS_API_TOKEN }}' \
|
|
134
|
+
-d '{
|
|
135
|
+
"applicationId": "${{ secrets.PAAS_APPLICATION_ID }}"
|
|
136
|
+
}'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: PR Sent -> main
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: ['main']
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
linting:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout code
|
|
13
|
+
uses: actions/checkout@v4.1.1
|
|
14
|
+
|
|
15
|
+
- name: Set up Node.js
|
|
16
|
+
uses: actions/setup-node@v4.0.1
|
|
17
|
+
with:
|
|
18
|
+
node-version: 20
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Run ESLint
|
|
24
|
+
run: npm run lint
|
|
25
|
+
|
|
26
|
+
build:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout code
|
|
31
|
+
uses: actions/checkout@v4.1.1
|
|
32
|
+
|
|
33
|
+
- name: Set up Node.js
|
|
34
|
+
uses: actions/setup-node@v4.0.1
|
|
35
|
+
with:
|
|
36
|
+
node-version: 20
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: npm ci
|
|
40
|
+
|
|
41
|
+
- name: Build
|
|
42
|
+
run: npm run build
|
package/.prettierrc.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
tabWidth: 2,
|
|
3
|
+
printWidth: 100,
|
|
4
|
+
useTabs: false,
|
|
5
|
+
semi: true,
|
|
6
|
+
singleQuote: true,
|
|
7
|
+
trailingComma: "all",
|
|
8
|
+
bracketSpacing: true,
|
|
9
|
+
arrowParens: "always",
|
|
10
|
+
endOfLine: "auto",
|
|
11
|
+
importOrderSeparation: true,
|
|
12
|
+
importOrderSortSpecifiers: true,
|
|
13
|
+
importOrderCaseInsensitive: true,
|
|
14
|
+
importOrderParserPlugins: [
|
|
15
|
+
"classProperties",
|
|
16
|
+
"decorators-legacy",
|
|
17
|
+
"typescript",
|
|
18
|
+
],
|
|
19
|
+
importOrder: ["<THIRD_PARTY_MODULES>", "^@/(.*)$", "^../(.*)", "^./(.*)"],
|
|
20
|
+
plugins: ["@trivago/prettier-plugin-sort-imports"],
|
|
21
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"type": "node-terminal",
|
|
6
|
+
"name": "Linked API MCP - HTTP",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"command": "npm run dev:http",
|
|
9
|
+
"envFile": "${workspaceFolder}/.env"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "node-terminal",
|
|
13
|
+
"name": "Linked API MCP - STDIO",
|
|
14
|
+
"request": "launch",
|
|
15
|
+
"command": "npm run dev:stdio",
|
|
16
|
+
"envFile": "${workspaceFolder}/.env"
|
|
17
|
+
},
|
|
18
|
+
]
|
|
19
|
+
}
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
FROM node:20-slim AS deps
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
|
|
4
|
+
# Copy package files
|
|
5
|
+
COPY package.json package-lock.json* ./
|
|
6
|
+
|
|
7
|
+
# Install production dependencies only
|
|
8
|
+
RUN npm ci --omit=dev --legacy-peer-deps --ignore-scripts
|
|
9
|
+
|
|
10
|
+
FROM node:20-slim AS builder
|
|
11
|
+
WORKDIR /app
|
|
12
|
+
|
|
13
|
+
# Copy package files
|
|
14
|
+
COPY package.json package-lock.json* ./
|
|
15
|
+
|
|
16
|
+
# Install all dependencies (including dev)
|
|
17
|
+
RUN HUSKY=0 npm ci --legacy-peer-deps
|
|
18
|
+
|
|
19
|
+
# Copy sources and build
|
|
20
|
+
COPY tsconfig.json ./
|
|
21
|
+
COPY src ./src
|
|
22
|
+
COPY README.md ./README.md
|
|
23
|
+
RUN npm run build
|
|
24
|
+
|
|
25
|
+
FROM node:20-slim AS runner
|
|
26
|
+
ENV NODE_ENV=production
|
|
27
|
+
WORKDIR /app
|
|
28
|
+
|
|
29
|
+
# Copy production node_modules and built app
|
|
30
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
31
|
+
COPY --from=builder /app/dist ./dist
|
|
32
|
+
COPY --from=builder /app/package.json ./
|
|
33
|
+
|
|
34
|
+
ENV HOST=0.0.0.0 \
|
|
35
|
+
PORT=3000
|
|
36
|
+
|
|
37
|
+
EXPOSE 3000
|
|
38
|
+
|
|
39
|
+
CMD ["node", "dist/index.js", "--http"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Linked API
|
|
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,17 @@
|
|
|
1
|
+
Linked API MCP server connects your LinkedIn account to AI assistants like Claude, Cursor, and VS Code. Ask them to search for leads, send messages, analyze profiles, and much more – they'll handle it through our cloud browser, safely and automatically.
|
|
2
|
+
|
|
3
|
+
## Use cases
|
|
4
|
+
- **Sales automation assistant**. Ask your AI to find leads, check their profiles, and draft personalized outreach. It can search for "software engineers at companies with 50-200 employees in San Francisco", analyze their backgrounds, and suggest connection messages that actually make sense.
|
|
5
|
+
- **Recruitment assistant**. Let your assistant search for candidates with specific skills, review their experience, and send initial outreach. It handles the time-consuming parts while you focus on actually talking to people.
|
|
6
|
+
- **Conversation assistant**. Your AI can read your existing LinkedIn conversations and help you respond naturally. It understands the context of your chats, suggests relevant replies, and can even send follow-up messages.
|
|
7
|
+
- **Market research assistant**. Need competitor analysis? Your assistant can gather data about companies, their employees, and recent activities. Get insights about industry trends without spending hours on LinkedIn.
|
|
8
|
+
|
|
9
|
+
## Get started
|
|
10
|
+
To start using Linked API MCP, spend 2 minutes reading these essential guides:
|
|
11
|
+
|
|
12
|
+
1. [Installation](https://linkedapi.io/mcp/installation/) – set up MCP in Claude, Cursor, VS Code, or Windsurf.
|
|
13
|
+
2. [Available tools](https://linkedapi.io/mcp/available-tools/) – explore all the LinkedIn tools your assistant can call.
|
|
14
|
+
3. [Usage examples](https://linkedapi.io/mcp/usage-examples/) – see real-world examples to get you started quickly.
|
|
15
|
+
|
|
16
|
+
## License
|
|
17
|
+
This project is licensed under the MIT – see the [LICENSE](https://github.com/Linked-API/linkedapi-mcp/blob/main/LICENSE) file for details.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
8
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
9
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
10
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
11
|
+
const linked_api_server_1 = require("./linked-api-server");
|
|
12
|
+
const prompts_1 = require("./prompts");
|
|
13
|
+
const json_http_transport_1 = require("./utils/json-http-transport");
|
|
14
|
+
const logger_1 = require("./utils/logger");
|
|
15
|
+
function deriveClientFromUserAgent(userAgent) {
|
|
16
|
+
const ua = userAgent.toLowerCase();
|
|
17
|
+
if (ua.includes('cursor'))
|
|
18
|
+
return 'cursor';
|
|
19
|
+
if (ua.includes('windsurf'))
|
|
20
|
+
return 'windsurf';
|
|
21
|
+
if (ua.includes('vscode') || ua.includes('visual studio code'))
|
|
22
|
+
return 'vscode';
|
|
23
|
+
if (ua.includes('chatgpt') || ua.includes('openai'))
|
|
24
|
+
return 'chatgpt';
|
|
25
|
+
if (ua.includes('curl'))
|
|
26
|
+
return 'curl';
|
|
27
|
+
if (ua.includes('postman'))
|
|
28
|
+
return 'postman';
|
|
29
|
+
if (ua.includes('mozilla') ||
|
|
30
|
+
ua.includes('chrome') ||
|
|
31
|
+
ua.includes('safari') ||
|
|
32
|
+
ua.includes('firefox'))
|
|
33
|
+
return 'browser';
|
|
34
|
+
return userAgent;
|
|
35
|
+
}
|
|
36
|
+
function getArgValue(flag) {
|
|
37
|
+
const index = process.argv.indexOf(flag);
|
|
38
|
+
if (index === -1)
|
|
39
|
+
return undefined;
|
|
40
|
+
const value = process.argv[index + 1];
|
|
41
|
+
if (!value || value.startsWith('--'))
|
|
42
|
+
return undefined;
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
function hasFlag(flag) {
|
|
46
|
+
return process.argv.includes(flag);
|
|
47
|
+
}
|
|
48
|
+
async function main() {
|
|
49
|
+
const server = new index_js_1.Server({
|
|
50
|
+
name: 'linkedapi-mcp',
|
|
51
|
+
version: '1.0.0',
|
|
52
|
+
description: 'MCP Server for Linked API (https://linkedapi.io)',
|
|
53
|
+
}, {
|
|
54
|
+
capabilities: {
|
|
55
|
+
tools: {},
|
|
56
|
+
prompts: {},
|
|
57
|
+
},
|
|
58
|
+
instructions: prompts_1.systemPrompt,
|
|
59
|
+
});
|
|
60
|
+
const progressCallback = (_notification) => { };
|
|
61
|
+
const linkedApiServer = new linked_api_server_1.LinkedApiMCPServer(progressCallback);
|
|
62
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
63
|
+
const tools = linkedApiServer.getTools();
|
|
64
|
+
return {
|
|
65
|
+
tools,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => {
|
|
69
|
+
return {
|
|
70
|
+
prompts: prompts_1.availablePrompts,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
|
|
74
|
+
const { name } = request.params;
|
|
75
|
+
try {
|
|
76
|
+
const content = name === 'performance_guidelines' ? prompts_1.systemPrompt : (0, prompts_1.getPromptContent)(name);
|
|
77
|
+
return {
|
|
78
|
+
description: `Linked API MCP: ${name.replace('_', ' ')}`,
|
|
79
|
+
messages: [
|
|
80
|
+
{
|
|
81
|
+
role: 'user',
|
|
82
|
+
content: {
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: content,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request, extra) => {
|
|
95
|
+
const requestInfoAny = extra?.requestInfo;
|
|
96
|
+
const method = requestInfoAny?.method ?? 'N/A';
|
|
97
|
+
const transportType = requestInfoAny?.transport ?? 'N/A';
|
|
98
|
+
logger_1.logger.info({
|
|
99
|
+
method,
|
|
100
|
+
transport: transportType,
|
|
101
|
+
}, 'Tool request received');
|
|
102
|
+
try {
|
|
103
|
+
const localLinkedApiToken = process.env.LINKED_API_TOKEN;
|
|
104
|
+
const localIdentificationToken = process.env.IDENTIFICATION_TOKEN;
|
|
105
|
+
const headers = extra?.requestInfo?.headers ?? {};
|
|
106
|
+
const linkedApiToken = (headers['linked-api-token'] ?? localLinkedApiToken ?? '');
|
|
107
|
+
const identificationToken = (headers['identification-token'] ??
|
|
108
|
+
localIdentificationToken ??
|
|
109
|
+
'');
|
|
110
|
+
let mcpClient = (headers['client'] ?? '');
|
|
111
|
+
if (!mcpClient) {
|
|
112
|
+
const userAgentHeader = headers['user-agent'];
|
|
113
|
+
if (typeof userAgentHeader === 'string' && userAgentHeader.trim().length > 0) {
|
|
114
|
+
mcpClient = deriveClientFromUserAgent(userAgentHeader);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const result = await linkedApiServer.executeWithTokens(request.params, {
|
|
118
|
+
linkedApiToken,
|
|
119
|
+
identificationToken,
|
|
120
|
+
mcpClient,
|
|
121
|
+
});
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
logger_1.logger.error({
|
|
126
|
+
toolName: request.params.name,
|
|
127
|
+
error: error instanceof Error ? error.message : String(error),
|
|
128
|
+
}, 'Critical tool execution error');
|
|
129
|
+
return {
|
|
130
|
+
content: [
|
|
131
|
+
{
|
|
132
|
+
type: 'text',
|
|
133
|
+
text: 'Unknown error. Please try again.',
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
if (hasFlag('--http') || hasFlag('--transport=http')) {
|
|
140
|
+
const port = Number(process.env.PORT ?? getArgValue('--port') ?? 3000);
|
|
141
|
+
const host = process.env.HOST ?? getArgValue('--host') ?? '0.0.0.0';
|
|
142
|
+
const transport = new json_http_transport_1.JsonHTTPServerTransport();
|
|
143
|
+
await server.connect(transport);
|
|
144
|
+
const httpServer = node_http_1.default.createServer(async (req, res) => {
|
|
145
|
+
try {
|
|
146
|
+
if (!req.url) {
|
|
147
|
+
res.statusCode = 400;
|
|
148
|
+
res.end('Bad Request');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const url = new URL(req.url, `http://${req.headers.host ?? 'localhost'}`);
|
|
152
|
+
// Set query parameters to headers if they are not set
|
|
153
|
+
const linkedApiTokenQP = url.searchParams.get('linked-api-token');
|
|
154
|
+
const identificationTokenQP = url.searchParams.get('identification-token');
|
|
155
|
+
const mcpClient = url.searchParams.get('client');
|
|
156
|
+
if (!req.headers['linked-api-token'] && linkedApiTokenQP) {
|
|
157
|
+
req.headers['linked-api-token'] = linkedApiTokenQP;
|
|
158
|
+
}
|
|
159
|
+
if (!req.headers['identification-token'] && identificationTokenQP) {
|
|
160
|
+
req.headers['identification-token'] = identificationTokenQP;
|
|
161
|
+
}
|
|
162
|
+
if (!req.headers['client'] && mcpClient) {
|
|
163
|
+
req.headers['client'] = mcpClient;
|
|
164
|
+
}
|
|
165
|
+
await transport.handleRequest(req, res);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
logger_1.logger.error({
|
|
169
|
+
error: error instanceof Error ? error.message : String(error),
|
|
170
|
+
}, 'HTTP request handling failed');
|
|
171
|
+
res.statusCode = 500;
|
|
172
|
+
res.end('Internal Server Error');
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
httpServer.listen(port, host, () => {
|
|
176
|
+
logger_1.logger.info({ host }, `HTTP transport listening on port ${port}`);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
181
|
+
await server.connect(transport);
|
|
182
|
+
logger_1.logger.info('stdio transport connected');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
main().catch((error) => {
|
|
186
|
+
logger_1.logger.error(error, 'Fatal error');
|
|
187
|
+
process.exit(1);
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TLinkedApiConfig } from '@linkedapi/node';
|
|
2
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { CallToolResult, ExtendedCallToolRequest, LinkedApiProgressNotification } from './utils/types';
|
|
4
|
+
export declare class LinkedApiMCPServer {
|
|
5
|
+
private tools;
|
|
6
|
+
constructor(progressCallback: (notification: LinkedApiProgressNotification) => void);
|
|
7
|
+
getTools(): Tool[];
|
|
8
|
+
executeWithTokens(request: ExtendedCallToolRequest['params'], { linkedApiToken, identificationToken, mcpClient }: TLinkedApiConfig & {
|
|
9
|
+
mcpClient: string;
|
|
10
|
+
}): Promise<CallToolResult>;
|
|
11
|
+
private calculateDuration;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=linked-api-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linked-api-server.d.ts","sourceRoot":"","sources":["../src/linked-api-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAM1D,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,6BAA6B,EAC9B,MAAM,eAAe,CAAC;AAEvB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAAiB;gBAElB,gBAAgB,EAAE,CAAC,YAAY,EAAE,6BAA6B,KAAK,IAAI;IAI5E,QAAQ,IAAI,IAAI,EAAE;IAIZ,iBAAiB,CAC5B,OAAO,EAAE,uBAAuB,CAAC,QAAQ,CAAC,EAC1C,EAAE,cAAc,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,gBAAgB,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAC3F,OAAO,CAAC,cAAc,CAAC;IA8H1B,OAAO,CAAC,iBAAiB;CAI1B"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LinkedApiMCPServer = void 0;
|
|
4
|
+
const node_1 = require("@linkedapi/node");
|
|
5
|
+
const core_1 = require("@linkedapi/node/dist/core");
|
|
6
|
+
const linked_api_tools_1 = require("./linked-api-tools");
|
|
7
|
+
const define_request_timeout_1 = require("./utils/define-request-timeout");
|
|
8
|
+
const handle_linked_api_error_1 = require("./utils/handle-linked-api-error");
|
|
9
|
+
const logger_1 = require("./utils/logger");
|
|
10
|
+
class LinkedApiMCPServer {
|
|
11
|
+
tools;
|
|
12
|
+
constructor(progressCallback) {
|
|
13
|
+
this.tools = new linked_api_tools_1.LinkedApiTools(progressCallback);
|
|
14
|
+
}
|
|
15
|
+
getTools() {
|
|
16
|
+
return this.tools.tools.map((tool) => tool.getTool());
|
|
17
|
+
}
|
|
18
|
+
async executeWithTokens(request, { linkedApiToken, identificationToken, mcpClient }) {
|
|
19
|
+
const workflowTimeout = (0, define_request_timeout_1.defineRequestTimeoutInSeconds)(mcpClient) * 1000;
|
|
20
|
+
logger_1.logger.info({
|
|
21
|
+
toolName: request.name,
|
|
22
|
+
arguments: request.arguments,
|
|
23
|
+
mcpClient,
|
|
24
|
+
workflowTimeout,
|
|
25
|
+
}, 'Tool execution started');
|
|
26
|
+
const linkedapi = new node_1.LinkedApi((0, core_1.buildLinkedApiHttpClient)({
|
|
27
|
+
linkedApiToken: linkedApiToken,
|
|
28
|
+
identificationToken: identificationToken,
|
|
29
|
+
}, 'mcp'));
|
|
30
|
+
const { name: toolName, arguments: args, _meta } = request;
|
|
31
|
+
const progressToken = _meta?.progressToken;
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
try {
|
|
34
|
+
const tool = this.tools.toolByName(toolName);
|
|
35
|
+
if (!tool) {
|
|
36
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
37
|
+
}
|
|
38
|
+
const params = tool.validate(args);
|
|
39
|
+
const { data, errors } = await tool.execute({
|
|
40
|
+
linkedapi,
|
|
41
|
+
args: params,
|
|
42
|
+
workflowTimeout,
|
|
43
|
+
progressToken,
|
|
44
|
+
});
|
|
45
|
+
const endTime = Date.now();
|
|
46
|
+
const duration = `${((endTime - startTime) / 1000).toFixed(2)} seconds`;
|
|
47
|
+
if (errors.length > 0 && !data) {
|
|
48
|
+
logger_1.logger.error({
|
|
49
|
+
toolName,
|
|
50
|
+
duration,
|
|
51
|
+
errors,
|
|
52
|
+
}, 'Tool execution failed');
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: errors.map((e) => e.message).join('\n'),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
logger_1.logger.info({
|
|
63
|
+
toolName,
|
|
64
|
+
duration,
|
|
65
|
+
data,
|
|
66
|
+
}, 'Tool execution successful');
|
|
67
|
+
if (data) {
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: JSON.stringify(data, null, 2),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
content: [
|
|
79
|
+
{
|
|
80
|
+
type: 'text',
|
|
81
|
+
text: 'Completed',
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const duration = this.calculateDuration(startTime);
|
|
88
|
+
if (error instanceof node_1.LinkedApiError) {
|
|
89
|
+
const body = (0, handle_linked_api_error_1.handleLinkedApiError)(error);
|
|
90
|
+
logger_1.logger.error({
|
|
91
|
+
toolName,
|
|
92
|
+
duration,
|
|
93
|
+
body,
|
|
94
|
+
}, 'Tool execution failed with Linked API error');
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: 'text',
|
|
99
|
+
text: JSON.stringify(body, null, 2),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
105
|
+
logger_1.logger.error({
|
|
106
|
+
toolName,
|
|
107
|
+
duration,
|
|
108
|
+
error: errorMessage,
|
|
109
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
110
|
+
}, 'Tool execution failed with unknown error');
|
|
111
|
+
return {
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
type: 'text',
|
|
115
|
+
text: `Error executing ${toolName}: ${errorMessage}`,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
calculateDuration(startTime) {
|
|
122
|
+
const endTime = Date.now();
|
|
123
|
+
return `${((endTime - startTime) / 1000).toFixed(2)} seconds`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.LinkedApiMCPServer = LinkedApiMCPServer;
|
|
127
|
+
//# sourceMappingURL=linked-api-server.js.map
|