connected-workspace-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +17 -0
- package/CONTRIBUTING.md +47 -0
- package/LICENSE +21 -0
- package/README.md +123 -0
- package/dist/src/auth/google/authorize.js +71 -0
- package/dist/src/auth/google/index.js +27 -0
- package/dist/src/auth/linkedin/authorize.js +93 -0
- package/dist/src/auth/linkedin/index.js +16 -0
- package/dist/src/auth/token-store.js +36 -0
- package/dist/src/config/arguments.js +19 -0
- package/dist/src/config/bootstrap.js +2 -0
- package/dist/src/config/environment.js +14 -0
- package/dist/src/index.js +64 -0
- package/dist/src/logging/logger.js +66 -0
- package/dist/src/tools/calendar/index.js +123 -0
- package/dist/src/tools/gmail/index.js +177 -0
- package/dist/src/tools/linkedin/client.js +122 -0
- package/dist/src/tools/linkedin/index.js +52 -0
- package/dist/src/tools/shared.js +33 -0
- package/dist/src/utils/common.js +25 -0
- package/docs/README.md +25 -0
- package/docs/configuration.md +59 -0
- package/docs/google-auth.md +60 -0
- package/docs/installation.md +84 -0
- package/docs/linkedin-auth.md +61 -0
- package/docs/publishing.md +52 -0
- package/docs/tools.md +40 -0
- package/docs/troubleshooting.md +61 -0
- package/package.json +79 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Installation And MCP Setup
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
- Node.js 20 or newer
|
|
6
|
+
- An MCP-compatible host such as VS Code
|
|
7
|
+
- Google Cloud OAuth credentials
|
|
8
|
+
- Optional LinkedIn developer application credentials
|
|
9
|
+
|
|
10
|
+
## Install From npm
|
|
11
|
+
|
|
12
|
+
Install globally when you want stable command names:
|
|
13
|
+
|
|
14
|
+
```powershell
|
|
15
|
+
npm install --global connected-workspace-mcp
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Available commands:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
connected-workspace-mcp
|
|
22
|
+
connected-workspace-google-auth
|
|
23
|
+
connected-workspace-linkedin-auth
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
You can also run the server without a global installation:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
npx -y connected-workspace-mcp --env-file "C:\Users\you\.connected-workspace-mcp\.env"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configure The Environment
|
|
33
|
+
|
|
34
|
+
Create a private configuration directory, copy `.env.example` from the package
|
|
35
|
+
or repository, and populate the provider client settings. Pass its path with
|
|
36
|
+
`--env-file` when the current working directory does not contain `.env`.
|
|
37
|
+
|
|
38
|
+
On Windows, explicit persistent paths can look like:
|
|
39
|
+
|
|
40
|
+
```dotenv
|
|
41
|
+
PA_MCP_TOKEN_PATH=C:/Users/you/.connected-workspace-mcp/tokens.json
|
|
42
|
+
PA_MCP_LOG_PATH=C:/Users/you/.connected-workspace-mcp/server.log
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See [configuration.md](configuration.md) for every setting.
|
|
46
|
+
|
|
47
|
+
## VS Code MCP Configuration
|
|
48
|
+
|
|
49
|
+
For an npm-installed server, add a server entry equivalent to:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"servers": {
|
|
54
|
+
"connected-workspace": {
|
|
55
|
+
"type": "stdio",
|
|
56
|
+
"command": "npx",
|
|
57
|
+
"args": [
|
|
58
|
+
"-y",
|
|
59
|
+
"connected-workspace-mcp",
|
|
60
|
+
"--env-file",
|
|
61
|
+
"C:\\Users\\you\\.connected-workspace-mcp\\.env"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Alternatively, set provider values in the MCP host's `env` configuration. Never
|
|
69
|
+
place secrets directly in `args`, where process inspection may expose them.
|
|
70
|
+
Restart the MCP server after changing configuration or authorization.
|
|
71
|
+
|
|
72
|
+
## Local Development
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
npm install
|
|
76
|
+
Copy-Item .env.example .env
|
|
77
|
+
npm run auth:google
|
|
78
|
+
npm run auth:linkedin
|
|
79
|
+
npm run build
|
|
80
|
+
npm start
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The repository includes `.vscode/mcp.json` for running the compiled local
|
|
84
|
+
server.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# LinkedIn OAuth Setup
|
|
2
|
+
|
|
3
|
+
## Create The LinkedIn Application
|
|
4
|
+
|
|
5
|
+
1. Open https://www.linkedin.com/developers/apps and create or select an app.
|
|
6
|
+
2. Associate and verify the appropriate LinkedIn Page.
|
|
7
|
+
3. Enable **Sign In with LinkedIn using OpenID Connect**.
|
|
8
|
+
4. Enable **Share on LinkedIn**.
|
|
9
|
+
5. Add this exact authorized redirect URL:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
http://localhost:3001/callback
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Configure:
|
|
16
|
+
|
|
17
|
+
```dotenv
|
|
18
|
+
LINKEDIN_CLIENT_ID=your-client-id
|
|
19
|
+
LINKEDIN_CLIENT_SECRET=your-client-secret
|
|
20
|
+
LINKEDIN_REDIRECT_URI=http://localhost:3001/callback
|
|
21
|
+
LINKEDIN_API_VERSION=202609
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Required Scopes
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
openid
|
|
28
|
+
profile
|
|
29
|
+
email
|
|
30
|
+
w_member_social
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Authorize
|
|
34
|
+
|
|
35
|
+
From a source checkout:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
npm run auth:linkedin
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
After a global npm installation:
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
44
|
+
connected-workspace-linkedin-auth
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The callback validates OAuth state, exchanges the authorization code, reads the
|
|
48
|
+
OpenID member identifier, and persists the token with its expiry metadata.
|
|
49
|
+
|
|
50
|
+
## API Limitations
|
|
51
|
+
|
|
52
|
+
Standard LinkedIn member APIs can read basic OpenID identity information and
|
|
53
|
+
manage posts when the app has approved products and scopes. They do not permit
|
|
54
|
+
arbitrary edits to headline, experience, education, or skills. Messaging and
|
|
55
|
+
some analytics require partner-only access.
|
|
56
|
+
|
|
57
|
+
LinkedIn access tokens expire. If LinkedIn does not grant your application a
|
|
58
|
+
refresh token, rerun authorization after expiry.
|
|
59
|
+
|
|
60
|
+
See [Authentication troubleshooting](troubleshooting.md) for product approval,
|
|
61
|
+
redirect URI, and `401 Unauthorized` checks.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Publishing To npm
|
|
2
|
+
|
|
3
|
+
The package name is `connected-workspace-mcp`. Confirm availability directly
|
|
4
|
+
against npmjs immediately before the first publish.
|
|
5
|
+
|
|
6
|
+
## Before The First Publish
|
|
7
|
+
|
|
8
|
+
1. Confirm the GitHub repository URL in `package.json` is public and correct.
|
|
9
|
+
2. Confirm `.env` contains no values that should be copied into documentation.
|
|
10
|
+
3. Rotate any credentials that have been shared outside your password manager.
|
|
11
|
+
4. Add an `NPM_AUTH_TOKEN` repository secret with permission to publish the
|
|
12
|
+
package.
|
|
13
|
+
|
|
14
|
+
## Validate
|
|
15
|
+
|
|
16
|
+
```powershell
|
|
17
|
+
npm run format:check
|
|
18
|
+
npm test
|
|
19
|
+
npm run check
|
|
20
|
+
npm run build
|
|
21
|
+
npm pack --dry-run
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The tarball should include only compiled `dist` files, documentation,
|
|
25
|
+
`.env.example`, and top-level package metadata. It must not include `.env`,
|
|
26
|
+
tests, source files, tokens, logs, or coverage output.
|
|
27
|
+
|
|
28
|
+
## Publish
|
|
29
|
+
|
|
30
|
+
The recommended release path is to create a GitHub Release with a tag matching
|
|
31
|
+
`v<version>`, for example `v1.0.0`. The release workflow validates the project,
|
|
32
|
+
sets the package version from the tag, and publishes with npm provenance.
|
|
33
|
+
|
|
34
|
+
For a manual release:
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
npm login --registry=https://registry.npmjs.org/
|
|
38
|
+
npm publish
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The package uses public access and the official npm registry through
|
|
42
|
+
`publishConfig`. The `prepack` script automatically checks formatting, runs all
|
|
43
|
+
tests, and rebuilds before a tarball or publish is created.
|
|
44
|
+
|
|
45
|
+
For later releases, update the version first:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
npm version patch
|
|
49
|
+
npm publish
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use `minor` or `major` instead when the change warrants it.
|
package/docs/tools.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Tool Reference
|
|
2
|
+
|
|
3
|
+
## Gmail
|
|
4
|
+
|
|
5
|
+
| Tool | Purpose |
|
|
6
|
+
| ---------------------- | --------------------------------------------------- |
|
|
7
|
+
| `gmail_search` | Search with Gmail query syntax and return summaries |
|
|
8
|
+
| `gmail_get_message` | Read headers and decoded message text |
|
|
9
|
+
| `gmail_send_message` | Send a plain-text email |
|
|
10
|
+
| `gmail_reply` | Reply within an existing thread |
|
|
11
|
+
| `gmail_modify_message` | Add or remove labels such as `UNREAD` or `STARRED` |
|
|
12
|
+
|
|
13
|
+
## Google Calendar
|
|
14
|
+
|
|
15
|
+
| Tool | Purpose |
|
|
16
|
+
| ----------------------- | ------------------------------------------------- |
|
|
17
|
+
| `calendar_list_events` | List ordered events in a time range |
|
|
18
|
+
| `calendar_create_event` | Schedule an event and optionally notify attendees |
|
|
19
|
+
| `calendar_update_event` | Patch selected fields on an event |
|
|
20
|
+
| `calendar_delete_event` | Delete an event |
|
|
21
|
+
| `calendar_free_busy` | Read busy periods for one or more calendars |
|
|
22
|
+
|
|
23
|
+
## LinkedIn
|
|
24
|
+
|
|
25
|
+
| Tool | Purpose |
|
|
26
|
+
| ------------------------- | --------------------------------------------- |
|
|
27
|
+
| `linkedin_get_profile` | Read the authenticated OpenID profile |
|
|
28
|
+
| `linkedin_list_posts` | List posts authored by the member |
|
|
29
|
+
| `linkedin_get_post` | Read a post by URN |
|
|
30
|
+
| `linkedin_get_engagement` | Read available social action summaries |
|
|
31
|
+
| `linkedin_publish_text` | Publish a text post |
|
|
32
|
+
| `linkedin_publish_image` | Upload a local image and publish it with text |
|
|
33
|
+
| `linkedin_delete_post` | Permanently delete an owned post |
|
|
34
|
+
|
|
35
|
+
## Write Safety
|
|
36
|
+
|
|
37
|
+
Sending email, modifying labels, creating/updating/deleting events, and
|
|
38
|
+
publishing/deleting posts change live provider data. Configure your MCP host to
|
|
39
|
+
require confirmation for write tools. Automated Jest tests mock every provider
|
|
40
|
+
and never perform these actions on real accounts.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Authentication Troubleshooting
|
|
2
|
+
|
|
3
|
+
Never include client secrets, access tokens, refresh tokens, complete email
|
|
4
|
+
bodies, or complete logs in issues or support requests.
|
|
5
|
+
|
|
6
|
+
## Google `invalid_grant`
|
|
7
|
+
|
|
8
|
+
In Google Cloud Console, verify that Gmail API and Google Calendar API are
|
|
9
|
+
enabled and that the OAuth client configured in `.env` is a Desktop app. The
|
|
10
|
+
client ID and secret must belong to the same client, and the redirect URI must
|
|
11
|
+
be exactly:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
http://localhost:3000
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If the consent screen is in testing mode, add the account under **Test users**.
|
|
18
|
+
Testing-mode refresh tokens may expire after seven days. Confirm that all four
|
|
19
|
+
required scopes in the [Google setup guide](google-auth.md) are approved.
|
|
20
|
+
|
|
21
|
+
Common causes include a revoked or expired refresh token, credentials from a
|
|
22
|
+
different OAuth client, a changed account password, too many issued refresh
|
|
23
|
+
tokens, a redirect mismatch, or an incorrect system clock. Remove the old app
|
|
24
|
+
grant at https://myaccount.google.com/connections and authorize again when
|
|
25
|
+
needed.
|
|
26
|
+
|
|
27
|
+
## LinkedIn `401 Unauthorized`
|
|
28
|
+
|
|
29
|
+
In LinkedIn Developer Console, verify that the app is active, associated with a
|
|
30
|
+
verified LinkedIn Page, and has active access to both **Sign In with LinkedIn
|
|
31
|
+
using OpenID Connect** and **Share on LinkedIn**. Requested products are not
|
|
32
|
+
usable until LinkedIn approves them.
|
|
33
|
+
|
|
34
|
+
Confirm the client ID, client secret, required scopes, and this exact redirect:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
http://localhost:3001/callback
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
A 401 commonly means the access token expired, was revoked, belongs to another
|
|
41
|
+
app, or lacks an approved product or scope. Standard apps may not receive
|
|
42
|
+
refresh tokens, so reauthorization after expiry can be expected.
|
|
43
|
+
|
|
44
|
+
## Reauthorize And Restart
|
|
45
|
+
|
|
46
|
+
From a source checkout:
|
|
47
|
+
|
|
48
|
+
```powershell
|
|
49
|
+
npm run auth:google
|
|
50
|
+
npm run auth:linkedin
|
|
51
|
+
npm run build
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For a global npm installation, use
|
|
55
|
+
`connected-workspace-google-auth` or
|
|
56
|
+
`connected-workspace-linkedin-auth`. Restart the MCP server afterward so it
|
|
57
|
+
reloads the token store.
|
|
58
|
+
|
|
59
|
+
Run `npm run test:auth` to validate local token persistence and client
|
|
60
|
+
construction. Passing mocked tests does not prove that a live provider accepts
|
|
61
|
+
a token.
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "connected-workspace-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "MCP server for Gmail, Google Calendar, and LinkedIn communication workflows",
|
|
6
|
+
"author": "Deepak Kamboj",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepakkamboj/connected-workspace-mcp.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/deepakkamboj/connected-workspace-mcp#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/deepakkamboj/connected-workspace-mcp/issues"
|
|
15
|
+
},
|
|
16
|
+
"main": "dist/src/index.js",
|
|
17
|
+
"bin": {
|
|
18
|
+
"connected-workspace-mcp": "dist/src/index.js",
|
|
19
|
+
"connected-workspace-google-auth": "dist/src/auth/google/authorize.js",
|
|
20
|
+
"connected-workspace-linkedin-auth": "dist/src/auth/linkedin/authorize.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/",
|
|
24
|
+
"docs/",
|
|
25
|
+
".env.example",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CONTRIBUTING.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"mcp",
|
|
32
|
+
"model-context-protocol",
|
|
33
|
+
"gmail",
|
|
34
|
+
"google-calendar",
|
|
35
|
+
"linkedin",
|
|
36
|
+
"social-networking",
|
|
37
|
+
"productivity"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public",
|
|
41
|
+
"registry": "https://registry.npmjs.org/"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.json",
|
|
45
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"format": "prettier --write .",
|
|
47
|
+
"format:check": "prettier --check .",
|
|
48
|
+
"prepack": "npm run format:check && npm test && npm run build",
|
|
49
|
+
"test": "jest --runInBand",
|
|
50
|
+
"test:auth": "jest --runInBand --runTestsByPath tests/auth.test.ts",
|
|
51
|
+
"test:gmail": "jest --runInBand --runTestsByPath tests/gmail-tools.test.ts",
|
|
52
|
+
"test:calendar": "jest --runInBand --runTestsByPath tests/calendar-tools.test.ts",
|
|
53
|
+
"test:linkedin": "jest --runInBand --runTestsByPath tests/linkedin-tools.test.ts tests/linkedin-client.test.ts",
|
|
54
|
+
"test:coverage": "jest --runInBand --coverage",
|
|
55
|
+
"dev": "tsx src/index.ts",
|
|
56
|
+
"start": "node dist/src/index.js",
|
|
57
|
+
"auth": "npm run auth:google",
|
|
58
|
+
"auth:google": "tsx src/auth/google/authorize.ts",
|
|
59
|
+
"auth:linkedin": "tsx src/auth/linkedin/authorize.ts"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
63
|
+
"dotenv": "^17.0.0",
|
|
64
|
+
"googleapis": "^160.0.0",
|
|
65
|
+
"zod": "^4.0.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/jest": "^30.0.0",
|
|
69
|
+
"@types/node": "^24.0.0",
|
|
70
|
+
"jest": "^30.5.1",
|
|
71
|
+
"prettier": "^3.9.6",
|
|
72
|
+
"ts-jest": "^29.4.12",
|
|
73
|
+
"tsx": "^4.20.0",
|
|
74
|
+
"typescript": "^5.9.0"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=20"
|
|
78
|
+
}
|
|
79
|
+
}
|