ogment 0.1.0 → 0.2.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 +85 -56
- package/dist/api.d.ts +18 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +17 -0
- package/dist/auth.d.ts +10 -15
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +62 -40
- package/dist/cli.js +5 -6
- package/dist/commands/call.d.ts +1 -2
- package/dist/commands/call.d.ts.map +1 -1
- package/dist/commands/call.js +9 -9
- package/dist/commands/login.d.ts +4 -5
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +15 -45
- package/dist/commands/servers.d.ts +4 -2
- package/dist/commands/servers.d.ts.map +1 -1
- package/dist/commands/servers.js +25 -14
- package/dist/config.d.ts +0 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -11
- package/dist/mcp-client.d.ts +2 -2
- package/dist/mcp-client.d.ts.map +1 -1
- package/dist/mcp-client.js +1 -1
- package/dist/ui.d.ts +0 -3
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +0 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,93 +1,122 @@
|
|
|
1
|
-
# Ogment CLI
|
|
1
|
+
# Ogment CLI - Portable Enterprise Context For Agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ogment is the layer between all your AI agents and your business systems. Connect your integrations. Centralize your workflows, skills, and MCP servers. Govern with the right level of access control and security. Define once, connect from any AI client.
|
|
4
4
|
|
|
5
|
-
Ogment
|
|
5
|
+

|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## New AI Era
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
# 1. Log in (opens browser for OAuth)
|
|
11
|
-
npx ogment login
|
|
9
|
+
AI agents are becoming proactive — platforms like OpenClaw run agents that act independently, not just when you send a message. At the same time, teams use multiple AI providers: Cursor for code, OpenClaw for automation, Claude for analysis, LangChain for custom backends. Each one needs access to your business systems.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
npx ogment connect acme/main
|
|
11
|
+
Without a control plane, you're either giving every AI client raw API keys (insecure) or rebuilding integrations and permissions for each one (unscalable). You need a single place to plug your enterprise into all these AI systems — safely, with the right controls, without vendor lock-in.
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
# → Your agent is connected. Done.
|
|
18
|
-
```
|
|
13
|
+
**Ogment is that control plane.** Connect your integrations once. Set permissions once. Every AI agent — current and future — gets access through Ogment, with full governance and audit.
|
|
19
14
|
|
|
20
|
-
##
|
|
15
|
+
## What Ogment Enables
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
- **Multi-format workflows** — Skills, MCP servers, Claude Plugins — author once, deploy anywhere
|
|
18
|
+
- **Connect anything** — SaaS tools (Salesforce, Slack, Notion), internal APIs, databases, data warehouses
|
|
19
|
+
- **Enterprise SSO** — Okta, Azure AD, Google Workspace — federated auth across your organization
|
|
20
|
+
- **Integration marketplace** — 300+ pre-built connectors, community-contributed, security-scanned
|
|
21
|
+
- **Agent approval flows** — human-in-the-loop for sensitive operations, per-tool granular permissions
|
|
22
|
+
- **Full audit trail** — every tool call logged, searchable, and exportable
|
|
23
|
+
- **Works for agents and humans** — CLI for agents via exec, dashboard for humans, API for custom backends
|
|
24
|
+
- **Portable across AI clients** — Cursor, OpenClaw, Claude Desktop, ChatGPT, or your own agents — same config, same permissions
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
## How It Works
|
|
25
27
|
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
+
```
|
|
29
|
+
Any AI Client
|
|
30
|
+
(OpenClaw, Cursor, Claude, ChatGPT, custom agents)
|
|
31
|
+
│
|
|
32
|
+
│ ogment call <server> <tool> <args>
|
|
33
|
+
▼
|
|
34
|
+
┌─────────────────────────────────────────┐
|
|
35
|
+
│ Ogment Platform │
|
|
36
|
+
│ │
|
|
37
|
+
│ ✓ Authenticate (OAuth, SSO, tokens) │
|
|
38
|
+
│ ✓ Portable workflows (MCP, Skills, │
|
|
39
|
+
│ Claude Plugins) — author once, │
|
|
40
|
+
│ deploy to any AI client │
|
|
41
|
+
│ ✓ Enforce permissions per tool │
|
|
42
|
+
│ ✓ Human approval for sensitive ops │
|
|
43
|
+
│ ✓ Inject real credentials server-side │
|
|
44
|
+
│ ✓ Log every call for audit │
|
|
45
|
+
└──────────────┬──────────────────────────┘
|
|
46
|
+
│
|
|
47
|
+
┌──────────┼──────────┐
|
|
48
|
+
▼ ▼ ▼
|
|
49
|
+
Salesforce Internal Snowflake
|
|
50
|
+
SaaS APIs Data
|
|
28
51
|
```
|
|
29
52
|
|
|
30
|
-
|
|
53
|
+
## Quick Start
|
|
31
54
|
|
|
32
|
-
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g ogment
|
|
57
|
+
```
|
|
33
58
|
|
|
34
|
-
|
|
59
|
+
**`ogment login`** — Authenticate via browser OAuth. Auto-discovers your orgs and servers.
|
|
35
60
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
**`ogment servers [path]`** — List all servers, or inspect a specific server's tools:
|
|
62
|
+
```
|
|
63
|
+
ogment servers · ogment servers salesforce · ogment servers --json
|
|
64
|
+
```
|
|
39
65
|
|
|
40
|
-
|
|
41
|
-
|
|
66
|
+
**`ogment call <server> <tool> [args]`** — Call any tool. Returns JSON:
|
|
67
|
+
```
|
|
68
|
+
ogment call salesforce query_accounts '{"limit":5}'
|
|
69
|
+
ogment call my-api get_customers '{"status":"active"}'
|
|
42
70
|
```
|
|
43
71
|
|
|
44
|
-
|
|
72
|
+
**`ogment logout`** — Revoke token. All agent access stops immediately.
|
|
45
73
|
|
|
46
|
-
|
|
74
|
+
## For Agent Developers
|
|
47
75
|
|
|
48
|
-
|
|
76
|
+
The CLI is designed for AI agents calling via shell exec. Every command supports `--json`. A typical agent workflow:
|
|
49
77
|
|
|
50
78
|
```bash
|
|
51
|
-
|
|
79
|
+
ogment servers --json # discover
|
|
80
|
+
ogment servers salesforce --json # inspect tools
|
|
81
|
+
ogment call salesforce query_accounts '{"status":"open"}' # call
|
|
52
82
|
```
|
|
53
83
|
|
|
54
|
-
|
|
84
|
+
Publish a skill on [ClawHub](https://clawhub.ai) that teaches the agent these three commands — and it has access to every integration on Ogment.
|
|
55
85
|
|
|
56
|
-
|
|
86
|
+
## Why Not Just Call APIs Directly?
|
|
57
87
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
88
|
+
| | **Direct API + CLI** | **Through Ogment** |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| **Credentials** | API keys in env vars and config files. Every agent has a copy. | Credentials never leave Ogment. Agents get scoped, revocable tokens. |
|
|
91
|
+
| **Permissions** | All-or-nothing. Agent has the key, agent can do anything. | Per-tool. Read-only, write with approval, or blocked. |
|
|
92
|
+
| **Human approval** | Not possible. | Built-in. Sensitive tools require human sign-off. |
|
|
93
|
+
| **Team sharing** | Each person sets up their own keys. Onboarding = sharing secrets. | One workspace. Invite a teammate, same servers, same rules, no secrets shared. |
|
|
94
|
+
| **Multi-agent** | Each AI client needs its own keys and config. Switch tools? Redo everything. | Define once. Every AI client connects to the same setup. |
|
|
95
|
+
| **Workflows** | Rebuild skills, prompts, and tool chains for each AI client. | Author once as MCP servers, Skills, or Claude Plugins — works across every client. |
|
|
96
|
+
| **Audit** | Hope you added logging. | Every call logged — user, agent, timestamp, args, result. |
|
|
97
|
+
| **Revocation** | Rotate the API key, break everything that uses it. | Revoke one agent's token. Everything else keeps working. |
|
|
61
98
|
|
|
62
|
-
|
|
99
|
+
**The CLI and MCP are the interface. Ogment is the infrastructure.**
|
|
63
100
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
│
|
|
76
|
-
┌──────────┼──────────┐
|
|
77
|
-
▼ ▼ ▼
|
|
78
|
-
Salesforce Linear Snowflake
|
|
79
|
-
```
|
|
101
|
+
## Portability
|
|
102
|
+
|
|
103
|
+
Define your integrations, permissions, and workflows once — connect from any AI client:
|
|
104
|
+
|
|
105
|
+
| Client | How |
|
|
106
|
+
|---|---|
|
|
107
|
+
| **OpenClaw** | Agent calls `ogment` via `exec` tool |
|
|
108
|
+
| **Cursor** | MCP config with Ogment endpoint |
|
|
109
|
+
| **Claude Desktop** | MCP config with Ogment endpoint |
|
|
110
|
+
| **ChatGPT** | MCP config with Ogment endpoint |
|
|
111
|
+
| **Custom agents** | HTTP calls to Ogment's MCP proxy, or `ogment call` via subprocess |
|
|
80
112
|
|
|
81
|
-
|
|
82
|
-
2. **`ogment connect`** — Prints config snippet with token + MCP endpoint
|
|
83
|
-
3. **Agent calls tools** — Through Ogment's MCP proxy, real credentials injected server-side
|
|
84
|
-
4. **`ogment logout`** — Kill switch: revoke token, agent loses access instantly
|
|
113
|
+
Same servers, same tools, same permissions — regardless of which AI client your team uses.
|
|
85
114
|
|
|
86
115
|
## Environment Variables
|
|
87
116
|
|
|
88
117
|
| Variable | Default | Description |
|
|
89
118
|
|---|---|---|
|
|
90
|
-
| `OGMENT_BASE_URL` | `https://
|
|
119
|
+
| `OGMENT_BASE_URL` | `https://dashboard.ogment.ai` | Ogment platform URL |
|
|
91
120
|
|
|
92
121
|
## License
|
|
93
122
|
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ogment API client — calls the backend REST endpoints.
|
|
3
|
+
*/
|
|
4
|
+
export interface OgmentOrg {
|
|
5
|
+
orgSlug: string;
|
|
6
|
+
servers: {
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export interface OgmentMe {
|
|
13
|
+
email: string | null;
|
|
14
|
+
name: string | null;
|
|
15
|
+
orgs: OgmentOrg[];
|
|
16
|
+
}
|
|
17
|
+
export declare function fetchMe(token: string): Promise<OgmentMe>;
|
|
18
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAMD,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,qBAW1C"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ogment API client — calls the backend REST endpoints.
|
|
3
|
+
*/
|
|
4
|
+
import { OGMENT_BASE_URL } from './config.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// /me — user identity + server list across all orgs
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
export async function fetchMe(token) {
|
|
9
|
+
const res = await fetch(`${OGMENT_BASE_URL}/api/v1/mcp-auth/me`, {
|
|
10
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
11
|
+
});
|
|
12
|
+
if (!res.ok) {
|
|
13
|
+
const text = await res.text();
|
|
14
|
+
throw new Error(`Failed to fetch account info (${res.status}): ${text}`);
|
|
15
|
+
}
|
|
16
|
+
return (await res.json());
|
|
17
|
+
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -10,12 +10,15 @@
|
|
|
10
10
|
* 6. Exchange code for access token at /token
|
|
11
11
|
* 7. Store credentials locally
|
|
12
12
|
*/
|
|
13
|
+
export interface StoredOrg {
|
|
14
|
+
orgSlug: string;
|
|
15
|
+
servers: string[];
|
|
16
|
+
}
|
|
13
17
|
export interface StoredCredentials {
|
|
14
18
|
accessToken: string;
|
|
15
19
|
clientId: string;
|
|
16
20
|
clientSecret: string | null;
|
|
17
|
-
|
|
18
|
-
servers: string[];
|
|
21
|
+
orgs: StoredOrg[];
|
|
19
22
|
}
|
|
20
23
|
export declare function loadCredentials(): StoredCredentials | null;
|
|
21
24
|
export declare function deleteCredentials(): void;
|
|
@@ -27,19 +30,11 @@ export declare function revokeToken(token: string, clientId: string, clientSecre
|
|
|
27
30
|
/**
|
|
28
31
|
* Runs the full OAuth2 Authorization Code + PKCE login flow.
|
|
29
32
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
+
* No resource URL needed — the backend now supports server-less OAuth
|
|
34
|
+
* for CLI login. After getting the token, we call /me to discover
|
|
35
|
+
* the user's org and servers.
|
|
33
36
|
*
|
|
34
|
-
* Returns the
|
|
35
|
-
*/
|
|
36
|
-
export declare function loginFlow(resourceUrl: string): Promise<{
|
|
37
|
-
accessToken: string;
|
|
38
|
-
clientId: string;
|
|
39
|
-
clientSecret: string | null;
|
|
40
|
-
}>;
|
|
41
|
-
/**
|
|
42
|
-
* Run the login flow and store credentials with org + servers.
|
|
37
|
+
* Returns the stored credentials.
|
|
43
38
|
*/
|
|
44
|
-
export declare function login(
|
|
39
|
+
export declare function login(): Promise<StoredCredentials>;
|
|
45
40
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAsBH,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAsBH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAiCD,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAI1D;AASD,wBAAgB,iBAAiB,SAIhC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,sBAMjC;AAoED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,iBAoB7F;AAgID;;;;;;;;GAQG;AACH,wBAAsB,KAAK,+BA8D1B"}
|
package/dist/auth.js
CHANGED
|
@@ -162,11 +162,12 @@ function waitForAuthCallback(port) {
|
|
|
162
162
|
server.listen(port, CLI_REDIRECT_HOST, () => {
|
|
163
163
|
// Server is ready
|
|
164
164
|
});
|
|
165
|
-
// Timeout after 5 minutes
|
|
166
|
-
setTimeout(() => {
|
|
165
|
+
// Timeout after 5 minutes (unref so it doesn't block process exit)
|
|
166
|
+
const timeout = setTimeout(() => {
|
|
167
167
|
server.close();
|
|
168
168
|
reject(new Error('Login timed out. No callback received within 5 minutes.'));
|
|
169
169
|
}, 5 * 60 * 1000);
|
|
170
|
+
timeout.unref();
|
|
170
171
|
});
|
|
171
172
|
}
|
|
172
173
|
function getRandomPort() {
|
|
@@ -179,24 +180,52 @@ function getRandomPort() {
|
|
|
179
180
|
// ---------------------------------------------------------------------------
|
|
180
181
|
function successPage() {
|
|
181
182
|
return `<!DOCTYPE html>
|
|
182
|
-
<html>
|
|
183
|
-
<head
|
|
184
|
-
<
|
|
185
|
-
<
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
<html lang="en">
|
|
184
|
+
<head>
|
|
185
|
+
<meta charset="utf-8">
|
|
186
|
+
<title>Ogment — Logged in</title>
|
|
187
|
+
<style>
|
|
188
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
189
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f8f8fc; color: #333; }
|
|
190
|
+
.card { text-align: center; padding: 48px; border-radius: 16px; background: white; box-shadow: 0 2px 16px rgba(108, 92, 231, 0.08); max-width: 420px; }
|
|
191
|
+
.icon { font-size: 48px; margin-bottom: 16px; }
|
|
192
|
+
h1 { font-size: 24px; font-weight: 600; color: #6C5CE7; margin-bottom: 8px; }
|
|
193
|
+
p { font-size: 15px; color: #888; line-height: 1.5; }
|
|
194
|
+
.brand { font-size: 13px; color: #bbb; margin-top: 24px; }
|
|
195
|
+
</style>
|
|
196
|
+
</head>
|
|
197
|
+
<body>
|
|
198
|
+
<div class="card">
|
|
199
|
+
<div class="icon">🦞</div>
|
|
200
|
+
<h1>Ogment <3 Openclaw </h1>
|
|
201
|
+
<p>Authentication successful.<br>You can close this tab and return to your terminal.</p>
|
|
202
|
+
<p class="brand">ogment.ai</p>
|
|
188
203
|
</div>
|
|
189
204
|
</body>
|
|
190
205
|
</html>`;
|
|
191
206
|
}
|
|
192
207
|
function errorPage(error, description) {
|
|
193
208
|
return `<!DOCTYPE html>
|
|
194
|
-
<html>
|
|
195
|
-
<head
|
|
196
|
-
<
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
209
|
+
<html lang="en">
|
|
210
|
+
<head>
|
|
211
|
+
<meta charset="utf-8">
|
|
212
|
+
<title>Ogment — Login failed</title>
|
|
213
|
+
<style>
|
|
214
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
215
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f8f8fc; color: #333; }
|
|
216
|
+
.card { text-align: center; padding: 48px; border-radius: 16px; background: white; box-shadow: 0 2px 16px rgba(231, 76, 60, 0.08); max-width: 420px; }
|
|
217
|
+
.icon { font-size: 48px; margin-bottom: 16px; }
|
|
218
|
+
h1 { font-size: 24px; font-weight: 600; color: #e74c3c; margin-bottom: 8px; }
|
|
219
|
+
p { font-size: 15px; color: #888; line-height: 1.5; }
|
|
220
|
+
.error { font-size: 13px; color: #bbb; margin-top: 16px; font-family: monospace; }
|
|
221
|
+
</style>
|
|
222
|
+
</head>
|
|
223
|
+
<body>
|
|
224
|
+
<div class="card">
|
|
225
|
+
<div class="icon">⚠️</div>
|
|
226
|
+
<h1>Login failed</h1>
|
|
227
|
+
<p>${description ?? 'Something went wrong during authentication.'}</p>
|
|
228
|
+
<p class="error">${error}</p>
|
|
200
229
|
</div>
|
|
201
230
|
</body>
|
|
202
231
|
</html>`;
|
|
@@ -207,13 +236,17 @@ function errorPage(error, description) {
|
|
|
207
236
|
/**
|
|
208
237
|
* Runs the full OAuth2 Authorization Code + PKCE login flow.
|
|
209
238
|
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
239
|
+
* No resource URL needed — the backend now supports server-less OAuth
|
|
240
|
+
* for CLI login. After getting the token, we call /me to discover
|
|
241
|
+
* the user's org and servers.
|
|
213
242
|
*
|
|
214
|
-
* Returns the
|
|
243
|
+
* Returns the stored credentials.
|
|
215
244
|
*/
|
|
216
|
-
export async function
|
|
245
|
+
export async function login() {
|
|
246
|
+
const existing = loadCredentials();
|
|
247
|
+
if (existing?.accessToken) {
|
|
248
|
+
return existing;
|
|
249
|
+
}
|
|
217
250
|
const port = getRandomPort();
|
|
218
251
|
const redirectUri = `http://${CLI_REDIRECT_HOST}:${port}/callback`;
|
|
219
252
|
// Step 1 — Register as OAuth client
|
|
@@ -221,7 +254,7 @@ export async function loginFlow(resourceUrl) {
|
|
|
221
254
|
// Step 2 — Generate PKCE pair
|
|
222
255
|
const codeVerifier = generateCodeVerifier();
|
|
223
256
|
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
224
|
-
// Step 3 — Build authorization URL (
|
|
257
|
+
// Step 3 — Build authorization URL (no resource — server-less login)
|
|
225
258
|
const state = randomBytes(16).toString('hex');
|
|
226
259
|
const authorizeUrl = new URL(OAUTH_AUTHORIZE_URL);
|
|
227
260
|
authorizeUrl.searchParams.set('client_id', client.client_id);
|
|
@@ -230,7 +263,6 @@ export async function loginFlow(resourceUrl) {
|
|
|
230
263
|
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
|
|
231
264
|
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
|
|
232
265
|
authorizeUrl.searchParams.set('state', state);
|
|
233
|
-
authorizeUrl.searchParams.set('resource', resourceUrl);
|
|
234
266
|
// Step 4 — Start callback server, then open browser
|
|
235
267
|
const callbackPromise = waitForAuthCallback(port);
|
|
236
268
|
await open(authorizeUrl.toString());
|
|
@@ -247,28 +279,18 @@ export async function loginFlow(resourceUrl) {
|
|
|
247
279
|
codeVerifier,
|
|
248
280
|
redirectUri,
|
|
249
281
|
});
|
|
250
|
-
|
|
282
|
+
// Step 7 — Fetch user identity + servers from /me
|
|
283
|
+
const { fetchMe } = await import('./api.js');
|
|
284
|
+
const me = await fetchMe(tokenResponse.access_token);
|
|
285
|
+
// Step 8 — Store credentials
|
|
286
|
+
const creds = {
|
|
251
287
|
accessToken: tokenResponse.access_token,
|
|
252
288
|
clientId: client.client_id,
|
|
253
289
|
clientSecret: client.client_secret ?? null,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
*/
|
|
259
|
-
export async function login(orgSlug, servers, resourceUrl) {
|
|
260
|
-
const existing = loadCredentials();
|
|
261
|
-
if (existing?.accessToken) {
|
|
262
|
-
// Already logged in — just update the server list
|
|
263
|
-
const merged = [...new Set([...existing.servers, ...servers])];
|
|
264
|
-
saveCredentials({ ...existing, servers: merged });
|
|
265
|
-
return existing;
|
|
266
|
-
}
|
|
267
|
-
const result = await loginFlow(resourceUrl);
|
|
268
|
-
const creds = {
|
|
269
|
-
...result,
|
|
270
|
-
orgSlug,
|
|
271
|
-
servers,
|
|
290
|
+
orgs: me.orgs.map((org) => ({
|
|
291
|
+
orgSlug: org.orgSlug,
|
|
292
|
+
servers: org.servers.map((s) => s.path),
|
|
293
|
+
})),
|
|
272
294
|
};
|
|
273
295
|
saveCredentials(creds);
|
|
274
296
|
return creds;
|
package/dist/cli.js
CHANGED
|
@@ -22,10 +22,9 @@ program
|
|
|
22
22
|
// ── login ──────────────────────────────────────────────────────────────────
|
|
23
23
|
program
|
|
24
24
|
.command('login')
|
|
25
|
-
.description('Authenticate with Ogment
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
await loginCommand(targets);
|
|
25
|
+
.description('Authenticate with Ogment')
|
|
26
|
+
.action(async () => {
|
|
27
|
+
await loginCommand();
|
|
29
28
|
});
|
|
30
29
|
// ── servers ────────────────────────────────────────────────────────────────
|
|
31
30
|
program
|
|
@@ -57,14 +56,14 @@ program.action(() => {
|
|
|
57
56
|
console.log();
|
|
58
57
|
console.log(` ${BOLD('Commands:')}`);
|
|
59
58
|
console.log();
|
|
60
|
-
console.log(` ${BOLD('login')} ${DIM('Authenticate
|
|
59
|
+
console.log(` ${BOLD('login')} ${DIM('Authenticate with Ogment')}`);
|
|
61
60
|
console.log(` ${BOLD('servers')} ${DIM('List servers or inspect tools')}`);
|
|
62
61
|
console.log(` ${BOLD('call')} ${DIM('Call a tool on a server (returns JSON)')}`);
|
|
63
62
|
console.log(` ${BOLD('logout')} ${DIM('Revoke token and delete credentials')}`);
|
|
64
63
|
console.log();
|
|
65
64
|
console.log(` ${BOLD('Quick start:')}`);
|
|
66
65
|
console.log();
|
|
67
|
-
console.log(` ${DIM('$')} ogment login
|
|
66
|
+
console.log(` ${DIM('$')} ogment login`);
|
|
68
67
|
console.log(` ${DIM('$')} ogment servers`);
|
|
69
68
|
console.log(` ${DIM('$')} ogment call ${DIM('<server> <tool> [args-json]')}`);
|
|
70
69
|
console.log();
|
package/dist/commands/call.d.ts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* Usage:
|
|
5
5
|
* ogment call ecommerce-api get__health
|
|
6
6
|
* ogment call ecommerce-api get__api_products_ '{"limit":2}'
|
|
7
|
-
* ogment call ecommerce-api post__api_products_ '{"name":"Widget","price":9.99,"stock":100,"category":"gadgets"}'
|
|
8
7
|
*
|
|
9
8
|
* Always outputs JSON (designed for agent consumption via exec).
|
|
10
9
|
*/
|
|
11
|
-
export declare function callCommand(serverPath: string
|
|
10
|
+
export declare function callCommand(serverPath: string, toolName: string, argsJson: string | undefined): Promise<void>;
|
|
12
11
|
//# sourceMappingURL=call.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../src/commands/call.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,iBA6B7B"}
|
package/dist/commands/call.js
CHANGED
|
@@ -4,23 +4,23 @@
|
|
|
4
4
|
* Usage:
|
|
5
5
|
* ogment call ecommerce-api get__health
|
|
6
6
|
* ogment call ecommerce-api get__api_products_ '{"limit":2}'
|
|
7
|
-
* ogment call ecommerce-api post__api_products_ '{"name":"Widget","price":9.99,"stock":100,"category":"gadgets"}'
|
|
8
7
|
*
|
|
9
8
|
* Always outputs JSON (designed for agent consumption via exec).
|
|
10
9
|
*/
|
|
11
10
|
import { requireCredentials } from '../auth.js';
|
|
11
|
+
import { fetchMe } from '../api.js';
|
|
12
12
|
import { callTool } from '../mcp-client.js';
|
|
13
13
|
export async function callCommand(serverPath, toolName, argsJson) {
|
|
14
|
-
if (!serverPath || !toolName) {
|
|
15
|
-
throw new Error('Usage: ogment call <server> <tool> [args-json]\n' +
|
|
16
|
-
'Example: ogment call ecommerce-api get__api_products_ \'{"limit":2}\'');
|
|
17
|
-
}
|
|
18
14
|
const creds = requireCredentials();
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const me = await fetchMe(creds.accessToken);
|
|
16
|
+
// Find the server across all orgs
|
|
17
|
+
const allServers = me.orgs.flatMap((org) => org.servers.map((s) => ({ ...s, orgSlug: org.orgSlug })));
|
|
18
|
+
const server = allServers.find((s) => s.path === serverPath);
|
|
19
|
+
if (!server) {
|
|
20
|
+
const available = allServers.map((s) => s.path).join(', ');
|
|
21
|
+
throw new Error(`Server "${serverPath}" not found. Available: ${available || 'none'}`);
|
|
21
22
|
}
|
|
22
23
|
const args = argsJson ? JSON.parse(argsJson) : {};
|
|
23
|
-
const result = await callTool(
|
|
24
|
-
// Output the result as JSON — this is what the agent reads via exec
|
|
24
|
+
const result = await callTool(server.orgSlug, serverPath, creds.accessToken, toolName, args);
|
|
25
25
|
console.log(JSON.stringify(result, null, 2));
|
|
26
26
|
}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `ogment login
|
|
2
|
+
* `ogment login` — Authenticate with the Ogment platform.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* If already logged in, just adds new servers to the config.
|
|
4
|
+
* Zero arguments. Opens browser for OAuth, then auto-discovers
|
|
5
|
+
* orgs and servers via /me endpoint.
|
|
7
6
|
*/
|
|
8
|
-
export declare function loginCommand(
|
|
7
|
+
export declare function loginCommand(): Promise<void>;
|
|
9
8
|
//# sourceMappingURL=login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,wBAAsB,YAAY,kBA2BjC"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,64 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `ogment login
|
|
2
|
+
* `ogment login` — Authenticate with the Ogment platform.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* If already logged in, just adds new servers to the config.
|
|
4
|
+
* Zero arguments. Opens browser for OAuth, then auto-discovers
|
|
5
|
+
* orgs and servers via /me endpoint.
|
|
7
6
|
*/
|
|
8
7
|
import ora from 'ora';
|
|
9
8
|
import { loadCredentials, login } from '../auth.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
function parseTarget(target) {
|
|
13
|
-
const parts = target.split('/');
|
|
14
|
-
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
15
|
-
throw new Error(`Invalid target "${target}". Expected format: <org-slug>/<server-path> (e.g. ogment/main)`);
|
|
16
|
-
}
|
|
17
|
-
return { orgSlug: parts[0], serverPath: parts[1] };
|
|
18
|
-
}
|
|
19
|
-
export async function loginCommand(targets) {
|
|
20
|
-
if (targets.length === 0) {
|
|
21
|
-
heading('Log in to Ogment');
|
|
22
|
-
line(`${SYM.warn} ${YELLOW('Provide at least one target:')} ${BOLD('ogment login <org>/<server>')}`);
|
|
23
|
-
blank();
|
|
24
|
-
line(`${DIM('Examples:')}`);
|
|
25
|
-
line(` ${BOLD('ogment login ogment/ama-master-mcp')}`);
|
|
26
|
-
line(` ${BOLD('ogment login ogment/ama-master-mcp ogment/sales')}`);
|
|
27
|
-
blank();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
// Parse the first target to get orgSlug
|
|
31
|
-
const first = parseTarget(targets[0]);
|
|
32
|
-
const orgSlug = first.orgSlug;
|
|
33
|
-
// Collect all server paths (first + any extras)
|
|
34
|
-
const servers = [first.serverPath];
|
|
35
|
-
for (let i = 1; i < targets.length; i++) {
|
|
36
|
-
const t = targets[i];
|
|
37
|
-
// Allow both "org/server" and just "server" for extra args
|
|
38
|
-
const path = t.includes('/') ? parseTarget(t).serverPath : t;
|
|
39
|
-
servers.push(path);
|
|
40
|
-
}
|
|
9
|
+
import { blank, BOLD, DIM, heading, line, SYM } from '../ui.js';
|
|
10
|
+
export async function loginCommand() {
|
|
41
11
|
const existing = loadCredentials();
|
|
42
12
|
if (existing?.accessToken) {
|
|
43
|
-
// Already logged in — merge new servers
|
|
44
13
|
heading('Already logged in');
|
|
45
|
-
const
|
|
46
|
-
|
|
14
|
+
for (const org of existing.orgs) {
|
|
15
|
+
line(`${SYM.check} ${BOLD(org.orgSlug)}: ${org.servers.join(', ') || DIM('no servers')}`);
|
|
16
|
+
}
|
|
47
17
|
blank();
|
|
48
|
-
line(`${DIM('
|
|
18
|
+
line(`${DIM('To re-authenticate, run')} ${BOLD('ogment logout')} ${DIM('first.')}`);
|
|
49
19
|
blank();
|
|
50
20
|
return;
|
|
51
21
|
}
|
|
52
22
|
heading('Log in to Ogment');
|
|
53
|
-
const resourceUrl = MCP_RESOURCE_URL(orgSlug, first.serverPath);
|
|
54
23
|
const spinner = ora({ text: 'Opening browser…', color: 'magenta' }).start();
|
|
55
|
-
const creds = await login(
|
|
24
|
+
const creds = await login();
|
|
56
25
|
spinner.succeed('Logged in');
|
|
57
26
|
blank();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
27
|
+
for (const org of creds.orgs) {
|
|
28
|
+
const serverList = org.servers.length > 0 ? org.servers.join(', ') : DIM('no servers');
|
|
29
|
+
line(`${SYM.check} ${BOLD(org.orgSlug)}: ${serverList}`);
|
|
30
|
+
}
|
|
61
31
|
blank();
|
|
62
|
-
line(`${DIM('
|
|
32
|
+
line(`${DIM('Next:')} ${BOLD('ogment servers')} ${DIM('to see your tools')}`);
|
|
63
33
|
blank();
|
|
64
34
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `ogment servers [path]` — List
|
|
2
|
+
* `ogment servers [path]` — List servers and inspect their tools.
|
|
3
|
+
*
|
|
4
|
+
* Fetches the live server list from /me (auto-refreshes on every call).
|
|
3
5
|
*
|
|
4
6
|
* Usage:
|
|
5
|
-
* ogment servers List all
|
|
7
|
+
* ogment servers List all servers across all orgs
|
|
6
8
|
* ogment servers <path> Show server details + tool list
|
|
7
9
|
* ogment servers --json Machine-readable output
|
|
8
10
|
* ogment servers <path> --json Machine-readable tool list
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBA6EzB"}
|
package/dist/commands/servers.js
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `ogment servers [path]` — List
|
|
2
|
+
* `ogment servers [path]` — List servers and inspect their tools.
|
|
3
|
+
*
|
|
4
|
+
* Fetches the live server list from /me (auto-refreshes on every call).
|
|
3
5
|
*
|
|
4
6
|
* Usage:
|
|
5
|
-
* ogment servers List all
|
|
7
|
+
* ogment servers List all servers across all orgs
|
|
6
8
|
* ogment servers <path> Show server details + tool list
|
|
7
9
|
* ogment servers --json Machine-readable output
|
|
8
10
|
* ogment servers <path> --json Machine-readable tool list
|
|
9
11
|
*/
|
|
10
12
|
import { requireCredentials } from '../auth.js';
|
|
13
|
+
import { fetchMe } from '../api.js';
|
|
11
14
|
import { fetchTools } from '../mcp-client.js';
|
|
12
15
|
import { blank, BOLD, DIM, GREEN, heading, line, SYM } from '../ui.js';
|
|
13
16
|
export async function serversCommand(serverPath, opts) {
|
|
14
17
|
const creds = requireCredentials();
|
|
18
|
+
const me = await fetchMe(creds.accessToken);
|
|
19
|
+
// Flatten all servers with their org slug
|
|
20
|
+
const allServers = me.orgs.flatMap((org) => org.servers.map((s) => ({ ...s, orgSlug: org.orgSlug })));
|
|
15
21
|
// ── List all servers ───────────────────────────────────────────────────
|
|
16
22
|
if (!serverPath) {
|
|
17
23
|
if (opts.json) {
|
|
18
|
-
console.log(JSON.stringify(
|
|
24
|
+
console.log(JSON.stringify(allServers, null, 2));
|
|
19
25
|
return;
|
|
20
26
|
}
|
|
21
27
|
heading('Your servers');
|
|
22
|
-
if (
|
|
23
|
-
line(`${DIM('No servers
|
|
24
|
-
line(` ${BOLD('ogment login <org>/<server>')}`);
|
|
28
|
+
if (allServers.length === 0) {
|
|
29
|
+
line(`${DIM('No servers found. Create one in the Ogment dashboard.')}`);
|
|
25
30
|
blank();
|
|
26
31
|
return;
|
|
27
32
|
}
|
|
28
|
-
for (const
|
|
29
|
-
|
|
33
|
+
for (const server of allServers) {
|
|
34
|
+
const status = server.enabled ? GREEN('enabled') : DIM('disabled');
|
|
35
|
+
line(`${SYM.bullet} ${BOLD(server.path.padEnd(24))} ${server.name.padEnd(24)} ${DIM(server.orgSlug.padEnd(16))} ${status}`);
|
|
30
36
|
}
|
|
31
37
|
blank();
|
|
32
38
|
line(`${DIM('Inspect a server:')} ${BOLD('ogment servers <path>')}`);
|
|
@@ -35,20 +41,25 @@ export async function serversCommand(serverPath, opts) {
|
|
|
35
41
|
return;
|
|
36
42
|
}
|
|
37
43
|
// ── Server detail + tools ──────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
const server = allServers.find((s) => s.path === serverPath);
|
|
45
|
+
if (!server) {
|
|
46
|
+
const available = allServers.map((s) => s.path).join(', ');
|
|
47
|
+
throw new Error(`Server "${serverPath}" not found. Available: ${available || 'none'}`);
|
|
40
48
|
}
|
|
41
|
-
const tools = await fetchTools(
|
|
49
|
+
const tools = await fetchTools(server.orgSlug, serverPath, creds.accessToken);
|
|
42
50
|
if (opts.json) {
|
|
43
51
|
console.log(JSON.stringify({
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
name: server.name,
|
|
53
|
+
path: server.path,
|
|
54
|
+
enabled: server.enabled,
|
|
55
|
+
orgSlug: server.orgSlug,
|
|
46
56
|
toolCount: tools.length,
|
|
47
57
|
tools: tools.map((t) => ({ name: t.name, description: t.description })),
|
|
48
58
|
}, null, 2));
|
|
49
59
|
return;
|
|
50
60
|
}
|
|
51
|
-
heading(
|
|
61
|
+
heading(`${server.name} (${server.path})`);
|
|
62
|
+
line(`${BOLD('Org:')} ${server.orgSlug}`);
|
|
52
63
|
line(`${BOLD('Tools:')} ${tools.length}`);
|
|
53
64
|
blank();
|
|
54
65
|
for (const tool of tools) {
|
package/dist/config.d.ts
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/** Base URL of the Ogment platform (frontend). */
|
|
5
5
|
export declare const OGMENT_BASE_URL: string;
|
|
6
|
-
/** OAuth metadata endpoint. */
|
|
7
|
-
export declare const OAUTH_METADATA_URL: string;
|
|
8
6
|
/** OAuth endpoints (derived from base). */
|
|
9
7
|
export declare const OAUTH_AUTHORIZE_URL: string;
|
|
10
8
|
export declare const OAUTH_TOKEN_URL: string;
|
|
@@ -15,12 +13,6 @@ export declare const OAUTH_REVOKE_URL: string;
|
|
|
15
13
|
* Uses path format: {BASE_URL}/api/v1/mcp/{orgSlug}/{serverPath}
|
|
16
14
|
*/
|
|
17
15
|
export declare const MCP_ENDPOINT: (orgSlug: string, serverPath: string) => string;
|
|
18
|
-
/**
|
|
19
|
-
* Resource URL sent to the OAuth authorize endpoint.
|
|
20
|
-
* The backend parses this to resolve the MCP server.
|
|
21
|
-
* Uses subdomain format for resource identification (required by backend parser).
|
|
22
|
-
*/
|
|
23
|
-
export declare const MCP_RESOURCE_URL: (orgSlug: string, serverPath: string) => string;
|
|
24
16
|
/** Directory for CLI config & credentials. */
|
|
25
17
|
export declare const CONFIG_DIR: string;
|
|
26
18
|
/** Path to stored credentials file. */
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,kDAAkD;AAClD,eAAO,MAAM,eAAe,QACkC,CAAC;AAE/D
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,kDAAkD;AAClD,eAAO,MAAM,eAAe,QACkC,CAAC;AAE/D,2CAA2C;AAC3C,eAAO,MAAM,mBAAmB,QAAiD,CAAC;AAClF,eAAO,MAAM,eAAe,QAA6C,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAgD,CAAC;AAChF,eAAO,MAAM,gBAAgB,QAA8C,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,WACN,CAAC;AAO3D,8CAA8C;AAC9C,eAAO,MAAM,UAAU,QAAuC,CAAC;AAE/D,uCAAuC;AACvC,eAAO,MAAM,gBAAgB,QAAuC,CAAC;AAMrE,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAM7C,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -8,8 +8,6 @@ import { join } from 'node:path';
|
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
9
|
/** Base URL of the Ogment platform (frontend). */
|
|
10
10
|
export const OGMENT_BASE_URL = process.env.OGMENT_BASE_URL ?? 'https://dashboard.ogment.ai';
|
|
11
|
-
/** OAuth metadata endpoint. */
|
|
12
|
-
export const OAUTH_METADATA_URL = `${OGMENT_BASE_URL}/.well-known/oauth-authorization-server`;
|
|
13
11
|
/** OAuth endpoints (derived from base). */
|
|
14
12
|
export const OAUTH_AUTHORIZE_URL = `${OGMENT_BASE_URL}/api/v1/mcp-auth/authorize`;
|
|
15
13
|
export const OAUTH_TOKEN_URL = `${OGMENT_BASE_URL}/api/v1/mcp-auth/token`;
|
|
@@ -20,15 +18,6 @@ export const OAUTH_REVOKE_URL = `${OGMENT_BASE_URL}/api/v1/mcp-auth/revoke`;
|
|
|
20
18
|
* Uses path format: {BASE_URL}/api/v1/mcp/{orgSlug}/{serverPath}
|
|
21
19
|
*/
|
|
22
20
|
export const MCP_ENDPOINT = (orgSlug, serverPath) => `${OGMENT_BASE_URL}/api/v1/mcp/${orgSlug}/${serverPath}`;
|
|
23
|
-
/**
|
|
24
|
-
* Resource URL sent to the OAuth authorize endpoint.
|
|
25
|
-
* The backend parses this to resolve the MCP server.
|
|
26
|
-
* Uses subdomain format for resource identification (required by backend parser).
|
|
27
|
-
*/
|
|
28
|
-
export const MCP_RESOURCE_URL = (orgSlug, serverPath) => {
|
|
29
|
-
const mcpDomain = process.env.OGMENT_MCP_DOMAIN ?? 'mcp.ogment.ai';
|
|
30
|
-
return `https://${orgSlug}.${mcpDomain}/${serverPath}`;
|
|
31
|
-
};
|
|
32
21
|
// ---------------------------------------------------------------------------
|
|
33
22
|
// Local storage
|
|
34
23
|
// ---------------------------------------------------------------------------
|
package/dist/mcp-client.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface McpTool {
|
|
|
8
8
|
description: string;
|
|
9
9
|
inputSchema: Record<string, unknown>;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
interface McpToolCallResult {
|
|
12
12
|
content: {
|
|
13
13
|
type: string;
|
|
14
14
|
text: string;
|
|
@@ -16,9 +16,9 @@ export interface McpToolCallResult {
|
|
|
16
16
|
structuredContent?: unknown;
|
|
17
17
|
isError?: boolean;
|
|
18
18
|
}
|
|
19
|
-
export declare function mcpRequest(orgSlug: string, serverPath: string, token: string, method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
20
19
|
/** Fetch the list of tools available on a server. */
|
|
21
20
|
export declare function fetchTools(orgSlug: string, serverPath: string, token: string): Promise<McpTool[]>;
|
|
22
21
|
/** Call a tool on a server and return the result. */
|
|
23
22
|
export declare function callTool(orgSlug: string, serverPath: string, token: string, toolName: string, args: Record<string, unknown>): Promise<McpToolCallResult>;
|
|
23
|
+
export {};
|
|
24
24
|
//# sourceMappingURL=mcp-client.d.ts.map
|
package/dist/mcp-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiDD,qDAAqD;AACrD,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAKlF;AAED,qDAAqD;AACrD,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,8BAM9B"}
|
package/dist/mcp-client.js
CHANGED
|
@@ -7,7 +7,7 @@ import { MCP_ENDPOINT } from './config.js';
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
// Core JSON-RPC request
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
10
|
+
async function mcpRequest(orgSlug, serverPath, token, method, params) {
|
|
11
11
|
const endpoint = MCP_ENDPOINT(orgSlug, serverPath);
|
|
12
12
|
const body = {
|
|
13
13
|
jsonrpc: '2.0',
|
package/dist/ui.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ export declare const BOLD: import("chalk").ChalkInstance;
|
|
|
7
7
|
export declare const GREEN: import("chalk").ChalkInstance;
|
|
8
8
|
export declare const RED: import("chalk").ChalkInstance;
|
|
9
9
|
export declare const YELLOW: import("chalk").ChalkInstance;
|
|
10
|
-
export declare const CYAN: import("chalk").ChalkInstance;
|
|
11
10
|
export declare const SYM: {
|
|
12
11
|
readonly arrow: string;
|
|
13
12
|
readonly bullet: string;
|
|
@@ -19,6 +18,4 @@ export declare const SYM: {
|
|
|
19
18
|
export declare function heading(text: string): void;
|
|
20
19
|
export declare function line(text: string, indent?: number): void;
|
|
21
20
|
export declare function blank(): void;
|
|
22
|
-
export declare function section(title: string): void;
|
|
23
|
-
export declare function configSnippet(title: string, filename: string, json: Record<string, unknown>): void;
|
|
24
21
|
//# sourceMappingURL=ui.d.ts.map
|
package/dist/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,eAAO,MAAM,KAAK,QAAsC,CAAC;AACzD,eAAO,MAAM,GAAG,+BAAY,CAAC;AAC7B,eAAO,MAAM,IAAI,+BAAa,CAAC;AAC/B,eAAO,MAAM,KAAK,+BAAc,CAAC;AACjC,eAAO,MAAM,GAAG,+BAAY,CAAC;AAC7B,eAAO,MAAM,MAAM,+BAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,eAAO,MAAM,KAAK,QAAsC,CAAC;AACzD,eAAO,MAAM,GAAG,+BAAY,CAAC;AAC7B,eAAO,MAAM,IAAI,+BAAa,CAAC;AAC/B,eAAO,MAAM,KAAK,+BAAc,CAAC;AACjC,eAAO,MAAM,GAAG,+BAAY,CAAC;AAC7B,eAAO,MAAM,MAAM,+BAAe,CAAC;AAMnC,eAAO,MAAM,GAAG;;;;;;;CAON,CAAC;AAMX,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,QAInC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,QAE5C;AAED,wBAAgB,KAAK,SAEpB"}
|
package/dist/ui.js
CHANGED
|
@@ -11,7 +11,6 @@ export const BOLD = chalk.bold;
|
|
|
11
11
|
export const GREEN = chalk.green;
|
|
12
12
|
export const RED = chalk.red;
|
|
13
13
|
export const YELLOW = chalk.yellow;
|
|
14
|
-
export const CYAN = chalk.cyan;
|
|
15
14
|
// ---------------------------------------------------------------------------
|
|
16
15
|
// Symbols
|
|
17
16
|
// ---------------------------------------------------------------------------
|
|
@@ -37,19 +36,3 @@ export function line(text, indent = 2) {
|
|
|
37
36
|
export function blank() {
|
|
38
37
|
console.log();
|
|
39
38
|
}
|
|
40
|
-
export function section(title) {
|
|
41
|
-
console.log();
|
|
42
|
-
console.log(` ${DIM('──')} ${BOLD(title)} ${DIM('─'.repeat(Math.max(0, 48 - title.length)))}`);
|
|
43
|
-
console.log();
|
|
44
|
-
}
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
// Config snippet formatter
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
export function configSnippet(title, filename, json) {
|
|
49
|
-
line(`${BOLD(title)} ${DIM(`(${filename}):`)}`, 4);
|
|
50
|
-
const jsonStr = JSON.stringify(json, null, 2);
|
|
51
|
-
for (const jsonLine of jsonStr.split('\n')) {
|
|
52
|
-
line(DIM(jsonLine), 6);
|
|
53
|
-
}
|
|
54
|
-
blank();
|
|
55
|
-
}
|