@gpsglobal-ai/gpsglobal 1.4.1 → 1.4.5
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/CHANGELOG.md +21 -0
- package/LICENSE +40 -0
- package/README.md +143 -18
- package/dist/cli/doctor.js +15 -7
- package/dist/cli/setup.js +6 -4
- package/dist/cli.js +7 -7
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +9 -1
- package/dist/http.d.ts +3 -0
- package/dist/http.js +9 -2
- package/dist/index.js +12 -3
- package/dist/lib/host-config.js +4 -2
- package/dist/lib/public-api-base.d.ts +3 -0
- package/dist/lib/public-api-base.js +8 -0
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog — gpsglobal
|
|
2
2
|
|
|
3
|
+
## 1.4.5 — 2026-06-21
|
|
4
|
+
|
|
5
|
+
- **Production defaults:** `setup` and `login` use `https://lp.gpsglobal.ai` (not `localhost:8080`)
|
|
6
|
+
- **`setup` default mode:** `oauth` — Cursor/VS Code/GitHub get URL-only `https://lp.gpsglobal.ai/mcp`
|
|
7
|
+
- **Claude Desktop:** still gets stdio + `envFile` when mode is `oauth` (Desktop has no reliable HTTP OAuth)
|
|
8
|
+
- **`doctor`:** probes `${apiBase}/mcp` → expects 401 on production (not localhost:3100)
|
|
9
|
+
- Local dev: `GPS_API_BASE=http://localhost:8080 npx @gpsglobal-ai/gpsglobal setup --mode=stdio`
|
|
10
|
+
|
|
11
|
+
## 1.4.4 — 2026-06-18
|
|
12
|
+
|
|
13
|
+
- CI: disable npm provenance (private GitHub repo — OIDC publish still works)
|
|
14
|
+
|
|
15
|
+
## 1.4.3 — 2026-06-18
|
|
16
|
+
|
|
17
|
+
- CI: fix OIDC publish — do not inject `NODE_AUTH_TOKEN` via `setup-node` `registry-url`
|
|
18
|
+
|
|
19
|
+
## 1.4.2 — 2026-06-18
|
|
20
|
+
|
|
21
|
+
- **README** — LP-facing install guide, host matrix, security, troubleshooting
|
|
22
|
+
- **LICENSE** — proprietary GPS Global terms (not open source); `SEE LICENSE IN LICENSE`
|
|
23
|
+
|
|
3
24
|
## 1.4.1 — 2026-06-17
|
|
4
25
|
|
|
5
26
|
- **npm scope:** publish as `@gpsglobal-ai/gpsglobal` under org `gpsglobal-ai`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
GPS Global — Proprietary Software License
|
|
2
|
+
@gpsglobal-ai/gpsglobal MCP Server
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 GPS Global. All rights reserved.
|
|
5
|
+
|
|
6
|
+
NOTICE: This software is NOT open source. Public distribution on npm does not
|
|
7
|
+
grant any rights beyond those expressly stated below.
|
|
8
|
+
|
|
9
|
+
1. GRANT OF LICENSE
|
|
10
|
+
Subject to your valid GPS LP Workspace account and applicable agreement
|
|
11
|
+
with GPS Global (or its affiliates), you are granted a limited,
|
|
12
|
+
non-exclusive, non-transferable, revocable license to install and use
|
|
13
|
+
this MCP server package solely to access fund wiki content made available
|
|
14
|
+
to you through the GPS LP platform.
|
|
15
|
+
|
|
16
|
+
2. RESTRICTIONS
|
|
17
|
+
You may not:
|
|
18
|
+
- copy, modify, merge, publish, distribute, sublicense, or sell this software;
|
|
19
|
+
- reverse engineer, decompile, or disassemble the software, except where
|
|
20
|
+
prohibited by applicable law;
|
|
21
|
+
- use the software to access data belonging to another LP or bypass
|
|
22
|
+
GPS authentication or authorization controls;
|
|
23
|
+
- remove or alter proprietary notices.
|
|
24
|
+
|
|
25
|
+
3. OWNERSHIP
|
|
26
|
+
GPS Global and its licensors retain all right, title, and interest in and
|
|
27
|
+
to the software. No rights are granted except as expressly set forth herein.
|
|
28
|
+
|
|
29
|
+
4. TERMINATION
|
|
30
|
+
This license terminates automatically if you breach these terms or lose
|
|
31
|
+
authorized access to the GPS LP platform. Upon termination, you must cease
|
|
32
|
+
all use and destroy copies in your possession.
|
|
33
|
+
|
|
34
|
+
5. DISCLAIMER
|
|
35
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
36
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
38
|
+
|
|
39
|
+
6. CONTACT
|
|
40
|
+
Licensing inquiries: https://lp.gpsglobal.ai
|
package/README.md
CHANGED
|
@@ -1,33 +1,158 @@
|
|
|
1
1
|
# @gpsglobal-ai/gpsglobal
|
|
2
2
|
|
|
3
|
-
GPS LP fund wiki
|
|
3
|
+
**GPS LP fund wiki MCP server** — connect Cursor, GitHub Copilot, VS Code, and Claude to your GPS fund vault wikis.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|--|--|
|
|
7
|
-
| **npm** | `@gpsglobal-ai/gpsglobal` |
|
|
8
|
-
| **MCP server key** | `gpsglobal` |
|
|
9
|
-
| **CLI** | `gpsglobal` (after install) |
|
|
5
|
+
> **Licensed software** — not open source. Use is limited to authorized GPS Limited Partners. See [LICENSE](./LICENSE).
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it does
|
|
10
|
+
|
|
11
|
+
This package implements a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server so AI assistants can read **your** GPS fund knowledge wikis securely:
|
|
12
|
+
|
|
13
|
+
| Tool | Description |
|
|
14
|
+
|------|-------------|
|
|
15
|
+
| `list_funds` | List funds in your LP vault (with `has_wiki` metadata) |
|
|
16
|
+
| `get_fund_wiki` | Return the full markdown wiki for a fund |
|
|
17
|
+
|
|
18
|
+
Data never leaves GPS infrastructure except through your authenticated session — the MCP proxies to `https://lp.gpsglobal.ai` with LP-scoped JWT or OAuth tokens.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Who this is for
|
|
23
|
+
|
|
24
|
+
- **GPS Limited Partners** with access to [LP Workspace](https://lp.gpsglobal.ai)
|
|
25
|
+
- **Not** for GP operators, content managers, or unauthenticated use
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Quick start (recommended)
|
|
30
|
+
|
|
31
|
+
One command — browser sign-in at **production**, credentials saved locally, configs merged for major AI hosts:
|
|
12
32
|
|
|
13
33
|
```bash
|
|
14
34
|
npx @gpsglobal-ai/gpsglobal setup
|
|
15
35
|
```
|
|
16
36
|
|
|
17
|
-
|
|
37
|
+
This opens `https://lp.gpsglobal.ai` for OAuth, writes `~/.gps/mcp.env` (mode `600`), and updates **Cursor** (OAuth URL), **VS Code**, **GitHub Copilot**, and **Claude Desktop** (stdio) configs.
|
|
38
|
+
|
|
39
|
+
**Restart your AI tool**, then ask: *"List my GPS funds using gpsglobal"*.
|
|
40
|
+
|
|
41
|
+
**Local Docker dev** (backend on `localhost:8080`):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
GPS_API_BASE=http://localhost:8080 npx @gpsglobal-ai/gpsglobal setup --mode=stdio
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Other commands
|
|
48
|
+
|
|
49
|
+
| Goal | Command |
|
|
50
|
+
|------|---------|
|
|
51
|
+
| stdio-only (all hosts) | `npx @gpsglobal-ai/gpsglobal setup --mode=stdio` |
|
|
52
|
+
| Verify install + backend reachability | `npx @gpsglobal-ai/gpsglobal doctor` |
|
|
53
|
+
| Print config snippets for all hosts | `npx @gpsglobal-ai/gpsglobal print-config` |
|
|
54
|
+
| Refresh credentials | `npx @gpsglobal-ai/gpsglobal login --browser --refresh` |
|
|
55
|
+
|
|
56
|
+
Global install (optional):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install -g @gpsglobal-ai/gpsglobal
|
|
60
|
+
gpsglobal setup
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Supported AI hosts
|
|
18
66
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
67
|
+
| Host | Setup mode | Config key |
|
|
68
|
+
|------|------------|------------|
|
|
69
|
+
| **Cursor** | `setup` (default oauth) | `gpsglobal` |
|
|
70
|
+
| **VS Code / GitHub Copilot** | `setup` | `gpsglobal` |
|
|
71
|
+
| **Claude Desktop** | `setup` (stdio via envFile) | `gpsglobal` |
|
|
72
|
+
| **Claude Code** | `claude mcp add --transport http gpsglobal https://lp.gpsglobal.ai/mcp` | `gpsglobal` |
|
|
24
73
|
|
|
25
|
-
|
|
74
|
+
**OAuth Connect (production):** hosts discover auth via `https://lp.gpsglobal.ai/mcp` — no manual JWT paste.
|
|
26
75
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
76
|
+
**Cursor example** (`~/.cursor/mcp.json`):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"gpsglobal": {
|
|
82
|
+
"url": "https://lp.gpsglobal.ai/mcp"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Stdio example** (Claude Desktop, local dev):
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"gpsglobal": {
|
|
94
|
+
"command": "npx",
|
|
95
|
+
"args": ["-y", "@gpsglobal-ai/gpsglobal", "--stdio"],
|
|
96
|
+
"envFile": "${userHome}/.gps/mcp.env"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Security
|
|
105
|
+
|
|
106
|
+
- Credentials live in `~/.gps/mcp.env` — **never** commit tokens to git
|
|
107
|
+
- MCP HTTP uses **OAuth 2.1 + PKCE** with scoped tokens (`aud` + `mcp:read`)
|
|
108
|
+
- LP isolation enforced server-side — you only see your own vault
|
|
109
|
+
- OAuth tokens expire after 1 hour; run `login --refresh` or reconnect in your host
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Package identity
|
|
114
|
+
|
|
115
|
+
| | Value |
|
|
116
|
+
|--|-------|
|
|
117
|
+
| npm package | `@gpsglobal-ai/gpsglobal` |
|
|
118
|
+
| MCP server name (in host config) | `gpsglobal` |
|
|
119
|
+
| CLI binary (after global install) | `gpsglobal` |
|
|
120
|
+
| Production MCP endpoint | `https://lp.gpsglobal.ai/mcp` |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Requirements
|
|
125
|
+
|
|
126
|
+
- Node.js **18+**
|
|
127
|
+
- Valid GPS LP account on [lp.gpsglobal.ai](https://lp.gpsglobal.ai)
|
|
128
|
+
- Network access to the GPS API (local dev: `make dev` stack on ports 8080 / 3100)
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Troubleshooting
|
|
133
|
+
|
|
134
|
+
| Issue | Fix |
|
|
135
|
+
|-------|-----|
|
|
136
|
+
| Tools return 401 | `npx @gpsglobal-ai/gpsglobal login --browser --refresh` |
|
|
137
|
+
| Host shows disconnected | Restart the AI app after `setup` |
|
|
138
|
+
| `doctor` fails | Ensure you are whitelisted on prod; check `GPS_API_BASE` in `~/.gps/mcp.env` (should be `https://lp.gpsglobal.ai`) |
|
|
139
|
+
| OAuth Connect loop | Confirm Cursor/VS Code config is URL-only (no stale Bearer header) |
|
|
140
|
+
|
|
141
|
+
---
|
|
30
142
|
|
|
31
143
|
## License
|
|
32
144
|
|
|
33
|
-
|
|
145
|
+
**Proprietary — not open source.**
|
|
146
|
+
|
|
147
|
+
Copyright © 2026 GPS Global. All rights reserved.
|
|
148
|
+
|
|
149
|
+
This package is published on npm for convenient installation by **authorized GPS Limited Partners only**. See [LICENSE](./LICENSE) for full terms.
|
|
150
|
+
|
|
151
|
+
Unauthorized copying, modification, distribution, or reverse engineering is prohibited.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Links
|
|
156
|
+
|
|
157
|
+
- LP Workspace: https://lp.gpsglobal.ai
|
|
158
|
+
- MCP specification: https://modelcontextprotocol.io
|
package/dist/cli/doctor.js
CHANGED
|
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|
|
2
2
|
import { GpsApiClient } from '../clients/gps-api.js';
|
|
3
3
|
import { loadGpsConfig, normalizeApiBase, DEFAULT_ENV_PATH } from '../config/env.js';
|
|
4
4
|
import { decodeGpsJwt } from '../lib/jwt.js';
|
|
5
|
+
import { resolveMcpPublicUrl } from '../lib/host-config.js';
|
|
5
6
|
export async function runDoctor() {
|
|
6
7
|
const checks = [];
|
|
7
8
|
let config;
|
|
@@ -53,22 +54,29 @@ export async function runDoctor() {
|
|
|
53
54
|
detail: err instanceof Error ? err.message : String(err),
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
|
-
const mcpUrl =
|
|
57
|
+
const mcpUrl = resolveMcpPublicUrl(config.apiBase);
|
|
57
58
|
try {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const mcpProbe = await axios.get(`${mcpUrl}/mcp`, {
|
|
60
|
+
timeout: 10_000,
|
|
61
|
+
validateStatus: () => true,
|
|
62
|
+
maxRedirects: 0,
|
|
63
|
+
});
|
|
64
|
+
if (mcpProbe.status === 401) {
|
|
65
|
+
checks.push({ name: 'mcp-http', ok: true, detail: `${mcpUrl}/mcp → 401 (discovery OK)` });
|
|
66
|
+
}
|
|
67
|
+
else if (mcpProbe.status === 404) {
|
|
68
|
+
checks.push({ name: 'mcp-http', ok: true, detail: 'stdio mode (no remote /mcp)' });
|
|
61
69
|
}
|
|
62
70
|
else {
|
|
63
71
|
checks.push({
|
|
64
72
|
name: 'mcp-http',
|
|
65
|
-
ok:
|
|
66
|
-
detail: `${mcpUrl}/
|
|
73
|
+
ok: mcpProbe.status === 200,
|
|
74
|
+
detail: `${mcpUrl}/mcp → ${mcpProbe.status}`,
|
|
67
75
|
});
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
catch {
|
|
71
|
-
checks.push({ name: 'mcp-http', ok: true, detail: '
|
|
79
|
+
checks.push({ name: 'mcp-http', ok: true, detail: 'remote MCP unreachable (stdio mode OK)' });
|
|
72
80
|
}
|
|
73
81
|
return { ok: checks.every((c) => c.ok), checks };
|
|
74
82
|
}
|
package/dist/cli/setup.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { browserLogin } from './browser-login.js';
|
|
2
|
-
import { DEFAULT_ENV_PATH, normalizeApiBase } from '../config/env.js';
|
|
2
|
+
import { DEFAULT_ENV_PATH, LOCAL_GPS_API_BASE, normalizeApiBase, resolveDefaultApiBase } from '../config/env.js';
|
|
3
3
|
import { MCP_SERVER_KEY, PACKAGE, claudeCodeAddCommand, mergeVsCodeConfig, mergeVsCodeWorkspaceConfig, mergeClaudeDesktopConfig, mergeCursorConfig, buildOAuthConnectEntry, buildRemoteEntry, buildStdioEntry, resolveMcpPublicUrl, writeAllHostConfigs, } from '../lib/host-config.js';
|
|
4
4
|
export async function runSetup(options) {
|
|
5
|
-
const apiBase = normalizeApiBase(options.apiBase ??
|
|
5
|
+
const apiBase = normalizeApiBase(options.apiBase ?? resolveDefaultApiBase());
|
|
6
6
|
const host = options.host ?? 'all';
|
|
7
7
|
const useBrowser = options.useBrowser ?? true;
|
|
8
|
-
const mode = options.mode ?? '
|
|
8
|
+
const mode = options.mode ?? 'oauth';
|
|
9
9
|
const mcpPublic = resolveMcpPublicUrl(apiBase);
|
|
10
|
-
console.log(`GPS MCP setup — configure ${MCP_SERVER_KEY} for your AI tools
|
|
10
|
+
console.log(`GPS MCP setup — configure ${MCP_SERVER_KEY} for your AI tools`);
|
|
11
|
+
console.log(` API: ${apiBase} · MCP: ${mcpPublic}/mcp · mode: ${mode}\n`);
|
|
11
12
|
if (useBrowser) {
|
|
12
13
|
const result = await browserLogin(apiBase);
|
|
13
14
|
console.log(`\n✓ Signed in as ${result.username} (${result.lpId})`);
|
|
@@ -48,5 +49,6 @@ export async function runSetup(options) {
|
|
|
48
49
|
console.log(`\nRun:\n ${claudeCodeAddCommand(mcpPublic, mode === 'oauth' ? 'oauth' : 'remote')}`);
|
|
49
50
|
}
|
|
50
51
|
console.log(`\nVerify: npx ${PACKAGE} doctor`);
|
|
52
|
+
console.log(`Local dev: GPS_API_BASE=${LOCAL_GPS_API_BASE} npx ${PACKAGE} setup --mode=stdio`);
|
|
51
53
|
console.log(`Done. Ask your AI: "list my GPS funds using ${MCP_SERVER_KEY}"`);
|
|
52
54
|
}
|
package/dist/cli.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import readline from 'node:readline/promises';
|
|
3
3
|
import { stdin as input, stdout as output } from 'node:process';
|
|
4
4
|
import { GpsApiClient } from './clients/gps-api.js';
|
|
5
|
-
import { DEFAULT_ENV_PATH, loadGpsConfig,
|
|
5
|
+
import { DEFAULT_ENV_PATH, loadGpsConfig, resolveDefaultApiBase, writeGpsEnvFile, } from './config/env.js';
|
|
6
6
|
import { startStdioServer, startHttpFromEnv } from './index.js';
|
|
7
7
|
import { browserLogin } from './cli/browser-login.js';
|
|
8
8
|
import { runSetup } from './cli/setup.js';
|
|
9
9
|
import { runDoctor, printDoctor } from './cli/doctor.js';
|
|
10
10
|
import { MCP_SERVER_KEY, PACKAGE, buildMcpServersConfig, buildOAuthConnectEntry, buildRemoteEntry, buildStdioEntry, buildVsCodeServersConfig, resolveMcpPublicUrl, } from './lib/host-config.js';
|
|
11
11
|
function printConfig(envPath) {
|
|
12
|
-
const apiBase =
|
|
12
|
+
const apiBase = resolveDefaultApiBase();
|
|
13
13
|
const mcpPublic = resolveMcpPublicUrl(apiBase);
|
|
14
14
|
const stdio = buildStdioEntry(envPath);
|
|
15
15
|
const remote = buildRemoteEntry(mcpPublic);
|
|
@@ -17,7 +17,7 @@ function printConfig(envPath) {
|
|
|
17
17
|
console.log(`
|
|
18
18
|
═══ Easiest: one command (all major hosts) ═══
|
|
19
19
|
npx ${PACKAGE} setup
|
|
20
|
-
npx ${PACKAGE} setup --mode=
|
|
20
|
+
npx ${PACKAGE} setup --mode=stdio ← local dev / Claude Desktop stdio-only
|
|
21
21
|
|
|
22
22
|
═══ Cursor / Claude Desktop (mcpServers) ═══
|
|
23
23
|
${JSON.stringify(buildMcpServersConfig(stdio), null, 2)}
|
|
@@ -46,7 +46,7 @@ async function promptHidden(question) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
async function runLogin(refresh, useBrowser) {
|
|
49
|
-
const apiBase =
|
|
49
|
+
const apiBase = resolveDefaultApiBase();
|
|
50
50
|
if (useBrowser) {
|
|
51
51
|
const result = await browserLogin(apiBase);
|
|
52
52
|
console.log(`\n✓ Credentials saved to ${DEFAULT_ENV_PATH}`);
|
|
@@ -109,8 +109,8 @@ async function main() {
|
|
|
109
109
|
const cmd = args[0];
|
|
110
110
|
if (!cmd || cmd === 'help' || args.includes('--help')) {
|
|
111
111
|
console.log(`Usage:
|
|
112
|
-
npx ${PACKAGE} setup ←
|
|
113
|
-
npx ${PACKAGE} setup --mode=
|
|
112
|
+
npx ${PACKAGE} setup ← production OAuth Connect (https://lp.gpsglobal.ai/mcp)
|
|
113
|
+
npx ${PACKAGE} setup --mode=stdio ← local dev (GPS_API_BASE=http://localhost:8080)
|
|
114
114
|
npx ${PACKAGE} doctor ← verify credentials + backend
|
|
115
115
|
npx ${PACKAGE} login [--browser] [--refresh]
|
|
116
116
|
npx ${PACKAGE} status
|
|
@@ -128,7 +128,7 @@ async function main() {
|
|
|
128
128
|
await runSetup({
|
|
129
129
|
host: host ?? 'all',
|
|
130
130
|
useBrowser: !args.includes('--no-browser'),
|
|
131
|
-
mode: mode ?? '
|
|
131
|
+
mode: mode ?? 'oauth',
|
|
132
132
|
});
|
|
133
133
|
return;
|
|
134
134
|
}
|
package/dist/config/env.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export declare const DEFAULT_ENV_PATH: string;
|
|
2
|
+
/** Production LP Workspace origin — default for published npm package. */
|
|
3
|
+
export declare const DEFAULT_GPS_API_BASE = "https://lp.gpsglobal.ai";
|
|
4
|
+
/** Local Docker backend — opt-in via GPS_API_BASE for developers only. */
|
|
5
|
+
export declare const LOCAL_GPS_API_BASE = "http://localhost:8080";
|
|
6
|
+
/** Resolve API base: explicit env → production (not localhost). */
|
|
7
|
+
export declare function resolveDefaultApiBase(): string;
|
|
2
8
|
export interface GpsEnvConfig {
|
|
3
9
|
apiBase: string;
|
|
4
10
|
accessToken: string;
|
package/dist/config/env.js
CHANGED
|
@@ -2,6 +2,14 @@ import fs from 'node:fs';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
export const DEFAULT_ENV_PATH = path.join(os.homedir(), '.gps', 'mcp.env');
|
|
5
|
+
/** Production LP Workspace origin — default for published npm package. */
|
|
6
|
+
export const DEFAULT_GPS_API_BASE = 'https://lp.gpsglobal.ai';
|
|
7
|
+
/** Local Docker backend — opt-in via GPS_API_BASE for developers only. */
|
|
8
|
+
export const LOCAL_GPS_API_BASE = 'http://localhost:8080';
|
|
9
|
+
/** Resolve API base: explicit env → production (not localhost). */
|
|
10
|
+
export function resolveDefaultApiBase() {
|
|
11
|
+
return normalizeApiBase(process.env.GPS_API_BASE ?? DEFAULT_GPS_API_BASE);
|
|
12
|
+
}
|
|
5
13
|
export function parseEnvFile(content) {
|
|
6
14
|
const out = {};
|
|
7
15
|
for (const line of content.split('\n')) {
|
|
@@ -36,7 +44,7 @@ export function loadGpsConfig(envPath = process.env.GPS_MCP_ENV_PATH ?? DEFAULT_
|
|
|
36
44
|
}
|
|
37
45
|
const parsed = parseEnvFile(fs.readFileSync(envPath, 'utf8'));
|
|
38
46
|
const merged = {
|
|
39
|
-
apiBase: normalizeApiBase(parsed.GPS_API_BASE ??
|
|
47
|
+
apiBase: normalizeApiBase(parsed.GPS_API_BASE ?? DEFAULT_GPS_API_BASE),
|
|
40
48
|
accessToken: parsed.GPS_ACCESS_TOKEN ?? '',
|
|
41
49
|
lpId: parsed.GPS_LP_ID ?? '',
|
|
42
50
|
role: parsed.GPS_ROLE ?? 'lp',
|
package/dist/http.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ export interface HttpServerOptions {
|
|
|
3
3
|
host: string;
|
|
4
4
|
apiBase: string;
|
|
5
5
|
publicBaseUrl: string;
|
|
6
|
+
/** Public GPS API origin for OAuth AS in PRM (defaults to publicBaseUrl). */
|
|
7
|
+
publicApiBase?: string;
|
|
6
8
|
enabled: boolean;
|
|
9
|
+
version?: string;
|
|
7
10
|
}
|
|
8
11
|
export declare function startHttpServer(opts: HttpServerOptions): Promise<void>;
|
package/dist/http.js
CHANGED
|
@@ -5,6 +5,7 @@ import { assertMcpEligibleRole } from './config/env.js';
|
|
|
5
5
|
import { createGpsMcpServer } from './server/factory.js';
|
|
6
6
|
import { decodeGpsJwt } from './lib/jwt.js';
|
|
7
7
|
import { assertMcpHttpToken } from './lib/token-policy.js';
|
|
8
|
+
import { oauthAuthorizationServerUrl, resolvePublicApiBase } from './lib/public-api-base.js';
|
|
8
9
|
function parseBearer(req) {
|
|
9
10
|
const h = req.headers.authorization;
|
|
10
11
|
if (!h?.startsWith('Bearer '))
|
|
@@ -28,15 +29,21 @@ function sendUnauthorized(res, resourceMetadataUrl, message) {
|
|
|
28
29
|
export async function startHttpServer(opts) {
|
|
29
30
|
const app = createMcpExpressApp({ host: opts.host });
|
|
30
31
|
const resourceMetadataUrl = `${opts.publicBaseUrl}/.well-known/oauth-protected-resource`;
|
|
31
|
-
const
|
|
32
|
+
const publicApiBase = resolvePublicApiBase(opts.publicApiBase, opts.publicBaseUrl);
|
|
33
|
+
const authServer = oauthAuthorizationServerUrl(publicApiBase);
|
|
34
|
+
const serviceVersion = opts.version ?? process.env.GPS_MCP_VERSION ?? '1.4.4';
|
|
32
35
|
app.get('/health', (_req, res) => {
|
|
33
36
|
if (!opts.enabled) {
|
|
34
37
|
res.status(503).json({ status: 'disabled', message: 'GPS MCP HTTP is disabled' });
|
|
35
38
|
return;
|
|
36
39
|
}
|
|
37
|
-
res.json({ status: 'ok', service: 'gpsglobal', version:
|
|
40
|
+
res.json({ status: 'ok', service: 'gpsglobal', version: serviceVersion });
|
|
38
41
|
});
|
|
39
42
|
app.get('/.well-known/oauth-protected-resource', (_req, res) => {
|
|
43
|
+
if (!opts.enabled) {
|
|
44
|
+
res.status(503).json({ error: 'GPS MCP is temporarily disabled' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
40
47
|
res.json({
|
|
41
48
|
resource: `${opts.publicBaseUrl}/mcp`,
|
|
42
49
|
authorization_servers: [authServer],
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
2
|
import { GpsApiClient } from './clients/gps-api.js';
|
|
3
|
-
import { loadGpsConfig, normalizeApiBase } from './config/env.js';
|
|
3
|
+
import { loadGpsConfig, normalizeApiBase, LOCAL_GPS_API_BASE } from './config/env.js';
|
|
4
4
|
import { createGpsMcpServer } from './server/factory.js';
|
|
5
5
|
import { startHttpServer } from './http.js';
|
|
6
6
|
export async function startStdioServer() {
|
|
@@ -13,8 +13,17 @@ export async function startStdioServer() {
|
|
|
13
13
|
export async function startHttpFromEnv() {
|
|
14
14
|
const port = Number(process.env.PORT ?? 3100);
|
|
15
15
|
const host = process.env.MCP_HOST ?? '0.0.0.0';
|
|
16
|
-
const apiBase = normalizeApiBase(process.env.GPS_API_BASE ??
|
|
16
|
+
const apiBase = normalizeApiBase(process.env.GPS_API_BASE ?? LOCAL_GPS_API_BASE);
|
|
17
17
|
const publicBaseUrl = normalizeApiBase(process.env.GPS_MCP_PUBLIC_URL ?? `http://localhost:${port}`);
|
|
18
|
+
const publicApiBase = normalizeApiBase(process.env.GPS_MCP_PUBLIC_API_BASE ?? publicBaseUrl);
|
|
18
19
|
const enabled = process.env.GPS_MCP_ENABLED !== 'false';
|
|
19
|
-
await startHttpServer({
|
|
20
|
+
await startHttpServer({
|
|
21
|
+
port,
|
|
22
|
+
host,
|
|
23
|
+
apiBase,
|
|
24
|
+
publicBaseUrl,
|
|
25
|
+
publicApiBase,
|
|
26
|
+
enabled,
|
|
27
|
+
version: process.env.GPS_MCP_VERSION,
|
|
28
|
+
});
|
|
20
29
|
}
|
package/dist/lib/host-config.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import os from 'node:os';
|
|
7
7
|
import path from 'node:path';
|
|
8
|
+
import { DEFAULT_GPS_API_BASE } from '../config/env.js';
|
|
8
9
|
/** npm scoped package under org gpsglobal-ai (see docs/57-mcp/018-npm-publish-and-cicd.md). */
|
|
9
10
|
export const NPM_PACKAGE = '@gpsglobal-ai/gpsglobal';
|
|
10
11
|
/** MCP protocol server key in mcp.json — short, stable across hosts. */
|
|
@@ -133,7 +134,7 @@ export function resolveMcpPublicUrl(apiBase) {
|
|
|
133
134
|
if (normalized.includes('localhost') || normalized.includes('127.0.0.1')) {
|
|
134
135
|
return process.env.GPS_MCP_PUBLIC_URL ?? 'http://localhost:3100';
|
|
135
136
|
}
|
|
136
|
-
return process.env.GPS_MCP_PUBLIC_URL ??
|
|
137
|
+
return process.env.GPS_MCP_PUBLIC_URL ?? (normalized || DEFAULT_GPS_API_BASE);
|
|
137
138
|
}
|
|
138
139
|
export function claudeCodeAddCommand(mcpPublicUrl, mode = 'oauth') {
|
|
139
140
|
const url = `${mcpPublicUrl.replace(/\/+$/, '')}/mcp`;
|
|
@@ -172,7 +173,8 @@ export function writeAllHostConfigs(envPath, mode, mcpPublicUrl, projectRoot = p
|
|
|
172
173
|
catch {
|
|
173
174
|
results.push({ host: 'vscode', path: vscodeUserMcpPath(), written: false });
|
|
174
175
|
}
|
|
175
|
-
|
|
176
|
+
// Claude Desktop has no reliable remote HTTP + OAuth — always stdio + envFile.
|
|
177
|
+
if (mode === 'stdio' || mode === 'oauth') {
|
|
176
178
|
try {
|
|
177
179
|
results.push({
|
|
178
180
|
host: 'claude-desktop',
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Public GPS API origin for OAuth PRM (external clients). Internal GPS_API_BASE may differ in ECS. */
|
|
2
|
+
export declare function resolvePublicApiBase(publicApiBase: string | undefined, publicMcpUrl: string): string;
|
|
3
|
+
export declare function oauthAuthorizationServerUrl(publicApiBase: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Public GPS API origin for OAuth PRM (external clients). Internal GPS_API_BASE may differ in ECS. */
|
|
2
|
+
export function resolvePublicApiBase(publicApiBase, publicMcpUrl) {
|
|
3
|
+
const base = (publicApiBase ?? publicMcpUrl).replace(/\/+$/, '');
|
|
4
|
+
return base;
|
|
5
|
+
}
|
|
6
|
+
export function oauthAuthorizationServerUrl(publicApiBase) {
|
|
7
|
+
return `${publicApiBase.replace(/\/+$/, '')}/api/v2/oauth/mcp-cli`;
|
|
8
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gpsglobal-ai/gpsglobal",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "GPS LP fund wiki MCP server — list_funds and get_fund_wiki for Cursor, Copilot, Claude",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"dist",
|
|
20
20
|
"templates",
|
|
21
21
|
"README.md",
|
|
22
|
-
"CHANGELOG.md"
|
|
22
|
+
"CHANGELOG.md",
|
|
23
|
+
"LICENSE"
|
|
23
24
|
],
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "tsc",
|
|
@@ -52,6 +53,6 @@
|
|
|
52
53
|
"copilot",
|
|
53
54
|
"claude"
|
|
54
55
|
],
|
|
55
|
-
"license": "
|
|
56
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
56
57
|
"private": false
|
|
57
58
|
}
|