Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/tools/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
listOrganizationsInputSchema,
listSharedProjectsInputSchema,
resetFromParentInputSchema,
compareDatabaseSchemaInputSchema,
} from './toolsSchema.js';

export const NEON_TOOLS = [
Expand Down Expand Up @@ -608,4 +609,66 @@ export const NEON_TOOLS = [
description: 'Lists compute endpoints for a project or specific branch',
inputSchema: listBranchComputesInputSchema,
},
{
name: 'compare_database_schema' as const,
description: `
<use_case>
Use this tool to compare the schema of a database between two branches.
The output of the tool is a JSON object with one field: \`diff\`.
At this field you will find a difference between two schemas.

You MUST BE READY to generate a zero-downtime migration from the diff and apply it to the parent branch.
</use_case>

<important_notes>
To generate schema diff, you MUST SPECIFY the \`database_name\`.
If it's not specified, try to use the default database name: \`${NEON_DEFAULT_DATABASE_NAME}\`.

You MUST TAKE INTO ACCOUNT the Postgres version. The Postgres version is the same for both branches.
You MUST ASK user consent before running each generated SQL query.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to check how this instruction will behave with Cursor "Auth-Run" or Claude's "Auto-Approve" mode. These modes do not need user's approval every command/tool to execute.

This tool itself is safe to execute, but if LLM runs the migration following instruction, if can be destructive.

You SHOULD USE \`run_sql\` tool to run each generated SQL query.
Generated queries change the schema of the parent branch and MIGHT BE dangerous to execute.
</important_notes>

<next_steps>
After executing this tool, you MUST follow these steps:
1. Review the schema diff and suggest to generate a zero-downtime migration.
2. Follow these instructions to respond to the client:

<response_instructions>
<instructions>
Provide a brief information about the changes:
* Tables
* Views
* Indexes
* Ownership
* Constraints
* Triggers
* Policies
* Extensions
* Schemas
* Sequences
* Tablespaces
* Users
* Roles
* Privileges
</instructions>
</response_instructions>
</next_steps>

This tool:
1. Generates a diff between two branches.
2. Generates a SQL migration from the diff.
3. Suggest to generate zero-downtime migration.

Workflow:
1. User asks you to generate a diff between two branches.
2. You suggest to generate a SQL migration from the diff.
3. You ensure that the generated migration is a zero-downtime migration,
otherwise you should warn the user about it.
4. You ensure that your suggested migration is also matching the Postgres version.
5. You use \`run_sql\` tool to run each generated SQL query and ask the user consent before running it.
`,
inputSchema: compareDatabaseSchemaInputSchema,
},
];
23 changes: 23 additions & 0 deletions src/tools/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EndpointType,
ListProjectsParams,
ListSharedProjectsParams,
GetProjectBranchSchemaComparisonParams,
Organization,
ProjectCreateRequest,
} from '@neondatabase/api-client';
Expand Down Expand Up @@ -1212,6 +1213,14 @@ async function handleListSharedProjects(
return response.data.projects;
}

async function handleCompareDatabaseSchema(
params: GetProjectBranchSchemaComparisonParams,
neonClient: Api<unknown>,
) {
const response = await neonClient.getProjectBranchSchemaComparison(params);
return response.data;
}

export const NEON_HANDLERS = {
list_projects: async ({ params }, neonClient, extra) => {
const organization = await getOrgByOrgIdOrDefault(
Expand Down Expand Up @@ -1774,4 +1783,18 @@ export const NEON_HANDLERS = {
],
};
},

compare_database_schema: async ({ params }, neonClient) => {
const result = await handleCompareDatabaseSchema(
{
projectId: params.projectId,
branchId: params.branchId,
db_name: params.databaseName,
},
neonClient
);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
};
},
} satisfies ToolHandlers;
6 changes: 6 additions & 0 deletions src/tools/toolsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,9 @@ export const resetFromParentInputSchema = z.object({
'Optional name to preserve the current state under a new branch before resetting',
),
});

export const compareDatabaseSchemaInputSchema = z.object({
projectId: z.string().describe('The ID of the project'),
branchId: z.string().describe('The ID of the branch'),
databaseName: z.string().describe(DATABASE_NAME_DESCRIPTION),
});
Loading