@integrity-labs/cloud-broker 0.7.9 → 0.7.11

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.
Files changed (2) hide show
  1. package/dist/index.js +82 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21364,6 +21364,32 @@ var BrokerClient = class {
21364
21364
  { query: this.agentId ? { agent_id: this.agentId } : void 0 }
21365
21365
  );
21366
21366
  }
21367
+ // ENG-7326 Phase 1: capability tools. Server-side scoped execution - the
21368
+ // agent never receives a database credential.
21369
+ supabaseQuery(args) {
21370
+ return this.request(
21371
+ "POST",
21372
+ `/supabase/grants/${encodeURIComponent(args.grant_id)}/query`,
21373
+ { query: this.agentId ? { agent_id: this.agentId } : void 0, body: { sql: args.sql } }
21374
+ );
21375
+ }
21376
+ supabaseDescribe(args) {
21377
+ return this.request(
21378
+ "GET",
21379
+ `/supabase/grants/${encodeURIComponent(args.grant_id)}/describe`,
21380
+ { query: this.agentId ? { agent_id: this.agentId } : void 0 }
21381
+ );
21382
+ }
21383
+ supabaseRest(args) {
21384
+ return this.request(
21385
+ "POST",
21386
+ `/supabase/grants/${encodeURIComponent(args.grant_id)}/rest`,
21387
+ {
21388
+ query: this.agentId ? { agent_id: this.agentId } : void 0,
21389
+ body: { method: args.method, path: args.path, ...args.body !== void 0 ? { body: args.body } : {} }
21390
+ }
21391
+ );
21392
+ }
21367
21393
  };
21368
21394
 
21369
21395
  // src/inventory.ts
@@ -21590,6 +21616,19 @@ var supabaseCheckApprovalChannelSchema = external_exports.object({
21590
21616
  project_ref: supabaseProjectRefSchema
21591
21617
  });
21592
21618
  var supabaseListProjectsSchema = external_exports.object({});
21619
+ var supabaseQuerySchema = external_exports.object({
21620
+ grant_id: external_exports.string().uuid("grant_id must be a UUID"),
21621
+ sql: external_exports.string().min(1, "sql is required").describe("Read-only SQL to run server-side under your granted scope.")
21622
+ });
21623
+ var supabaseDescribeSchema = external_exports.object({
21624
+ grant_id: external_exports.string().uuid("grant_id must be a UUID")
21625
+ });
21626
+ var supabaseRestSchema = external_exports.object({
21627
+ grant_id: external_exports.string().uuid("grant_id must be a UUID"),
21628
+ method: external_exports.enum(["GET", "HEAD", "POST", "PATCH", "PUT", "DELETE"]).describe("HTTP method. Writes require a non-read-only grant."),
21629
+ path: external_exports.string().min(1, "path is required").describe('PostgREST-relative path, e.g. "orders?select=*&limit=10". Do NOT include /rest/v1/.'),
21630
+ body: external_exports.unknown().optional().describe("JSON body for POST/PATCH/PUT.")
21631
+ });
21593
21632
  var supabaseDescribeScopeShape = supabaseDescribeScopeSchema.shape;
21594
21633
  var supabasePreviewRequestShape = supabasePreviewRequestSchema.shape;
21595
21634
  var supabaseRequestAccessShape = supabaseRequestAccessSchema.shape;
@@ -21598,11 +21637,14 @@ var supabaseReleaseAccessShape = supabaseReleaseAccessSchema.shape;
21598
21637
  var supabaseGetCredentialsShape = supabaseGetCredentialsSchema.shape;
21599
21638
  var supabaseCheckApprovalChannelShape = supabaseCheckApprovalChannelSchema.shape;
21600
21639
  var supabaseListProjectsShape = supabaseListProjectsSchema.shape;
21640
+ var supabaseQueryShape = supabaseQuerySchema.shape;
21641
+ var supabaseDescribeShape = supabaseDescribeSchema.shape;
21642
+ var supabaseRestShape = supabaseRestSchema.shape;
21601
21643
 
21602
21644
  // package.json
21603
21645
  var package_default = {
21604
21646
  name: "@integrity-labs/cloud-broker",
21605
- version: "0.7.9",
21647
+ version: "0.7.11",
21606
21648
  description: "Cloud Access Broker \u2014 MCP server that mints scoped, TTL-bounded cloud credentials per agent task. Ships AWS support (aws_request_access, aws_poll_grant, aws_release_access, aws_describe_scope, aws_preview_request, aws_get_credentials \u2014 STS AssumeRole under the hood); GCP, Azure, and Cloudflare land alongside in the same package as the broker grows.",
21607
21649
  type: "module",
21608
21650
  bin: {
@@ -22080,6 +22122,45 @@ server.tool(
22080
22122
  }
22081
22123
  }
22082
22124
  );
22125
+ server.tool(
22126
+ "supabase_describe",
22127
+ "Inspect what an ACTIVE Supabase grant can actually do, BEFORE you run a query - so you never probe blindly. Takes a grant_id (from supabase_request_access). Returns { grant_id, status, project_ref, role, allowed_schemas, allowed_tables, read_only, expires_at, sql_query: { available, read_only_enforced, note } }. `sql_query.available` tells you whether server-side SQL is enabled for this project (an operator must have enrolled a scoped database credential); if false, supabase_query will 409 and you should tell the user the project is not set up for SQL access. Call this once after a grant goes active to learn your scope, then use supabase_query." + NO_DIRECT_SUPABASE_HTTP_BLOCK,
22128
+ supabaseDescribeShape,
22129
+ async (args) => {
22130
+ try {
22131
+ const result = await broker.supabaseDescribe(args);
22132
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
22133
+ } catch (err) {
22134
+ return { content: [{ type: "text", text: formatBrokerError(err) }], isError: true };
22135
+ }
22136
+ }
22137
+ );
22138
+ server.tool(
22139
+ "supabase_query",
22140
+ "Run READ-ONLY SQL against a Supabase project for an ACTIVE grant. THIS is how you query Supabase - you do NOT get or hold a database credential, and the supabase_get_credentials JWT cannot run SQL. The broker executes your SQL server-side under the grant's scoped database role, inside a READ ONLY transaction with a statement timeout, and returns rows. Args: { grant_id, sql }. Returns on success { grant_id, ok: true, rows, row_count, truncated } (truncated=true means the row cap was hit - add LIMIT/aggregate). On failure returns { ok: false, error_code, error } where error_code is one of READ_ONLY (you attempted a write - this capability is read-only), SCOPE_DENIED (your grant's role can't access that object - try supabase_describe to see your scope), OBJECT_NOT_FOUND (no such relation/schema, or not visible to your grant), TIMEOUT (query too slow), SYNTAX_ERROR, UNREACHABLE, SQL_NOT_CONFIGURED (no scoped DB credential enrolled - tell the user to ask their operator to configure it), or a grant-state code GRANT_NOT_ACTIVE / GRANT_EXPIRED / GRANT_RELEASED (re-request access). Writes are always rejected. Call supabase_describe first if unsure what you can read. All of these come back in the { ok:false, error_code } envelope on a normal response - branch on error_code, do not treat them as tool failures." + NO_DIRECT_SUPABASE_HTTP_BLOCK,
22141
+ supabaseQueryShape,
22142
+ async (args) => {
22143
+ try {
22144
+ const result = await broker.supabaseQuery(args);
22145
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
22146
+ } catch (err) {
22147
+ return { content: [{ type: "text", text: formatBrokerError(err) }], isError: true };
22148
+ }
22149
+ }
22150
+ );
22151
+ server.tool(
22152
+ "supabase_rest",
22153
+ 'Call a Supabase project\'s REST (PostgREST) API for an ACTIVE grant - the primary way to read AND write your app data. You do NOT hold a key; the broker injects the project api_key and runs the call server-side under your grant\'s scope. Args: { grant_id, method (GET/HEAD/POST/PATCH/PUT/DELETE), path, body? }. `path` is PostgREST-relative - e.g. "orders?select=*&limit=10", "orders?id=eq.7" - do NOT include /rest/v1/ or the host. Filtering/ordering/pagination use PostgREST query syntax. For writes, pass the row(s) as `body` (POST=insert, PATCH=update with a filter in path, DELETE=delete with a filter in path). Returns on success { grant_id, ok: true, status, body } where body is the PostgREST JSON (rows for reads, the affected rows for writes). On a denial returns { ok: false, error_code, error }: READ_ONLY (your grant is read-only - writes rejected), SCOPE_DENIED (table not in your grant\'s allowed tables, or rpc/ blocked), BAD_REQUEST (bad method/path), REST_NOT_CONFIGURED (no api_key enrolled - tell the user to ask their operator), GRANT_NOT_ACTIVE / GRANT_EXPIRED / GRANT_RELEASED, or EXECUTION_ERROR. A 4xx from PostgREST itself comes back as { ok:false, status, body } with the upstream error in body. Call supabase_describe first to see your allowed tables and whether REST is available. rpc/ calls are not permitted. Use supabase_query for raw SQL / system tables instead.' + NO_DIRECT_SUPABASE_HTTP_BLOCK,
22154
+ supabaseRestShape,
22155
+ async (args) => {
22156
+ try {
22157
+ const result = await broker.supabaseRest(args);
22158
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
22159
+ } catch (err) {
22160
+ return { content: [{ type: "text", text: formatBrokerError(err) }], isError: true };
22161
+ }
22162
+ }
22163
+ );
22083
22164
  var transport = new StdioServerTransport();
22084
22165
  await server.connect(transport);
22085
22166
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/cloud-broker",
3
- "version": "0.7.9",
3
+ "version": "0.7.11",
4
4
  "description": "Cloud Access Broker — MCP server that mints scoped, TTL-bounded cloud credentials per agent task. Ships AWS support (aws_request_access, aws_poll_grant, aws_release_access, aws_describe_scope, aws_preview_request, aws_get_credentials — STS AssumeRole under the hood); GCP, Azure, and Cloudflare land alongside in the same package as the broker grows.",
5
5
  "type": "module",
6
6
  "bin": {