Skip to content

Commit adac4a1

Browse files
authored
fix: make list_tables more terse (#129)
* Set Biome as default formatter for TypeScript, JSON * Reshape list_tables output to reduce token bloat * Cleanup * Update tests
1 parent e305905 commit adac4a1

File tree

3 files changed

+117
-38
lines changed

3 files changed

+117
-38
lines changed

.vscode/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"[typescript]": {
3+
"editor.defaultFormatter": "biomejs.biome"
4+
},
5+
"[json]": {
6+
"editor.defaultFormatter": "biomejs.biome"
7+
}
8+
}

packages/mcp-server-supabase/src/server.test.ts

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -808,48 +808,20 @@ describe('tools', () => {
808808

809809
expect(listTablesResult).toEqual([
810810
{
811-
bytes: 8192,
811+
schema: 'public',
812+
name: 'test',
813+
rls_enabled: false,
814+
rows: 0,
812815
columns: [
813816
{
814-
check: null,
815-
comment: null,
817+
name: 'id',
816818
data_type: 'integer',
817-
default_value: null,
818-
enums: [],
819819
format: 'int4',
820-
id: expect.stringMatching(/^\d+\.\d+$/),
820+
options: ['identity', 'updatable'],
821821
identity_generation: 'ALWAYS',
822-
is_generated: false,
823-
is_identity: true,
824-
is_nullable: false,
825-
is_unique: false,
826-
is_updatable: true,
827-
name: 'id',
828-
ordinal_position: 1,
829-
schema: 'public',
830-
table: 'test',
831-
table_id: expect.any(Number),
832-
},
833-
],
834-
comment: null,
835-
dead_rows_estimate: 0,
836-
id: expect.any(Number),
837-
live_rows_estimate: 0,
838-
name: 'test',
839-
primary_keys: [
840-
{
841-
name: 'id',
842-
schema: 'public',
843-
table_id: expect.any(Number),
844-
table_name: 'test',
845822
},
846823
],
847-
relationships: [],
848-
replica_identity: 'DEFAULT',
849-
rls_enabled: false,
850-
rls_forced: false,
851-
schema: 'public',
852-
size: '8192 bytes',
824+
primary_keys: ['id'],
853825
},
854826
]);
855827
});
@@ -2390,8 +2362,7 @@ describe('project scoped tools', () => {
23902362
columns: [
23912363
expect.objectContaining({
23922364
name: 'id',
2393-
is_identity: true,
2394-
is_generated: false,
2365+
options: expect.arrayContaining(['identity']),
23952366
}),
23962367
],
23972368
}),

packages/mcp-server-supabase/src/tools/database-operation-tools.ts

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,107 @@ export function getDatabaseOperationTools({
3838
query,
3939
read_only: readOnly,
4040
});
41-
const tables = data.map((table) => postgresTableSchema.parse(table));
41+
const tables = data
42+
.map((table) => postgresTableSchema.parse(table))
43+
.map(
44+
// Reshape to reduce token bloat
45+
({
46+
// Discarded fields
47+
id,
48+
bytes,
49+
size,
50+
rls_forced,
51+
live_rows_estimate,
52+
dead_rows_estimate,
53+
replica_identity,
54+
55+
// Modified fields
56+
columns,
57+
primary_keys,
58+
relationships,
59+
comment,
60+
61+
// Passthrough rest
62+
...table
63+
}) => {
64+
const foreign_key_constraints = relationships?.map(
65+
({
66+
constraint_name,
67+
source_schema,
68+
source_table_name,
69+
source_column_name,
70+
target_table_schema,
71+
target_table_name,
72+
target_column_name,
73+
}) => ({
74+
name: constraint_name,
75+
source: `${source_schema}.${source_table_name}.${source_column_name}`,
76+
target: `${target_table_schema}.${target_table_name}.${target_column_name}`,
77+
})
78+
);
79+
80+
return {
81+
...table,
82+
rows: live_rows_estimate,
83+
columns: columns?.map(
84+
({
85+
// Discarded fields
86+
id,
87+
table,
88+
table_id,
89+
schema,
90+
ordinal_position,
91+
92+
// Modified fields
93+
default_value,
94+
is_identity,
95+
identity_generation,
96+
is_generated,
97+
is_nullable,
98+
is_updatable,
99+
is_unique,
100+
check,
101+
comment,
102+
enums,
103+
104+
// Passthrough rest
105+
...column
106+
}) => {
107+
const options: string[] = [];
108+
if (is_identity) options.push('identity');
109+
if (is_generated) options.push('generated');
110+
if (is_nullable) options.push('nullable');
111+
if (is_updatable) options.push('updatable');
112+
if (is_unique) options.push('unique');
113+
114+
return {
115+
...column,
116+
options,
117+
118+
// Omit fields when empty
119+
...(default_value !== null && { default_value }),
120+
...(identity_generation !== null && {
121+
identity_generation,
122+
}),
123+
...(enums.length > 0 && { enums }),
124+
...(check !== null && { check }),
125+
...(comment !== null && { comment }),
126+
};
127+
}
128+
),
129+
primary_keys: primary_keys?.map(
130+
({ table_id, schema, table_name, ...primary_key }) =>
131+
primary_key.name
132+
),
133+
134+
// Omit fields when empty
135+
...(comment !== null && { comment }),
136+
...(foreign_key_constraints.length > 0 && {
137+
foreign_key_constraints,
138+
}),
139+
};
140+
}
141+
);
42142
return tables;
43143
},
44144
}),

0 commit comments

Comments
 (0)