@stablebaseline/sdk 0.1.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/LICENSE +21 -0
- package/README.md +119 -0
- package/dist/index.cjs +117 -0
- package/dist/index.d.cts +17842 -0
- package/dist/index.d.ts +17842 -0
- package/dist/index.js +90 -0
- package/openapi.json +19378 -0
- package/package.json +69 -0
- package/src/client.ts +164 -0
- package/src/index.ts +20 -0
- package/src/types.generated.ts +17745 -0
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stablebaseline/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for the Stable Baseline REST API. End-to-end agent-managed company brain — docs, diagrams, plans, and a self-learning Knowledge Graph. 163 tools across 16 categories.",
|
|
5
|
+
"homepage": "https://stablebaseline.io",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/stablebaseline/mcp.git",
|
|
9
|
+
"directory": "packages/sdk-typescript"
|
|
10
|
+
},
|
|
11
|
+
"bugs": "https://github.com/stablebaseline/mcp/issues",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"stablebaseline",
|
|
15
|
+
"stable-baseline",
|
|
16
|
+
"mcp",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"knowledge-graph",
|
|
19
|
+
"company-brain",
|
|
20
|
+
"documentation",
|
|
21
|
+
"diagrams",
|
|
22
|
+
"plans",
|
|
23
|
+
"ai-agent",
|
|
24
|
+
"rest-api",
|
|
25
|
+
"sdk",
|
|
26
|
+
"typescript"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./dist/index.cjs",
|
|
30
|
+
"module": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.js",
|
|
36
|
+
"require": "./dist/index.cjs"
|
|
37
|
+
},
|
|
38
|
+
"./types": {
|
|
39
|
+
"types": "./dist/types.generated.d.ts"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"src",
|
|
45
|
+
"openapi.json",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"codegen": "openapi-typescript ./openapi.json -o ./src/types.generated.ts",
|
|
51
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
52
|
+
"prepublishOnly": "npm run codegen && npm run build",
|
|
53
|
+
"test": "node --test"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"openapi-fetch": "^0.13.4"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"openapi-typescript": "^7.5.0",
|
|
60
|
+
"tsup": "^8.3.5",
|
|
61
|
+
"typescript": "^5.6.3"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=18"
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import createOpenApiClient from "openapi-fetch";
|
|
2
|
+
import type { paths } from "./types.generated.js";
|
|
3
|
+
|
|
4
|
+
const DEFAULT_BASE_URL =
|
|
5
|
+
"https://api.stablebaseline.io/functions/v1/cloud-serve/api/v1";
|
|
6
|
+
|
|
7
|
+
export interface StableBaselineClientOptions {
|
|
8
|
+
/**
|
|
9
|
+
* MCP API key with the `sta_` prefix. Mint at
|
|
10
|
+
* https://app.stablebaseline.io/settings/mcp-keys.
|
|
11
|
+
*
|
|
12
|
+
* Either `apiKey` or `accessToken` is required (mutually exclusive).
|
|
13
|
+
*/
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* OAuth 2.1 access token (Bearer) — for clients that authenticate via the
|
|
18
|
+
* OAuth flow at https://app.stablebaseline.io/oauth/authorize.
|
|
19
|
+
*/
|
|
20
|
+
accessToken?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Override the API base URL. Default:
|
|
24
|
+
* `https://api.stablebaseline.io/functions/v1/cloud-serve/api/v1`
|
|
25
|
+
*/
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Custom `fetch` implementation. Defaults to `globalThis.fetch`. Useful for
|
|
30
|
+
* testing or when running in a sandboxed runtime.
|
|
31
|
+
*/
|
|
32
|
+
fetch?: typeof fetch;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Per-request abort signal — applied to every call made by this client.
|
|
36
|
+
*/
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ToolError extends Error {
|
|
41
|
+
status: number;
|
|
42
|
+
code: string;
|
|
43
|
+
details?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function makeAuthHeader(opts: StableBaselineClientOptions): Record<string, string> {
|
|
47
|
+
const token = opts.accessToken ?? opts.apiKey;
|
|
48
|
+
if (!token) return {};
|
|
49
|
+
return { Authorization: `Bearer ${token}` };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class StableBaselineToolError extends Error implements ToolError {
|
|
53
|
+
constructor(
|
|
54
|
+
public status: number,
|
|
55
|
+
public code: string,
|
|
56
|
+
message: string,
|
|
57
|
+
public details?: Record<string, unknown>,
|
|
58
|
+
) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = "StableBaselineToolError";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Tool-RPC dispatch. Each method on `client.tools` posts to
|
|
66
|
+
* `POST /tools/{toolName}` with the input as the JSON body and returns the
|
|
67
|
+
* server's parsed JSON response. Errors are thrown as `StableBaselineToolError`.
|
|
68
|
+
*/
|
|
69
|
+
type ToolPath = keyof paths & `/tools/${string}`;
|
|
70
|
+
type ToolName<P extends ToolPath> = P extends `/tools/${infer N}` ? N : never;
|
|
71
|
+
|
|
72
|
+
type ToolInput<P extends ToolPath> = paths[P] extends {
|
|
73
|
+
post: { requestBody?: { content: { "application/json": infer I } } };
|
|
74
|
+
}
|
|
75
|
+
? I
|
|
76
|
+
: never;
|
|
77
|
+
|
|
78
|
+
type ToolOutput<P extends ToolPath> = paths[P] extends {
|
|
79
|
+
post: { responses: { 200: { content: { "application/json": infer O } } } };
|
|
80
|
+
}
|
|
81
|
+
? O
|
|
82
|
+
: unknown;
|
|
83
|
+
|
|
84
|
+
type ToolNames = { [P in ToolPath]: ToolName<P> }[ToolPath];
|
|
85
|
+
type ToolDispatchMap = {
|
|
86
|
+
[K in ToolNames]: (input: ToolInput<`/tools/${K}` & ToolPath>) => Promise<ToolOutput<`/tools/${K}` & ToolPath>>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export class StableBaseline {
|
|
90
|
+
private fetch: typeof fetch;
|
|
91
|
+
private baseUrl: string;
|
|
92
|
+
private authHeader: Record<string, string>;
|
|
93
|
+
private signal?: AbortSignal;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Strongly-typed dispatch surface. Every entry is one of the 163 MCP tools.
|
|
97
|
+
*
|
|
98
|
+
* const orgs = await sb.tools.listOrganisations({});
|
|
99
|
+
* const doc = await sb.tools.createDocument({ folderId, title, cdmd });
|
|
100
|
+
*/
|
|
101
|
+
public tools: ToolDispatchMap;
|
|
102
|
+
|
|
103
|
+
constructor(opts: StableBaselineClientOptions = {}) {
|
|
104
|
+
if (!opts.apiKey && !opts.accessToken) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"StableBaseline: provide either `apiKey` (sta_*) or `accessToken` (OAuth Bearer).",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
this.fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
110
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
111
|
+
this.authHeader = makeAuthHeader(opts);
|
|
112
|
+
this.signal = opts.signal;
|
|
113
|
+
|
|
114
|
+
// Build the tool-dispatch surface as a Proxy. Each property access
|
|
115
|
+
// returns a function that POSTs to `/tools/<name>`. This avoids hand-
|
|
116
|
+
// listing 163 methods while keeping full type safety on usage thanks
|
|
117
|
+
// to the generated `paths` type above.
|
|
118
|
+
const self = this;
|
|
119
|
+
this.tools = new Proxy({} as ToolDispatchMap, {
|
|
120
|
+
get(_target, prop: string) {
|
|
121
|
+
if (typeof prop !== "string") return undefined;
|
|
122
|
+
return (input: unknown) => self.callTool(prop, input);
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Call a tool by name. Mainly an escape hatch — prefer `client.tools.<toolName>`. */
|
|
128
|
+
async callTool<T = unknown>(name: string, input?: unknown): Promise<T> {
|
|
129
|
+
const url = `${this.baseUrl}/tools/${encodeURIComponent(name)}`;
|
|
130
|
+
const res = await this.fetch(url, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: { "Content-Type": "application/json", ...this.authHeader },
|
|
133
|
+
body: JSON.stringify(input ?? {}),
|
|
134
|
+
signal: this.signal,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (!res.ok) {
|
|
138
|
+
let body: any = null;
|
|
139
|
+
try { body = await res.json(); } catch { /* not JSON */ }
|
|
140
|
+
const errEnvelope = body?.error ?? {};
|
|
141
|
+
throw new StableBaselineToolError(
|
|
142
|
+
res.status,
|
|
143
|
+
errEnvelope.code ?? `http_${res.status}`,
|
|
144
|
+
errEnvelope.message ?? `${res.status} ${res.statusText}`,
|
|
145
|
+
errEnvelope.details,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return res.json() as Promise<T>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Fetch the live OpenAPI spec from the server. Useful for code generation. */
|
|
152
|
+
async openapi(): Promise<unknown> {
|
|
153
|
+
const res = await this.fetch(`${this.baseUrl}/openapi.json`, { signal: this.signal });
|
|
154
|
+
if (!res.ok) throw new Error(`Failed to fetch OpenAPI: ${res.status}`);
|
|
155
|
+
return res.json();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Lightweight tool-catalogue discovery without parsing the full OpenAPI doc. */
|
|
159
|
+
async listTools(): Promise<{ count: number; tools: Array<{ name: string; description: string; category: string; anonymous: boolean; feature: string | null }> }> {
|
|
160
|
+
const res = await this.fetch(`${this.baseUrl}/tools`, { signal: this.signal });
|
|
161
|
+
if (!res.ok) throw new Error(`Failed to list tools: ${res.status}`);
|
|
162
|
+
return res.json();
|
|
163
|
+
}
|
|
164
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @stablebaseline/sdk — TypeScript SDK for the Stable Baseline REST API.
|
|
2
|
+
//
|
|
3
|
+
// import { StableBaseline } from "@stablebaseline/sdk";
|
|
4
|
+
//
|
|
5
|
+
// const sb = new StableBaseline({ apiKey: "sta_xxx" });
|
|
6
|
+
// const orgs = await sb.tools.listOrganisations({});
|
|
7
|
+
// const doc = await sb.tools.createDocument({
|
|
8
|
+
// folderId: "...",
|
|
9
|
+
// title: "Q4 architecture",
|
|
10
|
+
// cdmd: "# ...",
|
|
11
|
+
// });
|
|
12
|
+
//
|
|
13
|
+
// All 163 MCP tools are reachable from `sb.tools.<toolName>(input)`. Types
|
|
14
|
+
// are generated from the live OpenAPI spec (`openapi.json` in this package).
|
|
15
|
+
|
|
16
|
+
export { StableBaseline } from "./client.js";
|
|
17
|
+
export type { StableBaselineClientOptions, ToolError } from "./client.js";
|
|
18
|
+
|
|
19
|
+
// Re-export the generated types so consumers can `import type { ... } from "@stablebaseline/sdk/types"`.
|
|
20
|
+
export type * from "./types.generated.js";
|