viviscape-mcp 1.0.0 → 2.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/README.md +62 -8
- package/dist/api-client.d.ts +26 -6
- package/dist/api-client.js +217 -100
- package/dist/auth/auth-service.d.ts +19 -0
- package/dist/auth/auth-service.js +148 -0
- package/dist/auth/credentials.d.ts +18 -0
- package/dist/auth/credentials.js +30 -0
- package/dist/auth/permissions.d.ts +18 -0
- package/dist/auth/permissions.js +68 -0
- package/dist/auth/token-store.d.ts +12 -0
- package/dist/auth/token-store.js +189 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +15 -0
- package/dist/index.js +195 -72
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,14 +16,36 @@ Or install globally:
|
|
|
16
16
|
npm install -g viviscape-mcp
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Sign in
|
|
20
|
+
|
|
21
|
+
Authentication is per-user, the same browser flow the ViviScape CLI uses — no
|
|
22
|
+
API keys. Sign in once:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx viviscape-mcp login
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A browser tab opens on ViviScape Work; confirm **Allow access** and the session
|
|
29
|
+
is stored in Windows Credential Manager (or `~/.viviscape/mcp-credentials.json`
|
|
30
|
+
on macOS/Linux). Every tool call then runs as *you*: your user id, account,
|
|
31
|
+
role, and plan come from the session, so tools see exactly the data you can see
|
|
32
|
+
in the app.
|
|
20
33
|
|
|
21
|
-
|
|
34
|
+
```bash
|
|
35
|
+
npx viviscape-mcp status # who am I, which account, role, plan
|
|
36
|
+
npx viviscape-mcp logout # clear the stored session
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you already ran `vs auth login` with the [ViviScape CLI](https://viviscape.io),
|
|
40
|
+
that session is picked up automatically. Inside an MCP client you can also call
|
|
41
|
+
the `auth_login`, `auth_status`, and `auth_logout` tools. Sessions expire; when
|
|
42
|
+
one does, tools report it and you re-run `login`.
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
22
45
|
|
|
23
46
|
| Variable | Required | Default | Description |
|
|
24
47
|
|----------|----------|---------|-------------|
|
|
25
|
-
| `
|
|
26
|
-
| `VIVISCAPE_API_URL` | no | `https://api.viviscape.io` | API base URL |
|
|
48
|
+
| `VIVISCAPE_BASE_URL` | no | `https://work.viviscape.io` | ViviScape Work base URL |
|
|
27
49
|
|
|
28
50
|
## Claude Desktop / Claude Code
|
|
29
51
|
|
|
@@ -34,15 +56,46 @@ Add to your MCP client config (e.g. `claude_desktop_config.json` or `.mcp.json`)
|
|
|
34
56
|
"mcpServers": {
|
|
35
57
|
"viviscape": {
|
|
36
58
|
"command": "npx",
|
|
37
|
-
"args": ["-y", "viviscape-mcp"]
|
|
38
|
-
"env": {
|
|
39
|
-
"VIVISCAPE_API_KEY": "your-api-key-here"
|
|
40
|
-
}
|
|
59
|
+
"args": ["-y", "viviscape-mcp"]
|
|
41
60
|
}
|
|
42
61
|
}
|
|
43
62
|
}
|
|
44
63
|
```
|
|
45
64
|
|
|
65
|
+
## OpenAI Codex CLI
|
|
66
|
+
|
|
67
|
+
Codex accepts stdio MCP servers directly. Add to `~/.codex/config.toml`:
|
|
68
|
+
|
|
69
|
+
```toml
|
|
70
|
+
[mcp_servers.viviscape]
|
|
71
|
+
command = "npx"
|
|
72
|
+
args = ["-y", "viviscape-mcp"]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## ChatGPT (Developer Mode / Apps SDK)
|
|
76
|
+
|
|
77
|
+
ChatGPT only accepts **remote HTTP** MCP servers — it does not run local stdio
|
|
78
|
+
processes. Bridge this server to an HTTP endpoint with
|
|
79
|
+
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote) or
|
|
80
|
+
[`supergateway`](https://www.npmjs.com/package/supergateway), then expose it
|
|
81
|
+
publicly (Cloudflare Tunnel, ngrok, or deploy to a host).
|
|
82
|
+
|
|
83
|
+
Example with `supergateway`:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx viviscape-mcp login # once, on the host running the gateway
|
|
87
|
+
npx -y supergateway --stdio "npx -y viviscape-mcp" --port 8000
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The gateway shares the host's stored session, so everyone reaching that endpoint
|
|
91
|
+
acts as the signed-in user — put your own auth in front of it.
|
|
92
|
+
|
|
93
|
+
Expose `http://localhost:8000/sse` publicly, then in ChatGPT:
|
|
94
|
+
|
|
95
|
+
**Settings → Connectors → Create → Custom MCP server**
|
|
96
|
+
- **URL:** `https://your-public-host/sse`
|
|
97
|
+
- **Auth:** none (or bearer, depending on your gateway)
|
|
98
|
+
|
|
46
99
|
## Tools
|
|
47
100
|
|
|
48
101
|
The server exposes tools across these domains:
|
|
@@ -56,6 +109,7 @@ The server exposes tools across these domains:
|
|
|
56
109
|
- **Notes** — `note_add`, `note_get`, `note_update`, `note_remove`, `notes_mine`, `notes_query`
|
|
57
110
|
- **Insights** — hours by person/service/project, AI summary, person stats, time totals
|
|
58
111
|
- **Account** — `account_info`, `account_services`, `account_users`
|
|
112
|
+
- **Auth** — `auth_login`, `auth_status`, `auth_logout`
|
|
59
113
|
|
|
60
114
|
## Development
|
|
61
115
|
|
package/dist/api-client.d.ts
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
import { Credentials } from './auth/credentials.js';
|
|
2
|
+
/** Raised when the stored session is rejected or bounced to the login page. */
|
|
3
|
+
export declare class SessionExpiredError extends Error {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
6
|
+
export declare class ApiError extends Error {
|
|
7
|
+
status: number;
|
|
8
|
+
constructor(status: number, message: string);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Client for the ViviScape Work core API. Authenticates exactly like the
|
|
12
|
+
* ViviScape CLI: the signed-in user's bearer token plus the user_id / pid
|
|
13
|
+
* context headers the core API falls back to.
|
|
14
|
+
*/
|
|
1
15
|
export declare class ViviScapeClient {
|
|
16
|
+
private creds;
|
|
2
17
|
private baseUrl;
|
|
3
|
-
|
|
4
|
-
|
|
18
|
+
constructor(creds: Credentials);
|
|
19
|
+
get userId(): number;
|
|
20
|
+
get accountId(): number;
|
|
21
|
+
get session(): Credentials;
|
|
22
|
+
private get ctx();
|
|
5
23
|
private request;
|
|
24
|
+
private get;
|
|
25
|
+
private post;
|
|
6
26
|
addProspect(data: Record<string, unknown>): Promise<unknown>;
|
|
7
27
|
updateProspect(data: Record<string, unknown>): Promise<unknown>;
|
|
8
28
|
getProspect(prospectId: number): Promise<unknown>;
|
|
@@ -30,6 +50,8 @@ export declare class ViviScapeClient {
|
|
|
30
50
|
getActiveProjects(): Promise<Record<string, unknown>[]>;
|
|
31
51
|
getProjectById(projectId: number): Promise<unknown>;
|
|
32
52
|
getProjectStaff(projectId: number): Promise<unknown>;
|
|
53
|
+
getProjectsByCompany(userId: number, companyId: number): Promise<unknown>;
|
|
54
|
+
getActiveProjectsByUser(userId: number): Promise<unknown>;
|
|
33
55
|
addTask(data: Record<string, unknown>): Promise<unknown>;
|
|
34
56
|
updateTask(data: Record<string, unknown>): Promise<unknown>;
|
|
35
57
|
getProjectTasks(projectId: number): Promise<unknown>;
|
|
@@ -39,15 +61,13 @@ export declare class ViviScapeClient {
|
|
|
39
61
|
getTasksByMilestone(milestoneId: number): Promise<unknown>;
|
|
40
62
|
getTasksByGroupAndUser(groupId: number, userId: number): Promise<unknown>;
|
|
41
63
|
getCompanyTasks(companyId: number): Promise<unknown>;
|
|
42
|
-
getProjectsByCompany(userId: number, companyId: number): Promise<unknown>;
|
|
43
|
-
getActiveProjectsByUser(userId: number): Promise<unknown>;
|
|
44
64
|
addTimeLog(data: Record<string, unknown>): Promise<unknown>;
|
|
45
65
|
updateTimeLog(data: Record<string, unknown>): Promise<unknown>;
|
|
46
66
|
getMyNotes(): Promise<unknown>;
|
|
47
|
-
getNoteById(noteId: number): Promise<unknown>;
|
|
67
|
+
getNoteById(noteId: number | string): Promise<unknown>;
|
|
48
68
|
addNote(data: Record<string, unknown>): Promise<unknown>;
|
|
49
69
|
updateNote(data: Record<string, unknown>): Promise<unknown>;
|
|
50
|
-
removeNote(noteId: number): Promise<unknown>;
|
|
70
|
+
removeNote(noteId: number | string): Promise<unknown>;
|
|
51
71
|
queryNotes(data: Record<string, unknown>): Promise<unknown>;
|
|
52
72
|
getAccountInfo(): Promise<unknown>;
|
|
53
73
|
getActiveServices(): Promise<unknown>;
|