runbios-mcp 0.2.1-dev.62
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 +363 -0
- package/dist/api-client.d.ts +147 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +806 -0
- package/dist/api-client.js.map +1 -0
- package/dist/auth.d.ts +3 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +11 -0
- package/dist/auth.js.map +1 -0
- package/dist/config.d.ts +30 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -0
- package/dist/deployment-contract.d.ts +78 -0
- package/dist/deployment-contract.d.ts.map +1 -0
- package/dist/deployment-contract.js +155 -0
- package/dist/deployment-contract.js.map +1 -0
- package/dist/gpu-priorities.d.ts +25 -0
- package/dist/gpu-priorities.d.ts.map +1 -0
- package/dist/gpu-priorities.js +61 -0
- package/dist/gpu-priorities.js.map +1 -0
- package/dist/http/app.d.ts +14 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +140 -0
- package/dist/http/app.js.map +1 -0
- package/dist/http/audit.d.ts +23 -0
- package/dist/http/audit.d.ts.map +1 -0
- package/dist/http/audit.js +41 -0
- package/dist/http/audit.js.map +1 -0
- package/dist/http/config.d.ts +23 -0
- package/dist/http/config.d.ts.map +1 -0
- package/dist/http/config.js +70 -0
- package/dist/http/config.js.map +1 -0
- package/dist/http/consent.d.ts +18 -0
- package/dist/http/consent.d.ts.map +1 -0
- package/dist/http/consent.js +148 -0
- package/dist/http/consent.js.map +1 -0
- package/dist/http/internal-auth.d.ts +22 -0
- package/dist/http/internal-auth.d.ts.map +1 -0
- package/dist/http/internal-auth.js +73 -0
- package/dist/http/internal-auth.js.map +1 -0
- package/dist/http/main.d.ts +3 -0
- package/dist/http/main.d.ts.map +1 -0
- package/dist/http/main.js +65 -0
- package/dist/http/main.js.map +1 -0
- package/dist/http/mcp-handler.d.ts +12 -0
- package/dist/http/mcp-handler.d.ts.map +1 -0
- package/dist/http/mcp-handler.js +103 -0
- package/dist/http/mcp-handler.js.map +1 -0
- package/dist/http/metadata.d.ts +6 -0
- package/dist/http/metadata.d.ts.map +1 -0
- package/dist/http/metadata.js +32 -0
- package/dist/http/metadata.js.map +1 -0
- package/dist/http/oauth.d.ts +56 -0
- package/dist/http/oauth.d.ts.map +1 -0
- package/dist/http/oauth.js +486 -0
- package/dist/http/oauth.js.map +1 -0
- package/dist/http/serviceHostGuard.d.ts +31 -0
- package/dist/http/serviceHostGuard.d.ts.map +1 -0
- package/dist/http/serviceHostGuard.js +68 -0
- package/dist/http/serviceHostGuard.js.map +1 -0
- package/dist/http/store.d.ts +150 -0
- package/dist/http/store.d.ts.map +1 -0
- package/dist/http/store.js +366 -0
- package/dist/http/store.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/inference-contract.d.ts +29 -0
- package/dist/inference-contract.d.ts.map +1 -0
- package/dist/inference-contract.js +112 -0
- package/dist/inference-contract.js.map +1 -0
- package/dist/redaction.d.ts +74 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +316 -0
- package/dist/redaction.js.map +1 -0
- package/dist/server.d.ts +63 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2282 -0
- package/dist/server.js.map +1 -0
- package/dist/training-contract.d.ts +107 -0
- package/dist/training-contract.d.ts.map +1 -0
- package/dist/training-contract.js +141 -0
- package/dist/training-contract.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for the hosted MCP OAuth 2.1 authorization server.
|
|
3
|
+
*
|
|
4
|
+
* Raw credentials (authorization codes, access tokens, refresh tokens,
|
|
5
|
+
* client secrets) are NEVER stored: only their sha256 hex digests are.
|
|
6
|
+
*
|
|
7
|
+
* PgStore is the production implementation (schema "mcp" on
|
|
8
|
+
* MCP_DATABASE_URL). MemoryStore implements the same interface so the OAuth
|
|
9
|
+
* flow is fully testable without Postgres or Docker.
|
|
10
|
+
*/
|
|
11
|
+
/** Minimal query surface of a pg.Pool, so this module never imports pg at runtime. */
|
|
12
|
+
export interface SqlPool {
|
|
13
|
+
query(text: string, values?: unknown[]): Promise<{
|
|
14
|
+
rows: Record<string, unknown>[];
|
|
15
|
+
rowCount: number | null;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export type RequestStatus = "pending" | "approved" | "denied" | "expired";
|
|
19
|
+
export type TokenKind = "access" | "refresh";
|
|
20
|
+
export interface OAuthClientRow {
|
|
21
|
+
client_id: string;
|
|
22
|
+
client_secret_hash: string | null;
|
|
23
|
+
client_name: string;
|
|
24
|
+
redirect_uris: string[];
|
|
25
|
+
token_endpoint_auth_method: string;
|
|
26
|
+
created_at: Date;
|
|
27
|
+
disabled_at: Date | null;
|
|
28
|
+
}
|
|
29
|
+
export interface OAuthRequestRow {
|
|
30
|
+
id: string;
|
|
31
|
+
client_id: string;
|
|
32
|
+
redirect_uri: string;
|
|
33
|
+
scope: string;
|
|
34
|
+
state: string;
|
|
35
|
+
code_challenge: string;
|
|
36
|
+
code_challenge_method: string;
|
|
37
|
+
status: RequestStatus;
|
|
38
|
+
created_at: Date;
|
|
39
|
+
expires_at: Date;
|
|
40
|
+
}
|
|
41
|
+
export interface OAuthGrantRow {
|
|
42
|
+
id: string;
|
|
43
|
+
client_id: string;
|
|
44
|
+
user_id: string;
|
|
45
|
+
user_email: string;
|
|
46
|
+
org_id: string;
|
|
47
|
+
workspace_id: string;
|
|
48
|
+
scopes: string[];
|
|
49
|
+
created_at: Date;
|
|
50
|
+
revoked_at: Date | null;
|
|
51
|
+
last_used_at: Date | null;
|
|
52
|
+
}
|
|
53
|
+
export interface OAuthCodeRow {
|
|
54
|
+
code_hash: string;
|
|
55
|
+
grant_id: string;
|
|
56
|
+
client_id: string;
|
|
57
|
+
redirect_uri: string;
|
|
58
|
+
code_challenge: string;
|
|
59
|
+
code_challenge_method: string;
|
|
60
|
+
created_at: Date;
|
|
61
|
+
expires_at: Date;
|
|
62
|
+
used_at: Date | null;
|
|
63
|
+
}
|
|
64
|
+
export interface OAuthTokenRow {
|
|
65
|
+
token_hash: string;
|
|
66
|
+
kind: TokenKind;
|
|
67
|
+
grant_id: string;
|
|
68
|
+
family_id: string;
|
|
69
|
+
expires_at: Date;
|
|
70
|
+
created_at: Date;
|
|
71
|
+
revoked_at: Date | null;
|
|
72
|
+
replaced_by: string | null;
|
|
73
|
+
}
|
|
74
|
+
export interface McpStore {
|
|
75
|
+
migrate(): Promise<void>;
|
|
76
|
+
insertClient(row: Omit<OAuthClientRow, "created_at" | "disabled_at">): Promise<void>;
|
|
77
|
+
getClient(clientId: string): Promise<OAuthClientRow | null>;
|
|
78
|
+
insertRequest(row: Omit<OAuthRequestRow, "created_at">): Promise<void>;
|
|
79
|
+
getRequest(id: string): Promise<OAuthRequestRow | null>;
|
|
80
|
+
setRequestStatus(id: string, status: RequestStatus): Promise<void>;
|
|
81
|
+
insertGrant(row: Omit<OAuthGrantRow, "created_at" | "revoked_at" | "last_used_at">): Promise<void>;
|
|
82
|
+
getGrant(id: string): Promise<OAuthGrantRow | null>;
|
|
83
|
+
revokeGrant(id: string): Promise<void>;
|
|
84
|
+
/** Sets last_used_at, but only when it is null or older than minAgeMs. */
|
|
85
|
+
touchGrantLastUsed(id: string, minAgeMs: number): Promise<void>;
|
|
86
|
+
insertCode(row: Omit<OAuthCodeRow, "created_at" | "used_at">): Promise<void>;
|
|
87
|
+
getCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
88
|
+
/** Atomically marks the code used. Returns the row, or null when missing or already used. */
|
|
89
|
+
consumeCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
90
|
+
insertToken(row: Omit<OAuthTokenRow, "created_at" | "revoked_at" | "replaced_by">): Promise<void>;
|
|
91
|
+
getToken(tokenHash: string): Promise<OAuthTokenRow | null>;
|
|
92
|
+
revokeToken(tokenHash: string, replacedBy?: string): Promise<void>;
|
|
93
|
+
revokeFamily(familyId: string): Promise<void>;
|
|
94
|
+
revokeTokensForGrant(grantId: string): Promise<void>;
|
|
95
|
+
/** Removes rows that expired long ago; safe to call periodically. */
|
|
96
|
+
cleanupExpired(now?: Date): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
export declare class PgStore implements McpStore {
|
|
99
|
+
private readonly pool;
|
|
100
|
+
constructor(pool: SqlPool);
|
|
101
|
+
migrate(): Promise<void>;
|
|
102
|
+
insertClient(row: Omit<OAuthClientRow, "created_at" | "disabled_at">): Promise<void>;
|
|
103
|
+
getClient(clientId: string): Promise<OAuthClientRow | null>;
|
|
104
|
+
insertRequest(row: Omit<OAuthRequestRow, "created_at">): Promise<void>;
|
|
105
|
+
getRequest(id: string): Promise<OAuthRequestRow | null>;
|
|
106
|
+
setRequestStatus(id: string, status: RequestStatus): Promise<void>;
|
|
107
|
+
insertGrant(row: Omit<OAuthGrantRow, "created_at" | "revoked_at" | "last_used_at">): Promise<void>;
|
|
108
|
+
getGrant(id: string): Promise<OAuthGrantRow | null>;
|
|
109
|
+
revokeGrant(id: string): Promise<void>;
|
|
110
|
+
touchGrantLastUsed(id: string, minAgeMs: number): Promise<void>;
|
|
111
|
+
insertCode(row: Omit<OAuthCodeRow, "created_at" | "used_at">): Promise<void>;
|
|
112
|
+
private static codeFromRow;
|
|
113
|
+
getCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
114
|
+
consumeCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
115
|
+
insertToken(row: Omit<OAuthTokenRow, "created_at" | "revoked_at" | "replaced_by">): Promise<void>;
|
|
116
|
+
getToken(tokenHash: string): Promise<OAuthTokenRow | null>;
|
|
117
|
+
revokeToken(tokenHash: string, replacedBy?: string): Promise<void>;
|
|
118
|
+
revokeFamily(familyId: string): Promise<void>;
|
|
119
|
+
revokeTokensForGrant(grantId: string): Promise<void>;
|
|
120
|
+
cleanupExpired(): Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
export declare class MemoryStore implements McpStore {
|
|
123
|
+
private readonly now;
|
|
124
|
+
clients: Map<string, OAuthClientRow>;
|
|
125
|
+
requests: Map<string, OAuthRequestRow>;
|
|
126
|
+
grants: Map<string, OAuthGrantRow>;
|
|
127
|
+
codes: Map<string, OAuthCodeRow>;
|
|
128
|
+
tokens: Map<string, OAuthTokenRow>;
|
|
129
|
+
constructor(now?: () => Date);
|
|
130
|
+
migrate(): Promise<void>;
|
|
131
|
+
insertClient(row: Omit<OAuthClientRow, "created_at" | "disabled_at">): Promise<void>;
|
|
132
|
+
getClient(clientId: string): Promise<OAuthClientRow | null>;
|
|
133
|
+
insertRequest(row: Omit<OAuthRequestRow, "created_at">): Promise<void>;
|
|
134
|
+
getRequest(id: string): Promise<OAuthRequestRow | null>;
|
|
135
|
+
setRequestStatus(id: string, status: RequestStatus): Promise<void>;
|
|
136
|
+
insertGrant(row: Omit<OAuthGrantRow, "created_at" | "revoked_at" | "last_used_at">): Promise<void>;
|
|
137
|
+
getGrant(id: string): Promise<OAuthGrantRow | null>;
|
|
138
|
+
revokeGrant(id: string): Promise<void>;
|
|
139
|
+
touchGrantLastUsed(id: string, minAgeMs: number): Promise<void>;
|
|
140
|
+
insertCode(row: Omit<OAuthCodeRow, "created_at" | "used_at">): Promise<void>;
|
|
141
|
+
getCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
142
|
+
consumeCode(codeHash: string): Promise<OAuthCodeRow | null>;
|
|
143
|
+
insertToken(row: Omit<OAuthTokenRow, "created_at" | "revoked_at" | "replaced_by">): Promise<void>;
|
|
144
|
+
getToken(tokenHash: string): Promise<OAuthTokenRow | null>;
|
|
145
|
+
revokeToken(tokenHash: string, replacedBy?: string): Promise<void>;
|
|
146
|
+
revokeFamily(familyId: string): Promise<void>;
|
|
147
|
+
revokeTokensForGrant(grantId: string): Promise<void>;
|
|
148
|
+
cleanupExpired(now?: Date): Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/http/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for the hosted MCP OAuth 2.1 authorization server.
|
|
3
|
+
*
|
|
4
|
+
* Raw credentials (authorization codes, access tokens, refresh tokens,
|
|
5
|
+
* client secrets) are NEVER stored: only their sha256 hex digests are.
|
|
6
|
+
*
|
|
7
|
+
* PgStore is the production implementation (schema "mcp" on
|
|
8
|
+
* MCP_DATABASE_URL). MemoryStore implements the same interface so the OAuth
|
|
9
|
+
* flow is fully testable without Postgres or Docker.
|
|
10
|
+
*/
|
|
11
|
+
/* ─── Postgres implementation ─── */
|
|
12
|
+
const MIGRATIONS = [
|
|
13
|
+
// The mcp schema is provisioned by the database bootstrap (owned by the
|
|
14
|
+
// service role, per the one-schema-per-service isolation contract), so the
|
|
15
|
+
// service only creates it when genuinely absent (local dev). An
|
|
16
|
+
// unconditional CREATE SCHEMA IF NOT EXISTS would demand database-level
|
|
17
|
+
// CREATE permission even when the schema already exists.
|
|
18
|
+
`DO $$ BEGIN
|
|
19
|
+
IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'mcp') THEN
|
|
20
|
+
CREATE SCHEMA mcp;
|
|
21
|
+
END IF;
|
|
22
|
+
END $$`,
|
|
23
|
+
`CREATE TABLE IF NOT EXISTS mcp.oauth_clients (
|
|
24
|
+
client_id text PRIMARY KEY,
|
|
25
|
+
client_secret_hash text,
|
|
26
|
+
client_name text NOT NULL DEFAULT 'MCP client',
|
|
27
|
+
redirect_uris jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
28
|
+
token_endpoint_auth_method text NOT NULL DEFAULT 'none',
|
|
29
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
30
|
+
disabled_at timestamptz
|
|
31
|
+
)`,
|
|
32
|
+
`CREATE TABLE IF NOT EXISTS mcp.oauth_requests (
|
|
33
|
+
id text PRIMARY KEY,
|
|
34
|
+
client_id text NOT NULL,
|
|
35
|
+
redirect_uri text NOT NULL,
|
|
36
|
+
scope text NOT NULL DEFAULT '',
|
|
37
|
+
state text NOT NULL DEFAULT '',
|
|
38
|
+
code_challenge text NOT NULL,
|
|
39
|
+
code_challenge_method text NOT NULL DEFAULT 'S256',
|
|
40
|
+
status text NOT NULL DEFAULT 'pending',
|
|
41
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
42
|
+
expires_at timestamptz NOT NULL
|
|
43
|
+
)`,
|
|
44
|
+
`CREATE INDEX IF NOT EXISTS oauth_requests_expires_at_idx ON mcp.oauth_requests (expires_at)`,
|
|
45
|
+
`CREATE TABLE IF NOT EXISTS mcp.oauth_grants (
|
|
46
|
+
id text PRIMARY KEY,
|
|
47
|
+
client_id text NOT NULL,
|
|
48
|
+
user_id text NOT NULL,
|
|
49
|
+
user_email text NOT NULL DEFAULT '',
|
|
50
|
+
org_id text NOT NULL DEFAULT '',
|
|
51
|
+
workspace_id text NOT NULL,
|
|
52
|
+
scopes jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
53
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
54
|
+
revoked_at timestamptz,
|
|
55
|
+
last_used_at timestamptz
|
|
56
|
+
)`,
|
|
57
|
+
`CREATE INDEX IF NOT EXISTS oauth_grants_user_id_idx ON mcp.oauth_grants (user_id)`,
|
|
58
|
+
`CREATE TABLE IF NOT EXISTS mcp.oauth_codes (
|
|
59
|
+
code_hash text PRIMARY KEY,
|
|
60
|
+
grant_id text NOT NULL,
|
|
61
|
+
client_id text NOT NULL,
|
|
62
|
+
redirect_uri text NOT NULL,
|
|
63
|
+
code_challenge text NOT NULL,
|
|
64
|
+
code_challenge_method text NOT NULL DEFAULT 'S256',
|
|
65
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
66
|
+
expires_at timestamptz NOT NULL,
|
|
67
|
+
used_at timestamptz
|
|
68
|
+
)`,
|
|
69
|
+
`CREATE INDEX IF NOT EXISTS oauth_codes_grant_id_idx ON mcp.oauth_codes (grant_id)`,
|
|
70
|
+
`CREATE INDEX IF NOT EXISTS oauth_codes_expires_at_idx ON mcp.oauth_codes (expires_at)`,
|
|
71
|
+
`CREATE TABLE IF NOT EXISTS mcp.oauth_tokens (
|
|
72
|
+
token_hash text PRIMARY KEY,
|
|
73
|
+
kind text NOT NULL,
|
|
74
|
+
grant_id text NOT NULL,
|
|
75
|
+
family_id text NOT NULL,
|
|
76
|
+
expires_at timestamptz NOT NULL,
|
|
77
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
78
|
+
revoked_at timestamptz,
|
|
79
|
+
replaced_by text
|
|
80
|
+
)`,
|
|
81
|
+
`CREATE INDEX IF NOT EXISTS oauth_tokens_grant_id_idx ON mcp.oauth_tokens (grant_id)`,
|
|
82
|
+
`CREATE INDEX IF NOT EXISTS oauth_tokens_family_id_idx ON mcp.oauth_tokens (family_id)`,
|
|
83
|
+
`CREATE INDEX IF NOT EXISTS oauth_tokens_expires_at_idx ON mcp.oauth_tokens (expires_at)`,
|
|
84
|
+
];
|
|
85
|
+
function asStringArray(value) {
|
|
86
|
+
if (Array.isArray(value))
|
|
87
|
+
return value.map((v) => String(v));
|
|
88
|
+
if (typeof value === "string") {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = JSON.parse(value);
|
|
91
|
+
return Array.isArray(parsed) ? parsed.map((v) => String(v)) : [];
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
export class PgStore {
|
|
100
|
+
pool;
|
|
101
|
+
constructor(pool) {
|
|
102
|
+
this.pool = pool;
|
|
103
|
+
}
|
|
104
|
+
async migrate() {
|
|
105
|
+
for (const sql of MIGRATIONS) {
|
|
106
|
+
await this.pool.query(sql);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async insertClient(row) {
|
|
110
|
+
await this.pool.query(`INSERT INTO mcp.oauth_clients
|
|
111
|
+
(client_id, client_secret_hash, client_name, redirect_uris, token_endpoint_auth_method)
|
|
112
|
+
VALUES ($1, $2, $3, $4::jsonb, $5)`, [row.client_id, row.client_secret_hash, row.client_name, JSON.stringify(row.redirect_uris), row.token_endpoint_auth_method]);
|
|
113
|
+
}
|
|
114
|
+
async getClient(clientId) {
|
|
115
|
+
const { rows } = await this.pool.query(`SELECT client_id, client_secret_hash, client_name, redirect_uris,
|
|
116
|
+
token_endpoint_auth_method, created_at, disabled_at
|
|
117
|
+
FROM mcp.oauth_clients WHERE client_id = $1`, [clientId]);
|
|
118
|
+
if (!rows[0])
|
|
119
|
+
return null;
|
|
120
|
+
const r = rows[0];
|
|
121
|
+
return {
|
|
122
|
+
client_id: String(r.client_id),
|
|
123
|
+
client_secret_hash: r.client_secret_hash ?? null,
|
|
124
|
+
client_name: String(r.client_name),
|
|
125
|
+
redirect_uris: asStringArray(r.redirect_uris),
|
|
126
|
+
token_endpoint_auth_method: String(r.token_endpoint_auth_method),
|
|
127
|
+
created_at: r.created_at,
|
|
128
|
+
disabled_at: r.disabled_at ?? null,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async insertRequest(row) {
|
|
132
|
+
await this.pool.query(`INSERT INTO mcp.oauth_requests
|
|
133
|
+
(id, client_id, redirect_uri, scope, state, code_challenge, code_challenge_method, status, expires_at)
|
|
134
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [row.id, row.client_id, row.redirect_uri, row.scope, row.state, row.code_challenge, row.code_challenge_method, row.status, row.expires_at]);
|
|
135
|
+
}
|
|
136
|
+
async getRequest(id) {
|
|
137
|
+
const { rows } = await this.pool.query(`SELECT id, client_id, redirect_uri, scope, state, code_challenge,
|
|
138
|
+
code_challenge_method, status, created_at, expires_at
|
|
139
|
+
FROM mcp.oauth_requests WHERE id = $1`, [id]);
|
|
140
|
+
if (!rows[0])
|
|
141
|
+
return null;
|
|
142
|
+
const r = rows[0];
|
|
143
|
+
return {
|
|
144
|
+
id: String(r.id),
|
|
145
|
+
client_id: String(r.client_id),
|
|
146
|
+
redirect_uri: String(r.redirect_uri),
|
|
147
|
+
scope: String(r.scope ?? ""),
|
|
148
|
+
state: String(r.state ?? ""),
|
|
149
|
+
code_challenge: String(r.code_challenge),
|
|
150
|
+
code_challenge_method: String(r.code_challenge_method),
|
|
151
|
+
status: String(r.status),
|
|
152
|
+
created_at: r.created_at,
|
|
153
|
+
expires_at: r.expires_at,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async setRequestStatus(id, status) {
|
|
157
|
+
await this.pool.query(`UPDATE mcp.oauth_requests SET status = $2 WHERE id = $1`, [id, status]);
|
|
158
|
+
}
|
|
159
|
+
async insertGrant(row) {
|
|
160
|
+
await this.pool.query(`INSERT INTO mcp.oauth_grants
|
|
161
|
+
(id, client_id, user_id, user_email, org_id, workspace_id, scopes)
|
|
162
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`, [row.id, row.client_id, row.user_id, row.user_email, row.org_id, row.workspace_id, JSON.stringify(row.scopes)]);
|
|
163
|
+
}
|
|
164
|
+
async getGrant(id) {
|
|
165
|
+
const { rows } = await this.pool.query(`SELECT id, client_id, user_id, user_email, org_id, workspace_id, scopes,
|
|
166
|
+
created_at, revoked_at, last_used_at
|
|
167
|
+
FROM mcp.oauth_grants WHERE id = $1`, [id]);
|
|
168
|
+
if (!rows[0])
|
|
169
|
+
return null;
|
|
170
|
+
const r = rows[0];
|
|
171
|
+
return {
|
|
172
|
+
id: String(r.id),
|
|
173
|
+
client_id: String(r.client_id),
|
|
174
|
+
user_id: String(r.user_id),
|
|
175
|
+
user_email: String(r.user_email ?? ""),
|
|
176
|
+
org_id: String(r.org_id ?? ""),
|
|
177
|
+
workspace_id: String(r.workspace_id),
|
|
178
|
+
scopes: asStringArray(r.scopes),
|
|
179
|
+
created_at: r.created_at,
|
|
180
|
+
revoked_at: r.revoked_at ?? null,
|
|
181
|
+
last_used_at: r.last_used_at ?? null,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async revokeGrant(id) {
|
|
185
|
+
await this.pool.query(`UPDATE mcp.oauth_grants SET revoked_at = now() WHERE id = $1 AND revoked_at IS NULL`, [id]);
|
|
186
|
+
}
|
|
187
|
+
async touchGrantLastUsed(id, minAgeMs) {
|
|
188
|
+
await this.pool.query(`UPDATE mcp.oauth_grants
|
|
189
|
+
SET last_used_at = now()
|
|
190
|
+
WHERE id = $1
|
|
191
|
+
AND (last_used_at IS NULL OR last_used_at < now() - ($2 || ' milliseconds')::interval)`, [id, String(Math.max(0, Math.floor(minAgeMs)))]);
|
|
192
|
+
}
|
|
193
|
+
async insertCode(row) {
|
|
194
|
+
await this.pool.query(`INSERT INTO mcp.oauth_codes
|
|
195
|
+
(code_hash, grant_id, client_id, redirect_uri, code_challenge, code_challenge_method, expires_at)
|
|
196
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)`, [row.code_hash, row.grant_id, row.client_id, row.redirect_uri, row.code_challenge, row.code_challenge_method, row.expires_at]);
|
|
197
|
+
}
|
|
198
|
+
static codeFromRow(r) {
|
|
199
|
+
return {
|
|
200
|
+
code_hash: String(r.code_hash),
|
|
201
|
+
grant_id: String(r.grant_id),
|
|
202
|
+
client_id: String(r.client_id),
|
|
203
|
+
redirect_uri: String(r.redirect_uri),
|
|
204
|
+
code_challenge: String(r.code_challenge),
|
|
205
|
+
code_challenge_method: String(r.code_challenge_method),
|
|
206
|
+
created_at: r.created_at,
|
|
207
|
+
expires_at: r.expires_at,
|
|
208
|
+
used_at: r.used_at ?? null,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
async getCode(codeHash) {
|
|
212
|
+
const { rows } = await this.pool.query(`SELECT code_hash, grant_id, client_id, redirect_uri, code_challenge,
|
|
213
|
+
code_challenge_method, created_at, expires_at, used_at
|
|
214
|
+
FROM mcp.oauth_codes WHERE code_hash = $1`, [codeHash]);
|
|
215
|
+
return rows[0] ? PgStore.codeFromRow(rows[0]) : null;
|
|
216
|
+
}
|
|
217
|
+
async consumeCode(codeHash) {
|
|
218
|
+
const { rows } = await this.pool.query(`UPDATE mcp.oauth_codes SET used_at = now()
|
|
219
|
+
WHERE code_hash = $1 AND used_at IS NULL
|
|
220
|
+
RETURNING code_hash, grant_id, client_id, redirect_uri, code_challenge,
|
|
221
|
+
code_challenge_method, created_at, expires_at, used_at`, [codeHash]);
|
|
222
|
+
return rows[0] ? PgStore.codeFromRow(rows[0]) : null;
|
|
223
|
+
}
|
|
224
|
+
async insertToken(row) {
|
|
225
|
+
await this.pool.query(`INSERT INTO mcp.oauth_tokens (token_hash, kind, grant_id, family_id, expires_at)
|
|
226
|
+
VALUES ($1, $2, $3, $4, $5)`, [row.token_hash, row.kind, row.grant_id, row.family_id, row.expires_at]);
|
|
227
|
+
}
|
|
228
|
+
async getToken(tokenHash) {
|
|
229
|
+
const { rows } = await this.pool.query(`SELECT token_hash, kind, grant_id, family_id, expires_at, created_at, revoked_at, replaced_by
|
|
230
|
+
FROM mcp.oauth_tokens WHERE token_hash = $1`, [tokenHash]);
|
|
231
|
+
if (!rows[0])
|
|
232
|
+
return null;
|
|
233
|
+
const r = rows[0];
|
|
234
|
+
return {
|
|
235
|
+
token_hash: String(r.token_hash),
|
|
236
|
+
kind: String(r.kind),
|
|
237
|
+
grant_id: String(r.grant_id),
|
|
238
|
+
family_id: String(r.family_id),
|
|
239
|
+
expires_at: r.expires_at,
|
|
240
|
+
created_at: r.created_at,
|
|
241
|
+
revoked_at: r.revoked_at ?? null,
|
|
242
|
+
replaced_by: r.replaced_by ?? null,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
async revokeToken(tokenHash, replacedBy) {
|
|
246
|
+
await this.pool.query(`UPDATE mcp.oauth_tokens
|
|
247
|
+
SET revoked_at = now(), replaced_by = COALESCE($2, replaced_by)
|
|
248
|
+
WHERE token_hash = $1 AND revoked_at IS NULL`, [tokenHash, replacedBy ?? null]);
|
|
249
|
+
}
|
|
250
|
+
async revokeFamily(familyId) {
|
|
251
|
+
await this.pool.query(`UPDATE mcp.oauth_tokens SET revoked_at = now() WHERE family_id = $1 AND revoked_at IS NULL`, [familyId]);
|
|
252
|
+
}
|
|
253
|
+
async revokeTokensForGrant(grantId) {
|
|
254
|
+
await this.pool.query(`UPDATE mcp.oauth_tokens SET revoked_at = now() WHERE grant_id = $1 AND revoked_at IS NULL`, [grantId]);
|
|
255
|
+
}
|
|
256
|
+
async cleanupExpired() {
|
|
257
|
+
await this.pool.query(`DELETE FROM mcp.oauth_requests WHERE expires_at < now() - interval '1 day'`);
|
|
258
|
+
await this.pool.query(`DELETE FROM mcp.oauth_codes WHERE expires_at < now() - interval '1 day'`);
|
|
259
|
+
// Expired token rows are kept for a week so refresh-reuse detection still
|
|
260
|
+
// observes recently rotated-out tokens, then removed.
|
|
261
|
+
await this.pool.query(`DELETE FROM mcp.oauth_tokens WHERE expires_at < now() - interval '7 days'`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/* ─── In-memory implementation (tests) ─── */
|
|
265
|
+
export class MemoryStore {
|
|
266
|
+
now;
|
|
267
|
+
clients = new Map();
|
|
268
|
+
requests = new Map();
|
|
269
|
+
grants = new Map();
|
|
270
|
+
codes = new Map();
|
|
271
|
+
tokens = new Map();
|
|
272
|
+
constructor(now = () => new Date()) {
|
|
273
|
+
this.now = now;
|
|
274
|
+
}
|
|
275
|
+
async migrate() { }
|
|
276
|
+
async insertClient(row) {
|
|
277
|
+
this.clients.set(row.client_id, { ...row, created_at: this.now(), disabled_at: null });
|
|
278
|
+
}
|
|
279
|
+
async getClient(clientId) {
|
|
280
|
+
return this.clients.get(clientId) ?? null;
|
|
281
|
+
}
|
|
282
|
+
async insertRequest(row) {
|
|
283
|
+
this.requests.set(row.id, { ...row, created_at: this.now() });
|
|
284
|
+
}
|
|
285
|
+
async getRequest(id) {
|
|
286
|
+
return this.requests.get(id) ?? null;
|
|
287
|
+
}
|
|
288
|
+
async setRequestStatus(id, status) {
|
|
289
|
+
const row = this.requests.get(id);
|
|
290
|
+
if (row)
|
|
291
|
+
row.status = status;
|
|
292
|
+
}
|
|
293
|
+
async insertGrant(row) {
|
|
294
|
+
this.grants.set(row.id, { ...row, created_at: this.now(), revoked_at: null, last_used_at: null });
|
|
295
|
+
}
|
|
296
|
+
async getGrant(id) {
|
|
297
|
+
return this.grants.get(id) ?? null;
|
|
298
|
+
}
|
|
299
|
+
async revokeGrant(id) {
|
|
300
|
+
const row = this.grants.get(id);
|
|
301
|
+
if (row && !row.revoked_at)
|
|
302
|
+
row.revoked_at = this.now();
|
|
303
|
+
}
|
|
304
|
+
async touchGrantLastUsed(id, minAgeMs) {
|
|
305
|
+
const row = this.grants.get(id);
|
|
306
|
+
if (!row)
|
|
307
|
+
return;
|
|
308
|
+
const t = this.now();
|
|
309
|
+
if (!row.last_used_at || t.getTime() - row.last_used_at.getTime() >= minAgeMs) {
|
|
310
|
+
row.last_used_at = t;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async insertCode(row) {
|
|
314
|
+
this.codes.set(row.code_hash, { ...row, created_at: this.now(), used_at: null });
|
|
315
|
+
}
|
|
316
|
+
async getCode(codeHash) {
|
|
317
|
+
return this.codes.get(codeHash) ?? null;
|
|
318
|
+
}
|
|
319
|
+
async consumeCode(codeHash) {
|
|
320
|
+
const row = this.codes.get(codeHash);
|
|
321
|
+
if (!row || row.used_at)
|
|
322
|
+
return null;
|
|
323
|
+
row.used_at = this.now();
|
|
324
|
+
return row;
|
|
325
|
+
}
|
|
326
|
+
async insertToken(row) {
|
|
327
|
+
this.tokens.set(row.token_hash, { ...row, created_at: this.now(), revoked_at: null, replaced_by: null });
|
|
328
|
+
}
|
|
329
|
+
async getToken(tokenHash) {
|
|
330
|
+
return this.tokens.get(tokenHash) ?? null;
|
|
331
|
+
}
|
|
332
|
+
async revokeToken(tokenHash, replacedBy) {
|
|
333
|
+
const row = this.tokens.get(tokenHash);
|
|
334
|
+
if (row && !row.revoked_at) {
|
|
335
|
+
row.revoked_at = this.now();
|
|
336
|
+
if (replacedBy)
|
|
337
|
+
row.replaced_by = replacedBy;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async revokeFamily(familyId) {
|
|
341
|
+
for (const row of this.tokens.values()) {
|
|
342
|
+
if (row.family_id === familyId && !row.revoked_at)
|
|
343
|
+
row.revoked_at = this.now();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
async revokeTokensForGrant(grantId) {
|
|
347
|
+
for (const row of this.tokens.values()) {
|
|
348
|
+
if (row.grant_id === grantId && !row.revoked_at)
|
|
349
|
+
row.revoked_at = this.now();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
async cleanupExpired(now = this.now()) {
|
|
353
|
+
const dayAgo = now.getTime() - 24 * 3600_000;
|
|
354
|
+
const weekAgo = now.getTime() - 7 * 24 * 3600_000;
|
|
355
|
+
for (const [k, v] of this.requests)
|
|
356
|
+
if (v.expires_at.getTime() < dayAgo)
|
|
357
|
+
this.requests.delete(k);
|
|
358
|
+
for (const [k, v] of this.codes)
|
|
359
|
+
if (v.expires_at.getTime() < dayAgo)
|
|
360
|
+
this.codes.delete(k);
|
|
361
|
+
for (const [k, v] of this.tokens)
|
|
362
|
+
if (v.expires_at.getTime() < weekAgo)
|
|
363
|
+
this.tokens.delete(k);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/http/store.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { buildAuthenticationHeaders } from "./auth.js";
|
|
4
|
+
import { resolveBaseURL } from "./config.js";
|
|
5
|
+
import { BiosClient } from "./api-client.js";
|
|
6
|
+
import { createBiosMcpServer } from "./server.js";
|
|
7
|
+
// RUNBIOS_* is the canonical environment prefix; the legacy BIOS_* names keep
|
|
8
|
+
// working so existing MCP client configs never break.
|
|
9
|
+
function envValue(name) {
|
|
10
|
+
return process.env[`RUNBIOS_${name}`] ?? process.env[`BIOS_${name}`] ?? "";
|
|
11
|
+
}
|
|
12
|
+
const BASE_URL = resolveBaseURL();
|
|
13
|
+
// Derives the console origin from the API base so every channel build points
|
|
14
|
+
// users at ITS environment's dashboard (api-dev → platform-dev, api-staging →
|
|
15
|
+
// platform-staging, api → platform). Non-runbios bases fall back to prod.
|
|
16
|
+
function platformOriginFromApiBase(apiBase) {
|
|
17
|
+
try {
|
|
18
|
+
const u = new URL(apiBase);
|
|
19
|
+
if (u.host.match(/^api(-[a-z0-9]+)?\.runbios\.ai$/)) {
|
|
20
|
+
return `${u.protocol}//${u.host.replace(/^api/, "platform")}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch { /* fall through */ }
|
|
24
|
+
return "https://platform-dev.runbios.ai";
|
|
25
|
+
}
|
|
26
|
+
const API_KEY = envValue("API_KEY");
|
|
27
|
+
const ACCESS_TOKEN = envValue("ACCESS_TOKEN");
|
|
28
|
+
const ORG_ID = envValue("ORG_ID");
|
|
29
|
+
const WORKSPACE_ID = envValue("WORKSPACE_ID");
|
|
30
|
+
const INFERENCE_KEY = envValue("INFERENCE_KEY");
|
|
31
|
+
const INFERENCE_BASE_URL = (envValue("INFERENCE_BASE_URL") || BASE_URL).replace(/\/+$/, "");
|
|
32
|
+
// Optional, per-deployment capability hints the console's "connect via MCP"
|
|
33
|
+
// flow can emit alongside the inference key. They only make chat_with_inference
|
|
34
|
+
// ADVERTISE honestly (omit tools for a text-only deployment; note no-image in
|
|
35
|
+
// the messages description) — the /v1 endpoint still enforces at runtime, so an
|
|
36
|
+
// unset/wrong value never blocks a valid call. Parsed as tri-state: an unset
|
|
37
|
+
// env is `undefined` (full schema), only an explicit "false"/"0"/"no" disables.
|
|
38
|
+
function envBoolOrUndefined(name) {
|
|
39
|
+
const raw = envValue(name).trim().toLowerCase();
|
|
40
|
+
if (raw === "")
|
|
41
|
+
return undefined;
|
|
42
|
+
return !(raw === "false" || raw === "0" || raw === "no");
|
|
43
|
+
}
|
|
44
|
+
const INFERENCE_SUPPORTS_IMAGES = envBoolOrUndefined("INFERENCE_SUPPORTS_IMAGES");
|
|
45
|
+
const INFERENCE_SUPPORTS_TOOLS = envBoolOrUndefined("INFERENCE_SUPPORTS_TOOLS");
|
|
46
|
+
const INFERENCE_TIMEOUT_MS = Math.max(1_000, Number.parseInt(envValue("INFERENCE_TIMEOUT_MS") || "900000", 10) || 900_000);
|
|
47
|
+
/* ─── Start server ─── */
|
|
48
|
+
async function main() {
|
|
49
|
+
if (!API_KEY && !ACCESS_TOKEN) {
|
|
50
|
+
console.error("Error: RUNBIOS_API_KEY or RUNBIOS_ACCESS_TOKEN is required.\n" +
|
|
51
|
+
"Set it in your MCP client config:\n" +
|
|
52
|
+
' "env": { "RUNBIOS_API_KEY": "bios-..." }\n' +
|
|
53
|
+
"(the legacy BIOS_* variable names also still work)\n" +
|
|
54
|
+
`Create an API key at: ${platformOriginFromApiBase(BASE_URL)}/dashboard/api-keys`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
const client = new BiosClient({
|
|
58
|
+
baseUrl: BASE_URL,
|
|
59
|
+
authHeaders: buildAuthenticationHeaders(API_KEY, ACCESS_TOKEN),
|
|
60
|
+
orgId: ORG_ID,
|
|
61
|
+
workspaceId: WORKSPACE_ID,
|
|
62
|
+
inferenceBaseUrl: INFERENCE_BASE_URL,
|
|
63
|
+
inferenceAuthHeader: INFERENCE_KEY ? `Bearer ${INFERENCE_KEY}` : "",
|
|
64
|
+
// Serverless fallback: with no dedicated deployment key, a workspace
|
|
65
|
+
// platform API key (serverless scope) authenticates model-ID-routed
|
|
66
|
+
// catalog calls on the unified /v1 endpoint. Access-token auth cannot mint
|
|
67
|
+
// a serverless bearer here, so it is left unset (dedicated-only).
|
|
68
|
+
serverlessAuthHeader: !INFERENCE_KEY && API_KEY ? `Bearer ${API_KEY}` : "",
|
|
69
|
+
inferenceTimeoutMs: INFERENCE_TIMEOUT_MS,
|
|
70
|
+
});
|
|
71
|
+
const server = createBiosMcpServer(client, undefined, {
|
|
72
|
+
supportsImages: INFERENCE_SUPPORTS_IMAGES,
|
|
73
|
+
supportsTools: INFERENCE_SUPPORTS_TOOLS,
|
|
74
|
+
});
|
|
75
|
+
const transport = new StdioServerTransport();
|
|
76
|
+
await server.connect(transport);
|
|
77
|
+
}
|
|
78
|
+
main();
|
|
79
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|