@exposify/supabase 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/README.md +228 -0
- package/dist/cli.js +266 -0
- package/dist/index.cjs +718 -0
- package/dist/index.d.cts +171 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +687 -0
- package/package.json +43 -0
- package/sql/agentify_meta.sql +46 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { WebMcpHandler } from '@exposify/core';
|
|
2
|
+
|
|
3
|
+
type ColumnType = "string" | "number" | "integer" | "boolean" | "object" | "array";
|
|
4
|
+
interface ColumnSchema {
|
|
5
|
+
name: string;
|
|
6
|
+
type: ColumnType;
|
|
7
|
+
/** OpenAPI `format`, e.g. "uuid", "timestamp with time zone", "bigint". */
|
|
8
|
+
format?: string;
|
|
9
|
+
required: boolean;
|
|
10
|
+
/** From `agentify_meta()`'s `column_comment` (a `COMMENT ON COLUMN`), not OpenAPI. */
|
|
11
|
+
description?: string;
|
|
12
|
+
isPrimaryKey?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface TableSchema {
|
|
15
|
+
name: string;
|
|
16
|
+
rlsEnabled: boolean;
|
|
17
|
+
/** From `agentify_meta()`'s `table_comment` (a `COMMENT ON TABLE`). */
|
|
18
|
+
description?: string;
|
|
19
|
+
columns: ColumnSchema[];
|
|
20
|
+
}
|
|
21
|
+
/** One row of `agentify_meta()` -- the migration returns one row per column. */
|
|
22
|
+
interface MetaRow {
|
|
23
|
+
table_name: string;
|
|
24
|
+
rls_enabled: boolean;
|
|
25
|
+
table_comment: string | null;
|
|
26
|
+
column_name: string;
|
|
27
|
+
column_comment: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Registered sibling edge function exposed as a tool. */
|
|
30
|
+
interface FunctionToolConfig {
|
|
31
|
+
description: string;
|
|
32
|
+
/** A pragmatic JSON Schema subset -- see jsonschema-to-zod.ts. */
|
|
33
|
+
input?: JsonSchemaObject;
|
|
34
|
+
}
|
|
35
|
+
interface JsonSchemaProperty {
|
|
36
|
+
type: "string" | "number" | "integer" | "boolean" | "array" | "object";
|
|
37
|
+
description?: string;
|
|
38
|
+
enum?: unknown[];
|
|
39
|
+
items?: JsonSchemaProperty;
|
|
40
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
41
|
+
required?: string[];
|
|
42
|
+
}
|
|
43
|
+
interface JsonSchemaObject {
|
|
44
|
+
type?: "object";
|
|
45
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
46
|
+
required?: string[];
|
|
47
|
+
}
|
|
48
|
+
interface AgentifySupabaseOptions {
|
|
49
|
+
/** `"<table>.insert"` / `"<table>.update"` / `"<table>.delete"` / `"<table>.*"`. */
|
|
50
|
+
writes?: string[];
|
|
51
|
+
/** Postgres function names exposed as `rpc_<fn>` tools. */
|
|
52
|
+
rpc?: string[];
|
|
53
|
+
/** Sibling edge functions, invoked via fetch with the caller's forwarded JWT. */
|
|
54
|
+
functions?: Record<string, FunctionToolConfig>;
|
|
55
|
+
/** Doc globs bundled in the function directory. Default: `["docs/**\/*.md"]`. */
|
|
56
|
+
docs?: string[];
|
|
57
|
+
docsAuth?: "public" | "required";
|
|
58
|
+
/** Row cap applied to every `query_<table>` call regardless of caller-supplied `limit`. Default 100. */
|
|
59
|
+
maxRows?: number;
|
|
60
|
+
/** Overrides for local/CI use -- production reads these from the Deno env automatically. */
|
|
61
|
+
supabaseUrl?: string;
|
|
62
|
+
anonKey?: string;
|
|
63
|
+
/** Injectable for tests; defaults to global `fetch`. */
|
|
64
|
+
fetchImpl?: typeof fetch;
|
|
65
|
+
/** Bundled fallback manifest (from `agentify-supabase generate`), used when runtime introspection fails. */
|
|
66
|
+
manifest?: unknown;
|
|
67
|
+
rateLimit?: number;
|
|
68
|
+
rateWindowMs?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Subset of PostgREST's generated OpenAPI (Swagger 2.0) document that we read. */
|
|
72
|
+
interface PostgrestOpenApiDoc {
|
|
73
|
+
definitions?: Record<string, PostgrestTableDefinition>;
|
|
74
|
+
paths?: Record<string, PostgrestPathItem>;
|
|
75
|
+
}
|
|
76
|
+
interface PostgrestPathItem {
|
|
77
|
+
post?: {
|
|
78
|
+
parameters?: PostgrestParameter[];
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
interface PostgrestParameter {
|
|
82
|
+
in?: string;
|
|
83
|
+
schema?: {
|
|
84
|
+
type?: string;
|
|
85
|
+
properties?: Record<string, PostgrestColumnProperty>;
|
|
86
|
+
required?: string[];
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface PostgrestTableDefinition {
|
|
90
|
+
properties?: Record<string, PostgrestColumnProperty>;
|
|
91
|
+
required?: string[];
|
|
92
|
+
}
|
|
93
|
+
interface PostgrestColumnProperty {
|
|
94
|
+
type?: string;
|
|
95
|
+
format?: string;
|
|
96
|
+
description?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extracts column schemas for one table from a PostgREST OpenAPI document.
|
|
100
|
+
* Returns `[]` for a table PostgREST never exposed (not in `definitions` --
|
|
101
|
+
* e.g. it exists at the catalog level per `agentify_meta()` but PostgREST's
|
|
102
|
+
* role lacks USAGE/SELECT grants on it), which the caller treats the same as
|
|
103
|
+
* "RLS-less": never shown to the agent.
|
|
104
|
+
*/
|
|
105
|
+
declare function columnsFromOpenApi(doc: PostgrestOpenApiDoc, table: string): ColumnSchema[];
|
|
106
|
+
/**
|
|
107
|
+
* Best-effort extraction of an `rpc_<fn>` tool's argument schema from
|
|
108
|
+
* PostgREST's OpenAPI doc (Swagger 2.0 body parameter on `POST /rpc/<fn>`).
|
|
109
|
+
* Returns `null` when the shape isn't there or isn't the expected object
|
|
110
|
+
* schema -- the caller falls back to a permissive `args` record (see
|
|
111
|
+
* server.ts), never throws.
|
|
112
|
+
*/
|
|
113
|
+
declare function rpcArgSchema(doc: PostgrestOpenApiDoc, fn: string): JsonSchemaObject | null;
|
|
114
|
+
|
|
115
|
+
declare const MANIFEST_VERSION = 1;
|
|
116
|
+
interface AgentifyManifest {
|
|
117
|
+
version: typeof MANIFEST_VERSION;
|
|
118
|
+
generatedAt: string;
|
|
119
|
+
tables: TableSchema[];
|
|
120
|
+
}
|
|
121
|
+
/** Built by `npx agentify-supabase generate` against a local/linked project. */
|
|
122
|
+
declare function buildManifest(openapi: PostgrestOpenApiDoc, metaRows: MetaRow[], generatedAt: string): AgentifyManifest;
|
|
123
|
+
/**
|
|
124
|
+
* Defensive load: a manifest is bundled JSON shipped alongside the function
|
|
125
|
+
* and can go stale relative to the deployed schema, or simply be malformed
|
|
126
|
+
* (hand-edited, wrong version). Returns `null` -- never throws -- so the
|
|
127
|
+
* degradation ladder can fall through to the next rung instead of crashing.
|
|
128
|
+
*/
|
|
129
|
+
declare function loadManifest(raw: unknown): AgentifyManifest | null;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Merges PostgREST's OpenAPI document (column types) with `agentify_meta()`
|
|
133
|
+
* rows (RLS status + comments) into the DB tool surface.
|
|
134
|
+
*
|
|
135
|
+
* DB exposure policy (spec, locked): RLS-gated, reads auto. A table only
|
|
136
|
+
* appears here if `agentify_meta()` reports `rls_enabled: true` for it AND
|
|
137
|
+
* PostgREST actually exposes it in its OpenAPI `definitions` (the role
|
|
138
|
+
* calling this has grants on it) -- a table failing either check never
|
|
139
|
+
* appears, silently, exactly like a table PostgREST doesn't know about at
|
|
140
|
+
* all. There is no override: an RLS-less table is invisible even if the
|
|
141
|
+
* owner explicitly lists it in `writes`.
|
|
142
|
+
*/
|
|
143
|
+
declare function introspectTables(openapi: PostgrestOpenApiDoc, metaRows: MetaRow[]): TableSchema[];
|
|
144
|
+
|
|
145
|
+
declare class MissingAgentifyMetaError extends Error {
|
|
146
|
+
constructor(cause: string);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Calls the `agentify_meta()` Postgres function via PostgREST's RPC
|
|
150
|
+
* endpoint. Requires the migration from `sql/agentify_meta.sql` to have been
|
|
151
|
+
* applied; a 404 (unknown route) or PostgREST's `PGRST202` (function not
|
|
152
|
+
* found in schema cache) both mean "migration missing" and are translated
|
|
153
|
+
* into a self-diagnosing error (spec: "a missing `agentify_meta()` migration
|
|
154
|
+
* produces a self-diagnosing message naming the exact fix").
|
|
155
|
+
*/
|
|
156
|
+
declare function fetchAgentifyMeta(postgrestUrl: string, headers: Headers, fetchImpl: typeof fetch): Promise<MetaRow[]>;
|
|
157
|
+
|
|
158
|
+
/** PostgREST serves its OpenAPI document at the API root when asked for it explicitly. */
|
|
159
|
+
declare function fetchOpenApi(postgrestUrl: string, headers: Headers, fetchImpl: typeof fetch): Promise<PostgrestOpenApiDoc>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Builds the `Deno.serve`-compatible MCP handler. Everything expensive
|
|
163
|
+
* (OpenAPI fetch, `agentify_meta()` call, doc loading/chunking) happens
|
|
164
|
+
* lazily on first request and is cached in-memory for the life of the edge
|
|
165
|
+
* instance -- "cold start" in the spec's sense, not literally module load,
|
|
166
|
+
* since env vars and the incoming JWT aren't available before the first
|
|
167
|
+
* request lands anyway.
|
|
168
|
+
*/
|
|
169
|
+
declare function aiReady(options?: AgentifySupabaseOptions): WebMcpHandler;
|
|
170
|
+
|
|
171
|
+
export { type AgentifyManifest, type AgentifySupabaseOptions, MANIFEST_VERSION, MissingAgentifyMetaError, type PostgrestOpenApiDoc, aiReady, buildManifest, columnsFromOpenApi, fetchAgentifyMeta, fetchOpenApi, introspectTables, loadManifest, rpcArgSchema };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { WebMcpHandler } from '@exposify/core';
|
|
2
|
+
|
|
3
|
+
type ColumnType = "string" | "number" | "integer" | "boolean" | "object" | "array";
|
|
4
|
+
interface ColumnSchema {
|
|
5
|
+
name: string;
|
|
6
|
+
type: ColumnType;
|
|
7
|
+
/** OpenAPI `format`, e.g. "uuid", "timestamp with time zone", "bigint". */
|
|
8
|
+
format?: string;
|
|
9
|
+
required: boolean;
|
|
10
|
+
/** From `agentify_meta()`'s `column_comment` (a `COMMENT ON COLUMN`), not OpenAPI. */
|
|
11
|
+
description?: string;
|
|
12
|
+
isPrimaryKey?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface TableSchema {
|
|
15
|
+
name: string;
|
|
16
|
+
rlsEnabled: boolean;
|
|
17
|
+
/** From `agentify_meta()`'s `table_comment` (a `COMMENT ON TABLE`). */
|
|
18
|
+
description?: string;
|
|
19
|
+
columns: ColumnSchema[];
|
|
20
|
+
}
|
|
21
|
+
/** One row of `agentify_meta()` -- the migration returns one row per column. */
|
|
22
|
+
interface MetaRow {
|
|
23
|
+
table_name: string;
|
|
24
|
+
rls_enabled: boolean;
|
|
25
|
+
table_comment: string | null;
|
|
26
|
+
column_name: string;
|
|
27
|
+
column_comment: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Registered sibling edge function exposed as a tool. */
|
|
30
|
+
interface FunctionToolConfig {
|
|
31
|
+
description: string;
|
|
32
|
+
/** A pragmatic JSON Schema subset -- see jsonschema-to-zod.ts. */
|
|
33
|
+
input?: JsonSchemaObject;
|
|
34
|
+
}
|
|
35
|
+
interface JsonSchemaProperty {
|
|
36
|
+
type: "string" | "number" | "integer" | "boolean" | "array" | "object";
|
|
37
|
+
description?: string;
|
|
38
|
+
enum?: unknown[];
|
|
39
|
+
items?: JsonSchemaProperty;
|
|
40
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
41
|
+
required?: string[];
|
|
42
|
+
}
|
|
43
|
+
interface JsonSchemaObject {
|
|
44
|
+
type?: "object";
|
|
45
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
46
|
+
required?: string[];
|
|
47
|
+
}
|
|
48
|
+
interface AgentifySupabaseOptions {
|
|
49
|
+
/** `"<table>.insert"` / `"<table>.update"` / `"<table>.delete"` / `"<table>.*"`. */
|
|
50
|
+
writes?: string[];
|
|
51
|
+
/** Postgres function names exposed as `rpc_<fn>` tools. */
|
|
52
|
+
rpc?: string[];
|
|
53
|
+
/** Sibling edge functions, invoked via fetch with the caller's forwarded JWT. */
|
|
54
|
+
functions?: Record<string, FunctionToolConfig>;
|
|
55
|
+
/** Doc globs bundled in the function directory. Default: `["docs/**\/*.md"]`. */
|
|
56
|
+
docs?: string[];
|
|
57
|
+
docsAuth?: "public" | "required";
|
|
58
|
+
/** Row cap applied to every `query_<table>` call regardless of caller-supplied `limit`. Default 100. */
|
|
59
|
+
maxRows?: number;
|
|
60
|
+
/** Overrides for local/CI use -- production reads these from the Deno env automatically. */
|
|
61
|
+
supabaseUrl?: string;
|
|
62
|
+
anonKey?: string;
|
|
63
|
+
/** Injectable for tests; defaults to global `fetch`. */
|
|
64
|
+
fetchImpl?: typeof fetch;
|
|
65
|
+
/** Bundled fallback manifest (from `agentify-supabase generate`), used when runtime introspection fails. */
|
|
66
|
+
manifest?: unknown;
|
|
67
|
+
rateLimit?: number;
|
|
68
|
+
rateWindowMs?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Subset of PostgREST's generated OpenAPI (Swagger 2.0) document that we read. */
|
|
72
|
+
interface PostgrestOpenApiDoc {
|
|
73
|
+
definitions?: Record<string, PostgrestTableDefinition>;
|
|
74
|
+
paths?: Record<string, PostgrestPathItem>;
|
|
75
|
+
}
|
|
76
|
+
interface PostgrestPathItem {
|
|
77
|
+
post?: {
|
|
78
|
+
parameters?: PostgrestParameter[];
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
interface PostgrestParameter {
|
|
82
|
+
in?: string;
|
|
83
|
+
schema?: {
|
|
84
|
+
type?: string;
|
|
85
|
+
properties?: Record<string, PostgrestColumnProperty>;
|
|
86
|
+
required?: string[];
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface PostgrestTableDefinition {
|
|
90
|
+
properties?: Record<string, PostgrestColumnProperty>;
|
|
91
|
+
required?: string[];
|
|
92
|
+
}
|
|
93
|
+
interface PostgrestColumnProperty {
|
|
94
|
+
type?: string;
|
|
95
|
+
format?: string;
|
|
96
|
+
description?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extracts column schemas for one table from a PostgREST OpenAPI document.
|
|
100
|
+
* Returns `[]` for a table PostgREST never exposed (not in `definitions` --
|
|
101
|
+
* e.g. it exists at the catalog level per `agentify_meta()` but PostgREST's
|
|
102
|
+
* role lacks USAGE/SELECT grants on it), which the caller treats the same as
|
|
103
|
+
* "RLS-less": never shown to the agent.
|
|
104
|
+
*/
|
|
105
|
+
declare function columnsFromOpenApi(doc: PostgrestOpenApiDoc, table: string): ColumnSchema[];
|
|
106
|
+
/**
|
|
107
|
+
* Best-effort extraction of an `rpc_<fn>` tool's argument schema from
|
|
108
|
+
* PostgREST's OpenAPI doc (Swagger 2.0 body parameter on `POST /rpc/<fn>`).
|
|
109
|
+
* Returns `null` when the shape isn't there or isn't the expected object
|
|
110
|
+
* schema -- the caller falls back to a permissive `args` record (see
|
|
111
|
+
* server.ts), never throws.
|
|
112
|
+
*/
|
|
113
|
+
declare function rpcArgSchema(doc: PostgrestOpenApiDoc, fn: string): JsonSchemaObject | null;
|
|
114
|
+
|
|
115
|
+
declare const MANIFEST_VERSION = 1;
|
|
116
|
+
interface AgentifyManifest {
|
|
117
|
+
version: typeof MANIFEST_VERSION;
|
|
118
|
+
generatedAt: string;
|
|
119
|
+
tables: TableSchema[];
|
|
120
|
+
}
|
|
121
|
+
/** Built by `npx agentify-supabase generate` against a local/linked project. */
|
|
122
|
+
declare function buildManifest(openapi: PostgrestOpenApiDoc, metaRows: MetaRow[], generatedAt: string): AgentifyManifest;
|
|
123
|
+
/**
|
|
124
|
+
* Defensive load: a manifest is bundled JSON shipped alongside the function
|
|
125
|
+
* and can go stale relative to the deployed schema, or simply be malformed
|
|
126
|
+
* (hand-edited, wrong version). Returns `null` -- never throws -- so the
|
|
127
|
+
* degradation ladder can fall through to the next rung instead of crashing.
|
|
128
|
+
*/
|
|
129
|
+
declare function loadManifest(raw: unknown): AgentifyManifest | null;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Merges PostgREST's OpenAPI document (column types) with `agentify_meta()`
|
|
133
|
+
* rows (RLS status + comments) into the DB tool surface.
|
|
134
|
+
*
|
|
135
|
+
* DB exposure policy (spec, locked): RLS-gated, reads auto. A table only
|
|
136
|
+
* appears here if `agentify_meta()` reports `rls_enabled: true` for it AND
|
|
137
|
+
* PostgREST actually exposes it in its OpenAPI `definitions` (the role
|
|
138
|
+
* calling this has grants on it) -- a table failing either check never
|
|
139
|
+
* appears, silently, exactly like a table PostgREST doesn't know about at
|
|
140
|
+
* all. There is no override: an RLS-less table is invisible even if the
|
|
141
|
+
* owner explicitly lists it in `writes`.
|
|
142
|
+
*/
|
|
143
|
+
declare function introspectTables(openapi: PostgrestOpenApiDoc, metaRows: MetaRow[]): TableSchema[];
|
|
144
|
+
|
|
145
|
+
declare class MissingAgentifyMetaError extends Error {
|
|
146
|
+
constructor(cause: string);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Calls the `agentify_meta()` Postgres function via PostgREST's RPC
|
|
150
|
+
* endpoint. Requires the migration from `sql/agentify_meta.sql` to have been
|
|
151
|
+
* applied; a 404 (unknown route) or PostgREST's `PGRST202` (function not
|
|
152
|
+
* found in schema cache) both mean "migration missing" and are translated
|
|
153
|
+
* into a self-diagnosing error (spec: "a missing `agentify_meta()` migration
|
|
154
|
+
* produces a self-diagnosing message naming the exact fix").
|
|
155
|
+
*/
|
|
156
|
+
declare function fetchAgentifyMeta(postgrestUrl: string, headers: Headers, fetchImpl: typeof fetch): Promise<MetaRow[]>;
|
|
157
|
+
|
|
158
|
+
/** PostgREST serves its OpenAPI document at the API root when asked for it explicitly. */
|
|
159
|
+
declare function fetchOpenApi(postgrestUrl: string, headers: Headers, fetchImpl: typeof fetch): Promise<PostgrestOpenApiDoc>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Builds the `Deno.serve`-compatible MCP handler. Everything expensive
|
|
163
|
+
* (OpenAPI fetch, `agentify_meta()` call, doc loading/chunking) happens
|
|
164
|
+
* lazily on first request and is cached in-memory for the life of the edge
|
|
165
|
+
* instance -- "cold start" in the spec's sense, not literally module load,
|
|
166
|
+
* since env vars and the incoming JWT aren't available before the first
|
|
167
|
+
* request lands anyway.
|
|
168
|
+
*/
|
|
169
|
+
declare function aiReady(options?: AgentifySupabaseOptions): WebMcpHandler;
|
|
170
|
+
|
|
171
|
+
export { type AgentifyManifest, type AgentifySupabaseOptions, MANIFEST_VERSION, MissingAgentifyMetaError, type PostgrestOpenApiDoc, aiReady, buildManifest, columnsFromOpenApi, fetchAgentifyMeta, fetchOpenApi, introspectTables, loadManifest, rpcArgSchema };
|