@neverinfamous/postgres-mcp 1.0.1
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/LICENSE +21 -0
- package/README.md +515 -0
- package/dist/__tests__/mocks/adapter.d.ts +80 -0
- package/dist/__tests__/mocks/adapter.d.ts.map +1 -0
- package/dist/__tests__/mocks/adapter.js +225 -0
- package/dist/__tests__/mocks/adapter.js.map +1 -0
- package/dist/__tests__/mocks/index.d.ts +11 -0
- package/dist/__tests__/mocks/index.d.ts.map +1 -0
- package/dist/__tests__/mocks/index.js +11 -0
- package/dist/__tests__/mocks/index.js.map +1 -0
- package/dist/__tests__/mocks/pool.d.ts +43 -0
- package/dist/__tests__/mocks/pool.d.ts.map +1 -0
- package/dist/__tests__/mocks/pool.js +71 -0
- package/dist/__tests__/mocks/pool.js.map +1 -0
- package/dist/adapters/DatabaseAdapter.d.ts +139 -0
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -0
- package/dist/adapters/DatabaseAdapter.js +250 -0
- package/dist/adapters/DatabaseAdapter.js.map +1 -0
- package/dist/adapters/postgresql/PostgresAdapter.d.ts +119 -0
- package/dist/adapters/postgresql/PostgresAdapter.d.ts.map +1 -0
- package/dist/adapters/postgresql/PostgresAdapter.js +902 -0
- package/dist/adapters/postgresql/PostgresAdapter.js.map +1 -0
- package/dist/adapters/postgresql/index.d.ts +5 -0
- package/dist/adapters/postgresql/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/index.js +5 -0
- package/dist/adapters/postgresql/index.js.map +1 -0
- package/dist/adapters/postgresql/prompts/backup.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/backup.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/backup.js +132 -0
- package/dist/adapters/postgresql/prompts/backup.js.map +1 -0
- package/dist/adapters/postgresql/prompts/citext.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/citext.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/citext.js +227 -0
- package/dist/adapters/postgresql/prompts/citext.js.map +1 -0
- package/dist/adapters/postgresql/prompts/extensionSetup.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/extensionSetup.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/extensionSetup.js +282 -0
- package/dist/adapters/postgresql/prompts/extensionSetup.js.map +1 -0
- package/dist/adapters/postgresql/prompts/health.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/health.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/health.js +118 -0
- package/dist/adapters/postgresql/prompts/health.js.map +1 -0
- package/dist/adapters/postgresql/prompts/index.d.ts +13 -0
- package/dist/adapters/postgresql/prompts/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/index.js +308 -0
- package/dist/adapters/postgresql/prompts/index.js.map +1 -0
- package/dist/adapters/postgresql/prompts/indexTuning.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/indexTuning.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/indexTuning.js +130 -0
- package/dist/adapters/postgresql/prompts/indexTuning.js.map +1 -0
- package/dist/adapters/postgresql/prompts/kcache.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/kcache.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/kcache.js +227 -0
- package/dist/adapters/postgresql/prompts/kcache.js.map +1 -0
- package/dist/adapters/postgresql/prompts/ltree.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/ltree.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/ltree.js +286 -0
- package/dist/adapters/postgresql/prompts/ltree.js.map +1 -0
- package/dist/adapters/postgresql/prompts/partman.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/partman.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/partman.js +211 -0
- package/dist/adapters/postgresql/prompts/partman.js.map +1 -0
- package/dist/adapters/postgresql/prompts/pgcron.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/pgcron.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/pgcron.js +233 -0
- package/dist/adapters/postgresql/prompts/pgcron.js.map +1 -0
- package/dist/adapters/postgresql/prompts/pgcrypto.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/pgcrypto.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/pgcrypto.js +299 -0
- package/dist/adapters/postgresql/prompts/pgcrypto.js.map +1 -0
- package/dist/adapters/postgresql/prompts/pgvector.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/pgvector.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/pgvector.js +148 -0
- package/dist/adapters/postgresql/prompts/pgvector.js.map +1 -0
- package/dist/adapters/postgresql/prompts/postgis.d.ts +8 -0
- package/dist/adapters/postgresql/prompts/postgis.d.ts.map +1 -0
- package/dist/adapters/postgresql/prompts/postgis.js +200 -0
- package/dist/adapters/postgresql/prompts/postgis.js.map +1 -0
- package/dist/adapters/postgresql/resources/activity.d.ts +9 -0
- package/dist/adapters/postgresql/resources/activity.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/activity.js +118 -0
- package/dist/adapters/postgresql/resources/activity.js.map +1 -0
- package/dist/adapters/postgresql/resources/capabilities.d.ts +9 -0
- package/dist/adapters/postgresql/resources/capabilities.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/capabilities.js +182 -0
- package/dist/adapters/postgresql/resources/capabilities.js.map +1 -0
- package/dist/adapters/postgresql/resources/cron.d.ts +9 -0
- package/dist/adapters/postgresql/resources/cron.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/cron.js +156 -0
- package/dist/adapters/postgresql/resources/cron.js.map +1 -0
- package/dist/adapters/postgresql/resources/crypto.d.ts +9 -0
- package/dist/adapters/postgresql/resources/crypto.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/crypto.js +191 -0
- package/dist/adapters/postgresql/resources/crypto.js.map +1 -0
- package/dist/adapters/postgresql/resources/extensions.d.ts +9 -0
- package/dist/adapters/postgresql/resources/extensions.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/extensions.js +85 -0
- package/dist/adapters/postgresql/resources/extensions.js.map +1 -0
- package/dist/adapters/postgresql/resources/health.d.ts +9 -0
- package/dist/adapters/postgresql/resources/health.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/health.js +185 -0
- package/dist/adapters/postgresql/resources/health.js.map +1 -0
- package/dist/adapters/postgresql/resources/index.d.ts +40 -0
- package/dist/adapters/postgresql/resources/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/index.js +87 -0
- package/dist/adapters/postgresql/resources/index.js.map +1 -0
- package/dist/adapters/postgresql/resources/indexes.d.ts +9 -0
- package/dist/adapters/postgresql/resources/indexes.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/indexes.js +130 -0
- package/dist/adapters/postgresql/resources/indexes.js.map +1 -0
- package/dist/adapters/postgresql/resources/kcache.d.ts +9 -0
- package/dist/adapters/postgresql/resources/kcache.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/kcache.js +219 -0
- package/dist/adapters/postgresql/resources/kcache.js.map +1 -0
- package/dist/adapters/postgresql/resources/locks.d.ts +9 -0
- package/dist/adapters/postgresql/resources/locks.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/locks.js +89 -0
- package/dist/adapters/postgresql/resources/locks.js.map +1 -0
- package/dist/adapters/postgresql/resources/partman.d.ts +9 -0
- package/dist/adapters/postgresql/resources/partman.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/partman.js +149 -0
- package/dist/adapters/postgresql/resources/partman.js.map +1 -0
- package/dist/adapters/postgresql/resources/performance.d.ts +9 -0
- package/dist/adapters/postgresql/resources/performance.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/performance.js +170 -0
- package/dist/adapters/postgresql/resources/performance.js.map +1 -0
- package/dist/adapters/postgresql/resources/pool.d.ts +9 -0
- package/dist/adapters/postgresql/resources/pool.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/pool.js +93 -0
- package/dist/adapters/postgresql/resources/pool.js.map +1 -0
- package/dist/adapters/postgresql/resources/postgis.d.ts +9 -0
- package/dist/adapters/postgresql/resources/postgis.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/postgis.js +232 -0
- package/dist/adapters/postgresql/resources/postgis.js.map +1 -0
- package/dist/adapters/postgresql/resources/replication.d.ts +9 -0
- package/dist/adapters/postgresql/resources/replication.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/replication.js +126 -0
- package/dist/adapters/postgresql/resources/replication.js.map +1 -0
- package/dist/adapters/postgresql/resources/schema.d.ts +10 -0
- package/dist/adapters/postgresql/resources/schema.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/schema.js +80 -0
- package/dist/adapters/postgresql/resources/schema.js.map +1 -0
- package/dist/adapters/postgresql/resources/settings.d.ts +9 -0
- package/dist/adapters/postgresql/resources/settings.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/settings.js +184 -0
- package/dist/adapters/postgresql/resources/settings.js.map +1 -0
- package/dist/adapters/postgresql/resources/stats.d.ts +10 -0
- package/dist/adapters/postgresql/resources/stats.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/stats.js +124 -0
- package/dist/adapters/postgresql/resources/stats.js.map +1 -0
- package/dist/adapters/postgresql/resources/tables.d.ts +9 -0
- package/dist/adapters/postgresql/resources/tables.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/tables.js +20 -0
- package/dist/adapters/postgresql/resources/tables.js.map +1 -0
- package/dist/adapters/postgresql/resources/vacuum.d.ts +9 -0
- package/dist/adapters/postgresql/resources/vacuum.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/vacuum.js +122 -0
- package/dist/adapters/postgresql/resources/vacuum.js.map +1 -0
- package/dist/adapters/postgresql/resources/vector.d.ts +9 -0
- package/dist/adapters/postgresql/resources/vector.d.ts.map +1 -0
- package/dist/adapters/postgresql/resources/vector.js +185 -0
- package/dist/adapters/postgresql/resources/vector.js.map +1 -0
- package/dist/adapters/postgresql/schemas/admin.d.ts +74 -0
- package/dist/adapters/postgresql/schemas/admin.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/admin.js +180 -0
- package/dist/adapters/postgresql/schemas/admin.js.map +1 -0
- package/dist/adapters/postgresql/schemas/backup.d.ts +68 -0
- package/dist/adapters/postgresql/schemas/backup.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/backup.js +114 -0
- package/dist/adapters/postgresql/schemas/backup.js.map +1 -0
- package/dist/adapters/postgresql/schemas/core.d.ts +443 -0
- package/dist/adapters/postgresql/schemas/core.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/core.js +628 -0
- package/dist/adapters/postgresql/schemas/core.js.map +1 -0
- package/dist/adapters/postgresql/schemas/cron.d.ts +131 -0
- package/dist/adapters/postgresql/schemas/cron.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/cron.js +218 -0
- package/dist/adapters/postgresql/schemas/cron.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions.d.ts +403 -0
- package/dist/adapters/postgresql/schemas/extensions.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions.js +600 -0
- package/dist/adapters/postgresql/schemas/extensions.js.map +1 -0
- package/dist/adapters/postgresql/schemas/index.d.ts +21 -0
- package/dist/adapters/postgresql/schemas/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/index.js +72 -0
- package/dist/adapters/postgresql/schemas/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb.d.ts +94 -0
- package/dist/adapters/postgresql/schemas/jsonb.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb.js +198 -0
- package/dist/adapters/postgresql/schemas/jsonb.js.map +1 -0
- package/dist/adapters/postgresql/schemas/monitoring.d.ts +28 -0
- package/dist/adapters/postgresql/schemas/monitoring.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/monitoring.js +45 -0
- package/dist/adapters/postgresql/schemas/monitoring.js.map +1 -0
- package/dist/adapters/postgresql/schemas/partitioning.d.ts +152 -0
- package/dist/adapters/postgresql/schemas/partitioning.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/partitioning.js +399 -0
- package/dist/adapters/postgresql/schemas/partitioning.js.map +1 -0
- package/dist/adapters/postgresql/schemas/partman.d.ts +94 -0
- package/dist/adapters/postgresql/schemas/partman.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/partman.js +264 -0
- package/dist/adapters/postgresql/schemas/partman.js.map +1 -0
- package/dist/adapters/postgresql/schemas/performance.d.ts +52 -0
- package/dist/adapters/postgresql/schemas/performance.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/performance.js +57 -0
- package/dist/adapters/postgresql/schemas/performance.js.map +1 -0
- package/dist/adapters/postgresql/schemas/postgis.d.ts +693 -0
- package/dist/adapters/postgresql/schemas/postgis.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/postgis.js +662 -0
- package/dist/adapters/postgresql/schemas/postgis.js.map +1 -0
- package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts +171 -0
- package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/schema-mgmt.js +235 -0
- package/dist/adapters/postgresql/schemas/schema-mgmt.js.map +1 -0
- package/dist/adapters/postgresql/schemas/stats.d.ts +229 -0
- package/dist/adapters/postgresql/schemas/stats.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/stats.js +587 -0
- package/dist/adapters/postgresql/schemas/stats.js.map +1 -0
- package/dist/adapters/postgresql/schemas/text-search.d.ts +83 -0
- package/dist/adapters/postgresql/schemas/text-search.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/text-search.js +132 -0
- package/dist/adapters/postgresql/schemas/text-search.js.map +1 -0
- package/dist/adapters/postgresql/schemas/vector.d.ts +143 -0
- package/dist/adapters/postgresql/schemas/vector.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/vector.js +123 -0
- package/dist/adapters/postgresql/schemas/vector.js.map +1 -0
- package/dist/adapters/postgresql/tools/admin.d.ts +13 -0
- package/dist/adapters/postgresql/tools/admin.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/admin.js +417 -0
- package/dist/adapters/postgresql/tools/admin.js.map +1 -0
- package/dist/adapters/postgresql/tools/backup/dump.d.ts +12 -0
- package/dist/adapters/postgresql/tools/backup/dump.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/backup/dump.js +546 -0
- package/dist/adapters/postgresql/tools/backup/dump.js.map +1 -0
- package/dist/adapters/postgresql/tools/backup/index.d.ts +16 -0
- package/dist/adapters/postgresql/tools/backup/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/backup/index.js +29 -0
- package/dist/adapters/postgresql/tools/backup/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/backup/planning.d.ts +22 -0
- package/dist/adapters/postgresql/tools/backup/planning.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/backup/planning.js +411 -0
- package/dist/adapters/postgresql/tools/backup/planning.js.map +1 -0
- package/dist/adapters/postgresql/tools/citext.d.ts +18 -0
- package/dist/adapters/postgresql/tools/citext.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/citext.js +568 -0
- package/dist/adapters/postgresql/tools/citext.js.map +1 -0
- package/dist/adapters/postgresql/tools/codemode/index.d.ts +27 -0
- package/dist/adapters/postgresql/tools/codemode/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/codemode/index.js +171 -0
- package/dist/adapters/postgresql/tools/codemode/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/convenience.d.ts +192 -0
- package/dist/adapters/postgresql/tools/core/convenience.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/convenience.js +617 -0
- package/dist/adapters/postgresql/tools/core/convenience.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/health.d.ts +20 -0
- package/dist/adapters/postgresql/tools/core/health.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/health.js +360 -0
- package/dist/adapters/postgresql/tools/core/health.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/index.d.ts +15 -0
- package/dist/adapters/postgresql/tools/core/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/index.js +40 -0
- package/dist/adapters/postgresql/tools/core/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/indexes.d.ts +30 -0
- package/dist/adapters/postgresql/tools/core/indexes.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/indexes.js +232 -0
- package/dist/adapters/postgresql/tools/core/indexes.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/objects.d.ts +20 -0
- package/dist/adapters/postgresql/tools/core/objects.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/objects.js +361 -0
- package/dist/adapters/postgresql/tools/core/objects.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/query.d.ts +16 -0
- package/dist/adapters/postgresql/tools/core/query.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/query.js +87 -0
- package/dist/adapters/postgresql/tools/core/query.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/schemas.d.ts +135 -0
- package/dist/adapters/postgresql/tools/core/schemas.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/schemas.js +221 -0
- package/dist/adapters/postgresql/tools/core/schemas.js.map +1 -0
- package/dist/adapters/postgresql/tools/core/tables.d.ts +24 -0
- package/dist/adapters/postgresql/tools/core/tables.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/tables.js +219 -0
- package/dist/adapters/postgresql/tools/core/tables.js.map +1 -0
- package/dist/adapters/postgresql/tools/cron.d.ts +16 -0
- package/dist/adapters/postgresql/tools/cron.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/cron.js +440 -0
- package/dist/adapters/postgresql/tools/cron.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/advanced.d.ts +33 -0
- package/dist/adapters/postgresql/tools/jsonb/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/advanced.js +681 -0
- package/dist/adapters/postgresql/tools/jsonb/advanced.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/basic.d.ts +20 -0
- package/dist/adapters/postgresql/tools/jsonb/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/basic.js +654 -0
- package/dist/adapters/postgresql/tools/jsonb/basic.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/index.d.ts +16 -0
- package/dist/adapters/postgresql/tools/jsonb/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/index.js +39 -0
- package/dist/adapters/postgresql/tools/jsonb/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/kcache.d.ts +20 -0
- package/dist/adapters/postgresql/tools/kcache.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/kcache.js +574 -0
- package/dist/adapters/postgresql/tools/kcache.js.map +1 -0
- package/dist/adapters/postgresql/tools/ltree.d.ts +8 -0
- package/dist/adapters/postgresql/tools/ltree.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/ltree.js +390 -0
- package/dist/adapters/postgresql/tools/ltree.js.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring.d.ts +13 -0
- package/dist/adapters/postgresql/tools/monitoring.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring.js +753 -0
- package/dist/adapters/postgresql/tools/monitoring.js.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning.d.ts +13 -0
- package/dist/adapters/postgresql/tools/partitioning.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning.js +500 -0
- package/dist/adapters/postgresql/tools/partitioning.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/index.d.ts +19 -0
- package/dist/adapters/postgresql/tools/partman/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partman/index.js +33 -0
- package/dist/adapters/postgresql/tools/partman/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/management.d.ts +28 -0
- package/dist/adapters/postgresql/tools/partman/management.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partman/management.js +563 -0
- package/dist/adapters/postgresql/tools/partman/management.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/operations.d.ts +28 -0
- package/dist/adapters/postgresql/tools/partman/operations.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partman/operations.js +632 -0
- package/dist/adapters/postgresql/tools/partman/operations.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/analysis.d.ts +9 -0
- package/dist/adapters/postgresql/tools/performance/analysis.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/analysis.js +383 -0
- package/dist/adapters/postgresql/tools/performance/analysis.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/explain.d.ts +13 -0
- package/dist/adapters/postgresql/tools/performance/explain.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/explain.js +71 -0
- package/dist/adapters/postgresql/tools/performance/explain.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/index.d.ts +13 -0
- package/dist/adapters/postgresql/tools/performance/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/index.js +40 -0
- package/dist/adapters/postgresql/tools/performance/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/monitoring.d.ts +9 -0
- package/dist/adapters/postgresql/tools/performance/monitoring.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/monitoring.js +122 -0
- package/dist/adapters/postgresql/tools/performance/monitoring.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/optimization.d.ts +9 -0
- package/dist/adapters/postgresql/tools/performance/optimization.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/optimization.js +315 -0
- package/dist/adapters/postgresql/tools/performance/optimization.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/stats.d.ts +14 -0
- package/dist/adapters/postgresql/tools/performance/stats.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/stats.js +559 -0
- package/dist/adapters/postgresql/tools/performance/stats.js.map +1 -0
- package/dist/adapters/postgresql/tools/pgcrypto.d.ts +8 -0
- package/dist/adapters/postgresql/tools/pgcrypto.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/pgcrypto.js +239 -0
- package/dist/adapters/postgresql/tools/pgcrypto.js.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/advanced.d.ts +21 -0
- package/dist/adapters/postgresql/tools/postgis/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/advanced.js +383 -0
- package/dist/adapters/postgresql/tools/postgis/advanced.js.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/basic.d.ts +16 -0
- package/dist/adapters/postgresql/tools/postgis/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/basic.js +479 -0
- package/dist/adapters/postgresql/tools/postgis/basic.js.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/index.d.ts +17 -0
- package/dist/adapters/postgresql/tools/postgis/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/index.js +46 -0
- package/dist/adapters/postgresql/tools/postgis/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/standalone.d.ts +21 -0
- package/dist/adapters/postgresql/tools/postgis/standalone.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/postgis/standalone.js +150 -0
- package/dist/adapters/postgresql/tools/postgis/standalone.js.map +1 -0
- package/dist/adapters/postgresql/tools/schema.d.ts +13 -0
- package/dist/adapters/postgresql/tools/schema.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/schema.js +515 -0
- package/dist/adapters/postgresql/tools/schema.js.map +1 -0
- package/dist/adapters/postgresql/tools/stats/advanced.d.ts +24 -0
- package/dist/adapters/postgresql/tools/stats/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/stats/advanced.js +876 -0
- package/dist/adapters/postgresql/tools/stats/advanced.js.map +1 -0
- package/dist/adapters/postgresql/tools/stats/basic.d.ts +24 -0
- package/dist/adapters/postgresql/tools/stats/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/stats/basic.js +501 -0
- package/dist/adapters/postgresql/tools/stats/basic.js.map +1 -0
- package/dist/adapters/postgresql/tools/stats/index.d.ts +17 -0
- package/dist/adapters/postgresql/tools/stats/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/stats/index.js +30 -0
- package/dist/adapters/postgresql/tools/stats/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/text.d.ts +13 -0
- package/dist/adapters/postgresql/tools/text.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/text.js +708 -0
- package/dist/adapters/postgresql/tools/text.js.map +1 -0
- package/dist/adapters/postgresql/tools/transactions.d.ts +13 -0
- package/dist/adapters/postgresql/tools/transactions.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/transactions.js +201 -0
- package/dist/adapters/postgresql/tools/transactions.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/advanced.d.ts +12 -0
- package/dist/adapters/postgresql/tools/vector/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/advanced.js +902 -0
- package/dist/adapters/postgresql/tools/vector/advanced.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/basic.d.ts +25 -0
- package/dist/adapters/postgresql/tools/vector/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/basic.js +1000 -0
- package/dist/adapters/postgresql/tools/vector/basic.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/index.d.ts +13 -0
- package/dist/adapters/postgresql/tools/vector/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/index.js +33 -0
- package/dist/adapters/postgresql/tools/vector/index.js.map +1 -0
- package/dist/auth/AuthorizationServerDiscovery.d.ts +44 -0
- package/dist/auth/AuthorizationServerDiscovery.d.ts.map +1 -0
- package/dist/auth/AuthorizationServerDiscovery.js +117 -0
- package/dist/auth/AuthorizationServerDiscovery.js.map +1 -0
- package/dist/auth/OAuthResourceServer.d.ts +42 -0
- package/dist/auth/OAuthResourceServer.d.ts.map +1 -0
- package/dist/auth/OAuthResourceServer.js +80 -0
- package/dist/auth/OAuthResourceServer.js.map +1 -0
- package/dist/auth/TokenValidator.d.ts +36 -0
- package/dist/auth/TokenValidator.d.ts.map +1 -0
- package/dist/auth/TokenValidator.js +139 -0
- package/dist/auth/TokenValidator.js.map +1 -0
- package/dist/auth/errors.d.ts +63 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +102 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +16 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +61 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +156 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/scopes.d.ts +65 -0
- package/dist/auth/scopes.d.ts.map +1 -0
- package/dist/auth/scopes.js +189 -0
- package/dist/auth/scopes.js.map +1 -0
- package/dist/auth/types.d.ts +208 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +8 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli/args.d.ts +34 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +308 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +341 -0
- package/dist/cli.js.map +1 -0
- package/dist/codemode/api.d.ts +62 -0
- package/dist/codemode/api.d.ts.map +1 -0
- package/dist/codemode/api.js +1505 -0
- package/dist/codemode/api.js.map +1 -0
- package/dist/codemode/index.d.ts +13 -0
- package/dist/codemode/index.d.ts.map +1 -0
- package/dist/codemode/index.js +17 -0
- package/dist/codemode/index.js.map +1 -0
- package/dist/codemode/sandbox-factory.d.ts +72 -0
- package/dist/codemode/sandbox-factory.d.ts.map +1 -0
- package/dist/codemode/sandbox-factory.js +88 -0
- package/dist/codemode/sandbox-factory.js.map +1 -0
- package/dist/codemode/sandbox.d.ts +96 -0
- package/dist/codemode/sandbox.d.ts.map +1 -0
- package/dist/codemode/sandbox.js +345 -0
- package/dist/codemode/sandbox.js.map +1 -0
- package/dist/codemode/security.d.ts +44 -0
- package/dist/codemode/security.d.ts.map +1 -0
- package/dist/codemode/security.js +149 -0
- package/dist/codemode/security.js.map +1 -0
- package/dist/codemode/types.d.ts +137 -0
- package/dist/codemode/types.d.ts.map +1 -0
- package/dist/codemode/types.js +46 -0
- package/dist/codemode/types.js.map +1 -0
- package/dist/codemode/worker-sandbox.d.ts +82 -0
- package/dist/codemode/worker-sandbox.d.ts.map +1 -0
- package/dist/codemode/worker-sandbox.js +244 -0
- package/dist/codemode/worker-sandbox.js.map +1 -0
- package/dist/codemode/worker-script.d.ts +8 -0
- package/dist/codemode/worker-script.d.ts.map +1 -0
- package/dist/codemode/worker-script.js +113 -0
- package/dist/codemode/worker-script.js.map +1 -0
- package/dist/constants/ServerInstructions.d.ts +13 -0
- package/dist/constants/ServerInstructions.d.ts.map +1 -0
- package/dist/constants/ServerInstructions.js +405 -0
- package/dist/constants/ServerInstructions.js.map +1 -0
- package/dist/filtering/ToolConstants.d.ts +43 -0
- package/dist/filtering/ToolConstants.d.ts.map +1 -0
- package/dist/filtering/ToolConstants.js +352 -0
- package/dist/filtering/ToolConstants.js.map +1 -0
- package/dist/filtering/ToolFilter.d.ts +90 -0
- package/dist/filtering/ToolFilter.d.ts.map +1 -0
- package/dist/filtering/ToolFilter.js +315 -0
- package/dist/filtering/ToolFilter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/pool/ConnectionPool.d.ts +70 -0
- package/dist/pool/ConnectionPool.d.ts.map +1 -0
- package/dist/pool/ConnectionPool.js +254 -0
- package/dist/pool/ConnectionPool.js.map +1 -0
- package/dist/server/McpServer.d.ts +50 -0
- package/dist/server/McpServer.d.ts.map +1 -0
- package/dist/server/McpServer.js +108 -0
- package/dist/server/McpServer.js.map +1 -0
- package/dist/transports/http.d.ts +126 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +303 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/index.d.ts +8 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +7 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/types/adapters.d.ts +136 -0
- package/dist/types/adapters.d.ts.map +1 -0
- package/dist/types/adapters.js +7 -0
- package/dist/types/adapters.js.map +1 -0
- package/dist/types/database.d.ts +204 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/database.js +7 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/errors.d.ts +62 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +91 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/filtering.d.ts +39 -0
- package/dist/types/filtering.d.ts.map +1 -0
- package/dist/types/filtering.js +7 -0
- package/dist/types/filtering.js.map +1 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mcp.d.ts +31 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +7 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/oauth.d.ts +65 -0
- package/dist/types/oauth.d.ts.map +1 -0
- package/dist/types/oauth.js +7 -0
- package/dist/types/oauth.js.map +1 -0
- package/dist/types/schema.d.ts +110 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +7 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/utils/annotations.d.ts +42 -0
- package/dist/utils/annotations.d.ts.map +1 -0
- package/dist/utils/annotations.js +75 -0
- package/dist/utils/annotations.js.map +1 -0
- package/dist/utils/icons.d.ts +25 -0
- package/dist/utils/icons.d.ts.map +1 -0
- package/dist/utils/icons.js +212 -0
- package/dist/utils/icons.js.map +1 -0
- package/dist/utils/identifiers.d.ts +111 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +270 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/dist/utils/logger.d.ts +141 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +304 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/promptGenerator.d.ts +20 -0
- package/dist/utils/promptGenerator.d.ts.map +1 -0
- package/dist/utils/promptGenerator.js +81 -0
- package/dist/utils/promptGenerator.js.map +1 -0
- package/dist/utils/resourceAnnotations.d.ts +36 -0
- package/dist/utils/resourceAnnotations.d.ts.map +1 -0
- package/dist/utils/resourceAnnotations.js +57 -0
- package/dist/utils/resourceAnnotations.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL pgvector - Advanced Operations
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { readOnly } from "../../../../utils/annotations.js";
|
|
6
|
+
import { getToolIcons } from "../../../../utils/icons.js";
|
|
7
|
+
import { sanitizeIdentifier, sanitizeTableName, } from "../../../../utils/identifiers.js";
|
|
8
|
+
import { truncateVector } from "./basic.js";
|
|
9
|
+
/**
|
|
10
|
+
* Parse a PostgreSQL vector string to a number array.
|
|
11
|
+
*/
|
|
12
|
+
function parseVector(vecStr) {
|
|
13
|
+
if (typeof vecStr !== "string")
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
const cleaned = vecStr.replace(/[[\]()]/g, "");
|
|
17
|
+
return cleaned.split(",").map(Number);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function createVectorClusterTool(adapter) {
|
|
24
|
+
// Schema with parameter smoothing
|
|
25
|
+
const ClusterSchemaBase = z.object({
|
|
26
|
+
table: z.string().optional().describe("Table name"),
|
|
27
|
+
tableName: z.string().optional().describe("Alias for table"),
|
|
28
|
+
column: z.string().optional().describe("Vector column"),
|
|
29
|
+
col: z.string().optional().describe("Alias for column"),
|
|
30
|
+
k: z.number().optional().describe("Number of clusters"),
|
|
31
|
+
clusters: z
|
|
32
|
+
.number()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Alias for k (number of clusters)"),
|
|
35
|
+
iterations: z.number().optional().describe("Max iterations (default: 10)"),
|
|
36
|
+
sampleSize: z.number().optional().describe("Sample size for large tables"),
|
|
37
|
+
schema: z.string().optional().describe("Database schema (default: public)"),
|
|
38
|
+
});
|
|
39
|
+
const ClusterSchema = ClusterSchemaBase.transform((data) => ({
|
|
40
|
+
table: data.table ?? data.tableName ?? "",
|
|
41
|
+
column: data.column ?? data.col ?? "",
|
|
42
|
+
k: data.k ?? data.clusters,
|
|
43
|
+
iterations: data.iterations,
|
|
44
|
+
sampleSize: data.sampleSize,
|
|
45
|
+
schema: data.schema,
|
|
46
|
+
})).refine((data) => data.k !== undefined, {
|
|
47
|
+
message: "k (or clusters alias) is required",
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
name: "pg_vector_cluster",
|
|
51
|
+
description: "Perform K-means clustering on vectors. Returns cluster centroids only (not row assignments). To assign rows to clusters, compare row vectors to centroids using pg_vector_distance.",
|
|
52
|
+
group: "vector",
|
|
53
|
+
inputSchema: ClusterSchemaBase,
|
|
54
|
+
annotations: readOnly("Vector Cluster"),
|
|
55
|
+
icons: getToolIcons("vector", readOnly("Vector Cluster")),
|
|
56
|
+
handler: async (params, _context) => {
|
|
57
|
+
const parsed = ClusterSchema.parse(params);
|
|
58
|
+
// Refine guarantees k is defined, but add explicit check for TypeScript
|
|
59
|
+
const k = parsed.k;
|
|
60
|
+
if (k === undefined) {
|
|
61
|
+
throw new Error("k (or clusters alias) is required");
|
|
62
|
+
}
|
|
63
|
+
if (k < 1) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: "k must be at least 1 (number of clusters)",
|
|
67
|
+
suggestion: "Provide k >= 1, typically between 2 and 20",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const maxIter = parsed.iterations ?? 10;
|
|
71
|
+
const sample = parsed.sampleSize ?? 10000;
|
|
72
|
+
const tableName = sanitizeTableName(parsed.table, parsed.schema);
|
|
73
|
+
const columnName = sanitizeIdentifier(parsed.column);
|
|
74
|
+
const sampleSql = `
|
|
75
|
+
SELECT ${columnName} as vec
|
|
76
|
+
FROM ${tableName}
|
|
77
|
+
WHERE ${columnName} IS NOT NULL
|
|
78
|
+
ORDER BY RANDOM()
|
|
79
|
+
LIMIT ${String(sample)}
|
|
80
|
+
`;
|
|
81
|
+
const sampleResult = await adapter.executeQuery(sampleSql);
|
|
82
|
+
const vectors = (sampleResult.rows ?? []);
|
|
83
|
+
if (vectors.length < k) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
error: `Cannot create ${String(k)} clusters with only ${String(vectors.length)} data points. Reduce k to at most ${String(vectors.length)} or increase sampleSize.`,
|
|
87
|
+
k: k,
|
|
88
|
+
availableDataPoints: vectors.length,
|
|
89
|
+
sampleSize: sample,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const initialCentroids = vectors.slice(0, k).map((v) => v.vec);
|
|
93
|
+
const clusterSql = `
|
|
94
|
+
WITH sample_vectors AS (
|
|
95
|
+
SELECT ROW_NUMBER() OVER () as id, ${columnName} as vec
|
|
96
|
+
FROM ${tableName}
|
|
97
|
+
WHERE ${columnName} IS NOT NULL
|
|
98
|
+
LIMIT ${String(sample)}
|
|
99
|
+
),
|
|
100
|
+
centroids AS (
|
|
101
|
+
SELECT unnest($1::vector[]) as centroid
|
|
102
|
+
)
|
|
103
|
+
SELECT
|
|
104
|
+
c.centroid,
|
|
105
|
+
COUNT(*) as cluster_size,
|
|
106
|
+
AVG(s.vec) as new_centroid
|
|
107
|
+
FROM sample_vectors s
|
|
108
|
+
CROSS JOIN LATERAL (
|
|
109
|
+
SELECT centroid, ROW_NUMBER() OVER (ORDER BY s.vec <-> centroid) as rn
|
|
110
|
+
FROM centroids
|
|
111
|
+
) c
|
|
112
|
+
WHERE c.rn = 1
|
|
113
|
+
GROUP BY c.centroid
|
|
114
|
+
`;
|
|
115
|
+
let centroids = initialCentroids;
|
|
116
|
+
for (let i = 0; i < maxIter; i++) {
|
|
117
|
+
try {
|
|
118
|
+
const result = await adapter.executeQuery(clusterSql, [centroids]);
|
|
119
|
+
centroids = (result.rows ?? []).map((r) => r["new_centroid"]);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Truncate large centroids for display (like pg_vector_aggregate does)
|
|
126
|
+
const parsedCentroids = centroids.map((c) => {
|
|
127
|
+
const parsed = parseVector(c);
|
|
128
|
+
if (parsed === null) {
|
|
129
|
+
return { vector: c };
|
|
130
|
+
}
|
|
131
|
+
// For large vectors, use preview format (first 10 dimensions)
|
|
132
|
+
if (parsed.length > 10) {
|
|
133
|
+
const truncated = truncateVector(parsed, 10);
|
|
134
|
+
return {
|
|
135
|
+
preview: truncated.preview,
|
|
136
|
+
dimensions: truncated.dimensions,
|
|
137
|
+
truncated: truncated.truncated,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return { vector: parsed };
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
k: k,
|
|
144
|
+
iterations: maxIter,
|
|
145
|
+
sampleSize: vectors.length,
|
|
146
|
+
centroids: parsedCentroids,
|
|
147
|
+
note: "For production clustering, consider using specialized libraries",
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export function createVectorIndexOptimizeTool(adapter) {
|
|
153
|
+
// Schema with parameter smoothing
|
|
154
|
+
const IndexOptimizeSchemaBase = z.object({
|
|
155
|
+
table: z.string().optional().describe("Table name"),
|
|
156
|
+
tableName: z.string().optional().describe("Alias for table"),
|
|
157
|
+
column: z.string().optional().describe("Vector column"),
|
|
158
|
+
col: z.string().optional().describe("Alias for column"),
|
|
159
|
+
schema: z.string().optional().describe("Database schema (default: public)"),
|
|
160
|
+
});
|
|
161
|
+
const IndexOptimizeSchema = IndexOptimizeSchemaBase.transform((data) => ({
|
|
162
|
+
table: data.table ?? data.tableName ?? "",
|
|
163
|
+
column: data.column ?? data.col ?? "",
|
|
164
|
+
schema: data.schema,
|
|
165
|
+
}));
|
|
166
|
+
return {
|
|
167
|
+
name: "pg_vector_index_optimize",
|
|
168
|
+
description: "Analyze vector column and recommend optimal index parameters for IVFFlat/HNSW.",
|
|
169
|
+
group: "vector",
|
|
170
|
+
inputSchema: IndexOptimizeSchemaBase,
|
|
171
|
+
annotations: readOnly("Vector Index Optimize"),
|
|
172
|
+
icons: getToolIcons("vector", readOnly("Vector Index Optimize")),
|
|
173
|
+
handler: async (params, _context) => {
|
|
174
|
+
const parsed = IndexOptimizeSchema.parse(params ?? {});
|
|
175
|
+
const tableName = sanitizeTableName(parsed.table, parsed.schema);
|
|
176
|
+
const columnName = sanitizeIdentifier(parsed.column);
|
|
177
|
+
const schemaName = parsed.schema ?? "public";
|
|
178
|
+
const statsSql = `
|
|
179
|
+
SELECT
|
|
180
|
+
reltuples::bigint as estimated_rows,
|
|
181
|
+
pg_size_pretty(pg_total_relation_size('${tableName}'::regclass)) as table_size
|
|
182
|
+
FROM pg_class c
|
|
183
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
184
|
+
WHERE c.relname = $1 AND n.nspname = $2
|
|
185
|
+
`;
|
|
186
|
+
const statsResult = await adapter.executeQuery(statsSql, [
|
|
187
|
+
parsed.table,
|
|
188
|
+
schemaName,
|
|
189
|
+
]);
|
|
190
|
+
const stats = (statsResult.rows?.[0] ?? {});
|
|
191
|
+
// Validate column is actually a vector type before calling vector_dims
|
|
192
|
+
const typeCheckSql = `
|
|
193
|
+
SELECT udt_name FROM information_schema.columns
|
|
194
|
+
WHERE table_schema = $1 AND table_name = $2 AND column_name = $3
|
|
195
|
+
`;
|
|
196
|
+
const typeResult = await adapter.executeQuery(typeCheckSql, [
|
|
197
|
+
schemaName,
|
|
198
|
+
parsed.table,
|
|
199
|
+
parsed.column,
|
|
200
|
+
]);
|
|
201
|
+
if ((typeResult.rows?.length ?? 0) === 0) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
error: `Column '${parsed.column}' does not exist in table '${parsed.table}'`,
|
|
205
|
+
suggestion: "Use pg_describe_table to find available columns",
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const udtName = typeResult.rows?.[0]?.["udt_name"];
|
|
209
|
+
if (udtName !== "vector") {
|
|
210
|
+
return {
|
|
211
|
+
success: false,
|
|
212
|
+
error: `Column '${parsed.column}' is not a vector column (type: ${udtName ?? "unknown"})`,
|
|
213
|
+
suggestion: "Use a column with vector type for index optimization",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const dimSql = `
|
|
217
|
+
SELECT vector_dims(${columnName}) as dimensions
|
|
218
|
+
FROM ${tableName}
|
|
219
|
+
WHERE ${columnName} IS NOT NULL
|
|
220
|
+
LIMIT 1
|
|
221
|
+
`;
|
|
222
|
+
const dimResult = await adapter.executeQuery(dimSql);
|
|
223
|
+
const dimensions = dimResult.rows?.[0]?.dimensions;
|
|
224
|
+
const indexSql = `
|
|
225
|
+
SELECT i.indexname, i.indexdef
|
|
226
|
+
FROM pg_indexes i
|
|
227
|
+
WHERE i.tablename = $1 AND i.schemaname = $2
|
|
228
|
+
AND i.indexdef LIKE '%vector%'
|
|
229
|
+
`;
|
|
230
|
+
const indexResult = await adapter.executeQuery(indexSql, [
|
|
231
|
+
parsed.table,
|
|
232
|
+
schemaName,
|
|
233
|
+
]);
|
|
234
|
+
const rows = stats.estimated_rows ?? 0;
|
|
235
|
+
const recommendations = [];
|
|
236
|
+
if (rows < 10000) {
|
|
237
|
+
recommendations.push({
|
|
238
|
+
type: "none",
|
|
239
|
+
reason: "Table is small enough for brute force search",
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else if (rows < 100000) {
|
|
243
|
+
recommendations.push({
|
|
244
|
+
type: "ivfflat",
|
|
245
|
+
lists: Math.min(100, Math.round(Math.sqrt(rows))),
|
|
246
|
+
reason: "IVFFlat recommended for medium tables",
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
recommendations.push({
|
|
251
|
+
type: "hnsw",
|
|
252
|
+
m: dimensions !== undefined && dimensions > 768 ? 32 : 16,
|
|
253
|
+
efConstruction: 64,
|
|
254
|
+
reason: "HNSW recommended for large tables with high recall",
|
|
255
|
+
});
|
|
256
|
+
recommendations.push({
|
|
257
|
+
type: "ivfflat",
|
|
258
|
+
lists: Math.round(Math.sqrt(rows)),
|
|
259
|
+
reason: "IVFFlat is faster to build but lower recall",
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
table: parsed.table,
|
|
264
|
+
column: parsed.column,
|
|
265
|
+
dimensions,
|
|
266
|
+
estimatedRows: rows,
|
|
267
|
+
tableSize: stats.table_size,
|
|
268
|
+
existingIndexes: indexResult.rows,
|
|
269
|
+
recommendations,
|
|
270
|
+
};
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
export function createHybridSearchTool(adapter) {
|
|
275
|
+
// Schema with parameter smoothing
|
|
276
|
+
const HybridSearchSchemaBase = z.object({
|
|
277
|
+
table: z.string().optional().describe("Table name"),
|
|
278
|
+
tableName: z.string().optional().describe("Alias for table"),
|
|
279
|
+
vectorColumn: z.string().optional().describe("Vector column"),
|
|
280
|
+
vectorCol: z.string().optional().describe("Alias for vectorColumn"),
|
|
281
|
+
textColumn: z.string().describe("Text column for FTS"),
|
|
282
|
+
vector: z.array(z.number()).describe("Query vector"),
|
|
283
|
+
textQuery: z.string().describe("Text search query"),
|
|
284
|
+
vectorWeight: z
|
|
285
|
+
.number()
|
|
286
|
+
.optional()
|
|
287
|
+
.describe("Weight for vector score (0-1, default: 0.5)"),
|
|
288
|
+
limit: z.number().optional().describe("Max results"),
|
|
289
|
+
select: z
|
|
290
|
+
.array(z.string())
|
|
291
|
+
.optional()
|
|
292
|
+
.describe("Columns to return (defaults to non-vector columns)"),
|
|
293
|
+
});
|
|
294
|
+
const HybridSearchSchema = HybridSearchSchemaBase.transform((data) => ({
|
|
295
|
+
table: data.table ?? data.tableName ?? "",
|
|
296
|
+
vectorColumn: data.vectorColumn ?? data.vectorCol ?? "",
|
|
297
|
+
textColumn: data.textColumn,
|
|
298
|
+
vector: data.vector,
|
|
299
|
+
textQuery: data.textQuery,
|
|
300
|
+
vectorWeight: data.vectorWeight,
|
|
301
|
+
limit: data.limit,
|
|
302
|
+
select: data.select,
|
|
303
|
+
}));
|
|
304
|
+
return {
|
|
305
|
+
name: "pg_hybrid_search",
|
|
306
|
+
description: "Combined vector similarity and full-text search with weighted scoring.",
|
|
307
|
+
group: "vector",
|
|
308
|
+
inputSchema: HybridSearchSchemaBase,
|
|
309
|
+
annotations: readOnly("Hybrid Search"),
|
|
310
|
+
icons: getToolIcons("vector", readOnly("Hybrid Search")),
|
|
311
|
+
handler: async (params, _context) => {
|
|
312
|
+
const parsed = HybridSearchSchema.parse(params);
|
|
313
|
+
// Validate required parameters before using them
|
|
314
|
+
if (parsed.table === "") {
|
|
315
|
+
return {
|
|
316
|
+
success: false,
|
|
317
|
+
error: "table (or tableName) parameter is required",
|
|
318
|
+
requiredParams: [
|
|
319
|
+
"table",
|
|
320
|
+
"vectorColumn",
|
|
321
|
+
"textColumn",
|
|
322
|
+
"vector",
|
|
323
|
+
"textQuery",
|
|
324
|
+
],
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (parsed.vectorColumn === "") {
|
|
328
|
+
return {
|
|
329
|
+
success: false,
|
|
330
|
+
error: "vectorColumn (or vectorCol) parameter is required",
|
|
331
|
+
requiredParams: [
|
|
332
|
+
"table",
|
|
333
|
+
"vectorColumn",
|
|
334
|
+
"textColumn",
|
|
335
|
+
"vector",
|
|
336
|
+
"textQuery",
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
// Parse schema.table format (embedded schema takes priority)
|
|
341
|
+
let resolvedTable = parsed.table;
|
|
342
|
+
let resolvedSchema;
|
|
343
|
+
if (parsed.table.includes(".")) {
|
|
344
|
+
const parts = parsed.table.split(".");
|
|
345
|
+
resolvedSchema = parts[0];
|
|
346
|
+
resolvedTable = parts[1] ?? parsed.table;
|
|
347
|
+
}
|
|
348
|
+
const schemaName = resolvedSchema ?? "public";
|
|
349
|
+
const tableName = sanitizeTableName(resolvedTable, schemaName);
|
|
350
|
+
// Check column type - reject if it's a tsvector
|
|
351
|
+
const colTypeSql = `
|
|
352
|
+
SELECT data_type, udt_name
|
|
353
|
+
FROM information_schema.columns
|
|
354
|
+
WHERE table_schema = $1 AND table_name = $2 AND column_name = $3
|
|
355
|
+
`;
|
|
356
|
+
const colTypeResult = await adapter.executeQuery(colTypeSql, [
|
|
357
|
+
schemaName,
|
|
358
|
+
resolvedTable,
|
|
359
|
+
parsed.vectorColumn,
|
|
360
|
+
]);
|
|
361
|
+
const colType = colTypeResult.rows?.[0];
|
|
362
|
+
if (colType?.udt_name === "tsvector" ||
|
|
363
|
+
colType?.data_type === "tsvector") {
|
|
364
|
+
return {
|
|
365
|
+
success: false,
|
|
366
|
+
error: `Column '${parsed.vectorColumn}' is tsvector, not vector. For hybrid search, vectorColumn must be a pgvector column (type 'vector'). Use textColumn for text search.`,
|
|
367
|
+
suggestion: `Specify a different vector column, or check your table structure with pg_describe_table`,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
if (colType?.udt_name !== "vector" && colType !== undefined) {
|
|
371
|
+
const actualType = colType.udt_name ?? colType.data_type ?? "unknown";
|
|
372
|
+
return {
|
|
373
|
+
success: false,
|
|
374
|
+
error: `Column '${parsed.vectorColumn}' has type '${actualType}', not 'vector'. Hybrid search requires a pgvector column.`,
|
|
375
|
+
columnType: actualType,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
const vectorWeight = parsed.vectorWeight ?? 0.5;
|
|
379
|
+
// Fix floating point precision (e.g., 0.30000000000000004 -> 0.3)
|
|
380
|
+
const textWeight = Math.round((1 - vectorWeight) * 1000) / 1000;
|
|
381
|
+
const limitVal = parsed.limit ?? 10;
|
|
382
|
+
const vectorStr = `[${parsed.vector.join(",")}]`;
|
|
383
|
+
// Build select clause - use specified columns, excluding vector column if using t.*
|
|
384
|
+
let selectCols;
|
|
385
|
+
if (parsed.select !== undefined && parsed.select.length > 0) {
|
|
386
|
+
// Use only the explicitly selected columns
|
|
387
|
+
selectCols = parsed.select.map((c) => `t."${c}"`).join(", ");
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
// Get all columns except vector columns to avoid token waste
|
|
391
|
+
const colsSql = `
|
|
392
|
+
SELECT column_name
|
|
393
|
+
FROM information_schema.columns
|
|
394
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
395
|
+
AND udt_name != 'vector'
|
|
396
|
+
ORDER BY ordinal_position
|
|
397
|
+
`;
|
|
398
|
+
const colsResult = await adapter.executeQuery(colsSql, [
|
|
399
|
+
schemaName,
|
|
400
|
+
resolvedTable,
|
|
401
|
+
]);
|
|
402
|
+
const cols = (colsResult.rows ?? []).map((r) => r["column_name"]);
|
|
403
|
+
selectCols =
|
|
404
|
+
cols.length > 0 ? cols.map((c) => `t."${c}"`).join(", ") : "t.*";
|
|
405
|
+
}
|
|
406
|
+
const sql = `
|
|
407
|
+
WITH vector_scores AS (
|
|
408
|
+
SELECT
|
|
409
|
+
ctid,
|
|
410
|
+
1 - ("${parsed.vectorColumn}" <=> '${vectorStr}'::vector) as vector_score
|
|
411
|
+
FROM ${tableName}
|
|
412
|
+
WHERE "${parsed.vectorColumn}" IS NOT NULL
|
|
413
|
+
ORDER BY "${parsed.vectorColumn}" <=> '${vectorStr}'::vector
|
|
414
|
+
LIMIT ${String(limitVal * 3)}
|
|
415
|
+
),
|
|
416
|
+
text_scores AS (
|
|
417
|
+
SELECT
|
|
418
|
+
ctid,
|
|
419
|
+
ts_rank(to_tsvector('english', "${parsed.textColumn}"), plainto_tsquery($1)) as text_score
|
|
420
|
+
FROM ${tableName}
|
|
421
|
+
WHERE to_tsvector('english', "${parsed.textColumn}") @@ plainto_tsquery($1)
|
|
422
|
+
)
|
|
423
|
+
SELECT
|
|
424
|
+
${selectCols},
|
|
425
|
+
COALESCE(v.vector_score, 0) * ${String(vectorWeight)} +
|
|
426
|
+
COALESCE(ts.text_score, 0) * ${String(textWeight)} as combined_score,
|
|
427
|
+
COALESCE(v.vector_score, 0) as vector_score,
|
|
428
|
+
COALESCE(ts.text_score, 0) as text_score
|
|
429
|
+
FROM ${tableName} t
|
|
430
|
+
LEFT JOIN vector_scores v ON t.ctid = v.ctid
|
|
431
|
+
LEFT JOIN text_scores ts ON t.ctid = ts.ctid
|
|
432
|
+
WHERE v.ctid IS NOT NULL OR ts.ctid IS NOT NULL
|
|
433
|
+
ORDER BY combined_score DESC
|
|
434
|
+
LIMIT ${String(limitVal)}
|
|
435
|
+
`;
|
|
436
|
+
try {
|
|
437
|
+
const result = await adapter.executeQuery(sql, [parsed.textQuery]);
|
|
438
|
+
return {
|
|
439
|
+
results: result.rows,
|
|
440
|
+
count: result.rows?.length ?? 0,
|
|
441
|
+
vectorWeight,
|
|
442
|
+
textWeight,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
if (error instanceof Error) {
|
|
447
|
+
// Parse column not found errors
|
|
448
|
+
const colMatch = /column "([^"]+)" does not exist/.exec(error.message);
|
|
449
|
+
if (colMatch) {
|
|
450
|
+
const missingCol = colMatch[1] ?? "";
|
|
451
|
+
// Determine which parameter has the issue
|
|
452
|
+
let paramName = "column";
|
|
453
|
+
if (missingCol === parsed.textColumn) {
|
|
454
|
+
paramName = "textColumn";
|
|
455
|
+
}
|
|
456
|
+
else if (missingCol === parsed.vectorColumn) {
|
|
457
|
+
paramName = "vectorColumn";
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
success: false,
|
|
461
|
+
error: `Column '${missingCol}' does not exist in table '${resolvedTable}'`,
|
|
462
|
+
parameterWithIssue: paramName,
|
|
463
|
+
suggestion: "Use pg_describe_table to find available columns",
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
// Parse dimension mismatch errors
|
|
467
|
+
const dimMatch = /different vector dimensions (\d+) and (\d+)/.exec(error.message);
|
|
468
|
+
if (dimMatch) {
|
|
469
|
+
const expectedDim = dimMatch[1] ?? "0";
|
|
470
|
+
const providedDim = dimMatch[2] ?? "0";
|
|
471
|
+
return {
|
|
472
|
+
success: false,
|
|
473
|
+
error: `Vector dimension mismatch: column expects ${expectedDim} dimensions, but you provided ${providedDim} dimensions.`,
|
|
474
|
+
expectedDimensions: parseInt(expectedDim, 10),
|
|
475
|
+
providedDimensions: parseInt(providedDim, 10),
|
|
476
|
+
suggestion: "Ensure your query vector has the same dimensions as the column.",
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
// Parse relation not found errors
|
|
480
|
+
const relationMatch = /relation "([^"]+)" does not exist/.exec(error.message);
|
|
481
|
+
if (relationMatch) {
|
|
482
|
+
const missingRelation = relationMatch[1] ?? "";
|
|
483
|
+
return {
|
|
484
|
+
success: false,
|
|
485
|
+
error: `Table '${missingRelation}' does not exist`,
|
|
486
|
+
suggestion: "Use pg_list_tables to find available tables, or check the schema name",
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
// Return generic database error as {success: false} instead of throwing
|
|
490
|
+
return {
|
|
491
|
+
success: false,
|
|
492
|
+
error: error.message,
|
|
493
|
+
suggestion: "Check your query parameters and table structure",
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
// For non-Error exceptions, return generic error
|
|
497
|
+
return {
|
|
498
|
+
success: false,
|
|
499
|
+
error: "An unexpected error occurred",
|
|
500
|
+
details: String(error),
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
export function createVectorPerformanceTool(adapter) {
|
|
507
|
+
// Schema with parameter smoothing
|
|
508
|
+
const PerformanceSchemaBase = z.object({
|
|
509
|
+
table: z.string().optional().describe("Table name"),
|
|
510
|
+
tableName: z.string().optional().describe("Alias for table"),
|
|
511
|
+
column: z.string().optional().describe("Vector column"),
|
|
512
|
+
col: z.string().optional().describe("Alias for column"),
|
|
513
|
+
testVector: z
|
|
514
|
+
.array(z.number())
|
|
515
|
+
.optional()
|
|
516
|
+
.describe("Test vector for benchmarking"),
|
|
517
|
+
schema: z.string().optional().describe("Database schema (default: public)"),
|
|
518
|
+
});
|
|
519
|
+
const PerformanceSchema = PerformanceSchemaBase.transform((data) => ({
|
|
520
|
+
table: data.table ?? data.tableName ?? "",
|
|
521
|
+
column: data.column ?? data.col ?? "",
|
|
522
|
+
testVector: data.testVector,
|
|
523
|
+
schema: data.schema,
|
|
524
|
+
}));
|
|
525
|
+
return {
|
|
526
|
+
name: "pg_vector_performance",
|
|
527
|
+
description: "Analyze vector search performance and index effectiveness. Provide testVector for benchmarking (recommended).",
|
|
528
|
+
group: "vector",
|
|
529
|
+
inputSchema: PerformanceSchemaBase,
|
|
530
|
+
annotations: readOnly("Vector Performance"),
|
|
531
|
+
icons: getToolIcons("vector", readOnly("Vector Performance")),
|
|
532
|
+
handler: async (params, _context) => {
|
|
533
|
+
const parsed = PerformanceSchema.parse(params);
|
|
534
|
+
// Validate required params
|
|
535
|
+
if (parsed.table === "") {
|
|
536
|
+
return {
|
|
537
|
+
success: false,
|
|
538
|
+
error: "table (or tableName) parameter is required",
|
|
539
|
+
requiredParams: ["table", "column"],
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
if (parsed.column === "") {
|
|
543
|
+
return {
|
|
544
|
+
success: false,
|
|
545
|
+
error: "column (or col) parameter is required for the vector column name",
|
|
546
|
+
requiredParams: ["table", "column"],
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
const tableName = sanitizeTableName(parsed.table, parsed.schema);
|
|
550
|
+
const columnName = sanitizeIdentifier(parsed.column);
|
|
551
|
+
const schemaName = parsed.schema ?? "public";
|
|
552
|
+
// Check if column exists
|
|
553
|
+
const colCheckSql = `
|
|
554
|
+
SELECT 1 FROM information_schema.columns
|
|
555
|
+
WHERE table_schema = $1 AND table_name = $2 AND column_name = $3
|
|
556
|
+
`;
|
|
557
|
+
const colCheckResult = await adapter.executeQuery(colCheckSql, [
|
|
558
|
+
schemaName,
|
|
559
|
+
parsed.table,
|
|
560
|
+
parsed.column,
|
|
561
|
+
]);
|
|
562
|
+
if ((colCheckResult.rows?.length ?? 0) === 0) {
|
|
563
|
+
return {
|
|
564
|
+
success: false,
|
|
565
|
+
error: `Column '${parsed.column}' does not exist in table '${parsed.table}'`,
|
|
566
|
+
suggestion: "Verify the column name using pg_describe_table",
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
const indexSql = `
|
|
570
|
+
SELECT
|
|
571
|
+
i.indexname,
|
|
572
|
+
i.indexdef,
|
|
573
|
+
pg_size_pretty(pg_relation_size((i.schemaname || '.' || i.indexname)::regclass)) as index_size,
|
|
574
|
+
s.idx_scan,
|
|
575
|
+
s.idx_tup_read
|
|
576
|
+
FROM pg_indexes i
|
|
577
|
+
LEFT JOIN pg_stat_user_indexes s ON s.indexrelname = i.indexname AND s.schemaname = i.schemaname
|
|
578
|
+
WHERE i.tablename = $1 AND i.schemaname = $2
|
|
579
|
+
AND i.indexdef LIKE '%vector%'
|
|
580
|
+
`;
|
|
581
|
+
const indexResult = await adapter.executeQuery(indexSql, [
|
|
582
|
+
parsed.table,
|
|
583
|
+
schemaName,
|
|
584
|
+
]);
|
|
585
|
+
const statsSql = `
|
|
586
|
+
SELECT
|
|
587
|
+
reltuples::bigint as estimated_rows,
|
|
588
|
+
pg_size_pretty(pg_relation_size('${tableName}'::regclass)) as table_size
|
|
589
|
+
FROM pg_class c
|
|
590
|
+
JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
591
|
+
WHERE c.relname = $1 AND n.nspname = $2
|
|
592
|
+
`;
|
|
593
|
+
const statsResult = await adapter.executeQuery(statsSql, [
|
|
594
|
+
parsed.table,
|
|
595
|
+
schemaName,
|
|
596
|
+
]);
|
|
597
|
+
const stats = (statsResult.rows?.[0] ?? {});
|
|
598
|
+
let benchmark = null;
|
|
599
|
+
let testVectorSource;
|
|
600
|
+
let testVector = parsed.testVector;
|
|
601
|
+
// Auto-generate test vector from first row if not provided
|
|
602
|
+
if (testVector === undefined) {
|
|
603
|
+
try {
|
|
604
|
+
const sampleSql = `SELECT ${columnName}::text as vec FROM ${tableName} WHERE ${columnName} IS NOT NULL LIMIT 1`;
|
|
605
|
+
const sampleResult = await adapter.executeQuery(sampleSql);
|
|
606
|
+
const sampleRow = sampleResult.rows?.[0];
|
|
607
|
+
if (sampleRow?.vec !== undefined) {
|
|
608
|
+
// Parse vector string like "[0.1,0.2,0.3]" to array
|
|
609
|
+
const vecStr = sampleRow.vec.replace(/[[\]]/g, "");
|
|
610
|
+
testVector = vecStr.split(",").map(Number);
|
|
611
|
+
testVectorSource = "auto-generated from first row";
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
catch {
|
|
615
|
+
// Silently ignore - benchmark just won't be available
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
testVectorSource = "user-provided";
|
|
620
|
+
}
|
|
621
|
+
if (testVector !== undefined && testVector.length > 0) {
|
|
622
|
+
const vectorStr = `[${testVector.join(",")}]`;
|
|
623
|
+
const benchSql = `
|
|
624
|
+
EXPLAIN ANALYZE
|
|
625
|
+
SELECT * FROM ${tableName}
|
|
626
|
+
ORDER BY ${columnName} <-> '${vectorStr}'::vector
|
|
627
|
+
LIMIT 10
|
|
628
|
+
`;
|
|
629
|
+
const benchResult = await adapter.executeQuery(benchSql);
|
|
630
|
+
// Truncate large vectors in EXPLAIN output to reduce payload size
|
|
631
|
+
// Pattern matches vector literals like '[0.1,0.2,...,0.9]'::vector
|
|
632
|
+
const vectorPattern = /\[[\d.,\s-e]+\]'::vector/g;
|
|
633
|
+
const truncatedRows = (benchResult.rows ?? []).map((row) => {
|
|
634
|
+
const planLine = row["QUERY PLAN"];
|
|
635
|
+
if (planLine && planLine.length > 200) {
|
|
636
|
+
// Truncate long vector literals in query plan
|
|
637
|
+
const truncated = planLine.replace(vectorPattern, `[...${String(testVector.length)} dims]'::vector`);
|
|
638
|
+
return { "QUERY PLAN": truncated };
|
|
639
|
+
}
|
|
640
|
+
return row;
|
|
641
|
+
});
|
|
642
|
+
benchmark = truncatedRows;
|
|
643
|
+
}
|
|
644
|
+
const response = {
|
|
645
|
+
table: parsed.table,
|
|
646
|
+
column: parsed.column,
|
|
647
|
+
tableSize: stats.table_size,
|
|
648
|
+
// PostgreSQL returns -1 for tables that haven't been analyzed; normalize to 0
|
|
649
|
+
estimatedRows: (stats.estimated_rows ?? 0) < 0 ? 0 : (stats.estimated_rows ?? 0),
|
|
650
|
+
indexes: indexResult.rows,
|
|
651
|
+
benchmark,
|
|
652
|
+
recommendations: (indexResult.rows?.length ?? 0) === 0
|
|
653
|
+
? [
|
|
654
|
+
"No vector index found - consider creating one for better performance",
|
|
655
|
+
]
|
|
656
|
+
: [],
|
|
657
|
+
};
|
|
658
|
+
if (testVectorSource !== undefined) {
|
|
659
|
+
response["testVectorSource"] = testVectorSource;
|
|
660
|
+
}
|
|
661
|
+
if (benchmark === null) {
|
|
662
|
+
response["hint"] =
|
|
663
|
+
"No vectors in table to auto-generate test. Provide testVector param for benchmarking.";
|
|
664
|
+
}
|
|
665
|
+
return response;
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
export function createVectorDimensionReduceTool(adapter) {
|
|
670
|
+
// Define base schema that exposes all properties correctly to MCP
|
|
671
|
+
const VectorDimensionReduceSchemaBase = z.object({
|
|
672
|
+
// Direct vector mode
|
|
673
|
+
vector: z
|
|
674
|
+
.array(z.number())
|
|
675
|
+
.optional()
|
|
676
|
+
.describe("Vector to reduce (for direct mode)"),
|
|
677
|
+
// Table-based mode - include aliases for Split Schema compliance
|
|
678
|
+
table: z.string().optional().describe("Table name (for table mode)"),
|
|
679
|
+
tableName: z.string().optional().describe("Alias for table"),
|
|
680
|
+
column: z
|
|
681
|
+
.string()
|
|
682
|
+
.optional()
|
|
683
|
+
.describe("Vector column name (for table mode)"),
|
|
684
|
+
col: z.string().optional().describe("Alias for column"),
|
|
685
|
+
idColumn: z
|
|
686
|
+
.string()
|
|
687
|
+
.optional()
|
|
688
|
+
.describe("ID column to include in results (default: id)"),
|
|
689
|
+
limit: z.number().optional().describe("Max rows to process (default: 100)"),
|
|
690
|
+
// Common parameters - targetDimensions is required
|
|
691
|
+
targetDimensions: z
|
|
692
|
+
.number()
|
|
693
|
+
.optional()
|
|
694
|
+
.describe("Target number of dimensions"),
|
|
695
|
+
dimensions: z.number().optional().describe("Alias for targetDimensions"),
|
|
696
|
+
seed: z.number().optional().describe("Random seed for reproducibility"),
|
|
697
|
+
summarize: z
|
|
698
|
+
.boolean()
|
|
699
|
+
.optional()
|
|
700
|
+
.describe("Summarize reduced vectors to preview format in table mode (default: true)"),
|
|
701
|
+
});
|
|
702
|
+
// Schema with alias resolution applied via refinement
|
|
703
|
+
const VectorDimensionReduceSchema = VectorDimensionReduceSchemaBase.transform((data) => {
|
|
704
|
+
// Handle aliases: dimensions -> targetDimensions, tableName -> table, col -> column
|
|
705
|
+
const resolvedTargetDimensions = data.targetDimensions ?? data.dimensions;
|
|
706
|
+
return {
|
|
707
|
+
...data,
|
|
708
|
+
table: data.table ?? data.tableName,
|
|
709
|
+
column: data.column ?? data.col,
|
|
710
|
+
targetDimensions: resolvedTargetDimensions,
|
|
711
|
+
};
|
|
712
|
+
}).refine((data) => data.targetDimensions !== undefined, {
|
|
713
|
+
message: "targetDimensions (or dimensions alias) is required",
|
|
714
|
+
});
|
|
715
|
+
// Helper function for dimension reduction
|
|
716
|
+
const reduceVector = (vector, targetDim, seed) => {
|
|
717
|
+
const originalDim = vector.length;
|
|
718
|
+
const seededRandom = (s) => {
|
|
719
|
+
const x = Math.sin(s) * 10000;
|
|
720
|
+
return x - Math.floor(x);
|
|
721
|
+
};
|
|
722
|
+
const reduced = [];
|
|
723
|
+
const scaleFactor = Math.sqrt(originalDim / targetDim);
|
|
724
|
+
for (let i = 0; i < targetDim; i++) {
|
|
725
|
+
let sum = 0;
|
|
726
|
+
for (let j = 0; j < originalDim; j++) {
|
|
727
|
+
const randVal = seededRandom(seed + i * originalDim + j) > 0.5 ? 1 : -1;
|
|
728
|
+
sum += (vector[j] ?? 0) * randVal;
|
|
729
|
+
}
|
|
730
|
+
reduced.push(sum / scaleFactor);
|
|
731
|
+
}
|
|
732
|
+
return reduced;
|
|
733
|
+
};
|
|
734
|
+
return {
|
|
735
|
+
name: "pg_vector_dimension_reduce",
|
|
736
|
+
description: "Reduce vector dimensions using random projection. Supports direct vector input OR table-based extraction.",
|
|
737
|
+
group: "vector",
|
|
738
|
+
// Use base schema for MCP so properties are properly exposed in tool schema
|
|
739
|
+
inputSchema: VectorDimensionReduceSchemaBase,
|
|
740
|
+
annotations: readOnly("Vector Dimension Reduce"),
|
|
741
|
+
icons: getToolIcons("vector", readOnly("Vector Dimension Reduce")),
|
|
742
|
+
handler: async (params, _context) => {
|
|
743
|
+
// Use transformed schema with alias resolution for validation
|
|
744
|
+
const parsed = VectorDimensionReduceSchema.parse(params);
|
|
745
|
+
// Refine guarantees targetDimensions is defined, but add explicit check for type narrowing
|
|
746
|
+
const targetDim = parsed.targetDimensions;
|
|
747
|
+
if (targetDim === undefined) {
|
|
748
|
+
throw new Error("targetDimensions (or dimensions alias) is required");
|
|
749
|
+
}
|
|
750
|
+
const seed = parsed.seed ?? 42;
|
|
751
|
+
// Direct vector mode
|
|
752
|
+
if (parsed.vector !== undefined) {
|
|
753
|
+
const originalDim = parsed.vector.length;
|
|
754
|
+
if (targetDim >= originalDim) {
|
|
755
|
+
return {
|
|
756
|
+
success: false,
|
|
757
|
+
error: "Target dimensions must be less than original",
|
|
758
|
+
originalDimensions: originalDim,
|
|
759
|
+
targetDimensions: targetDim,
|
|
760
|
+
suggestion: `Reduce from ${String(originalDim)} to a smaller number`,
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
originalDimensions: originalDim,
|
|
765
|
+
targetDimensions: targetDim,
|
|
766
|
+
reduced: reduceVector(parsed.vector, targetDim, seed),
|
|
767
|
+
method: "random_projection",
|
|
768
|
+
note: "For PCA or UMAP, use external libraries",
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
// Table-based mode
|
|
772
|
+
if (parsed.table !== undefined && parsed.column !== undefined) {
|
|
773
|
+
const idCol = parsed.idColumn ?? "id";
|
|
774
|
+
const limitVal = parsed.limit ?? 100;
|
|
775
|
+
// Fetch vectors from table
|
|
776
|
+
const sql = `
|
|
777
|
+
SELECT "${idCol}" as id, "${parsed.column}"::text as vector_text
|
|
778
|
+
FROM "${parsed.table}"
|
|
779
|
+
WHERE "${parsed.column}" IS NOT NULL
|
|
780
|
+
LIMIT ${String(limitVal)}
|
|
781
|
+
`;
|
|
782
|
+
const result = await adapter.executeQuery(sql);
|
|
783
|
+
if ((result.rows?.length ?? 0) === 0) {
|
|
784
|
+
return {
|
|
785
|
+
error: "No vectors found in table",
|
|
786
|
+
table: parsed.table,
|
|
787
|
+
column: parsed.column,
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
// Determine if we should summarize (default true for table mode)
|
|
791
|
+
const shouldSummarize = parsed.summarize ?? true;
|
|
792
|
+
// Parse and reduce each vector
|
|
793
|
+
const reducedRows = [];
|
|
794
|
+
let originalDim = 0;
|
|
795
|
+
for (const row of result.rows ?? []) {
|
|
796
|
+
const vectorText = row["vector_text"];
|
|
797
|
+
// Parse PostgreSQL vector format: [0.1, 0.2, ...]
|
|
798
|
+
const vectorMatch = /\[([\d.,\s-e]+)\]/.exec(vectorText);
|
|
799
|
+
if (vectorMatch?.[1] === undefined)
|
|
800
|
+
continue;
|
|
801
|
+
const vector = vectorMatch[1]
|
|
802
|
+
.split(",")
|
|
803
|
+
.map((s) => parseFloat(s.trim()));
|
|
804
|
+
if (originalDim === 0)
|
|
805
|
+
originalDim = vector.length;
|
|
806
|
+
if (targetDim >= vector.length)
|
|
807
|
+
continue;
|
|
808
|
+
const reducedVector = reduceVector(vector, targetDim, seed);
|
|
809
|
+
// Apply summarization if requested
|
|
810
|
+
reducedRows.push({
|
|
811
|
+
id: row["id"],
|
|
812
|
+
original_dimensions: vector.length,
|
|
813
|
+
reduced: shouldSummarize
|
|
814
|
+
? truncateVector(reducedVector)
|
|
815
|
+
: reducedVector,
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
const response = {
|
|
819
|
+
mode: "table",
|
|
820
|
+
table: parsed.table,
|
|
821
|
+
column: parsed.column,
|
|
822
|
+
originalDimensions: originalDim,
|
|
823
|
+
targetDimensions: targetDim,
|
|
824
|
+
processedCount: reducedRows.length,
|
|
825
|
+
rows: reducedRows,
|
|
826
|
+
method: "random_projection",
|
|
827
|
+
note: "For PCA or UMAP, use external libraries",
|
|
828
|
+
};
|
|
829
|
+
// Add summarize indicator when summarization was applied
|
|
830
|
+
if (shouldSummarize) {
|
|
831
|
+
response["summarized"] = true;
|
|
832
|
+
response["hint"] =
|
|
833
|
+
"Vectors summarized to preview format. Use summarize: false for full vectors.";
|
|
834
|
+
}
|
|
835
|
+
return response;
|
|
836
|
+
}
|
|
837
|
+
return {
|
|
838
|
+
error: "Either vector (for direct mode) or table+column (for table mode) must be provided",
|
|
839
|
+
usage: {
|
|
840
|
+
directMode: "{ vector: [0.1, 0.2, ...], targetDimensions: 50 }",
|
|
841
|
+
tableMode: '{ table: "embeddings", column: "vector", targetDimensions: 50, limit: 100 }',
|
|
842
|
+
},
|
|
843
|
+
};
|
|
844
|
+
},
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
export function createVectorEmbedTool() {
|
|
848
|
+
const EmbedSchema = z.object({
|
|
849
|
+
text: z.string().describe("Text to embed"),
|
|
850
|
+
dimensions: z
|
|
851
|
+
.number()
|
|
852
|
+
.optional()
|
|
853
|
+
.describe("Vector dimensions (default: 384)"),
|
|
854
|
+
summarize: z
|
|
855
|
+
.boolean()
|
|
856
|
+
.optional()
|
|
857
|
+
.describe("Truncate embedding for display (default: true)"),
|
|
858
|
+
});
|
|
859
|
+
return {
|
|
860
|
+
name: "pg_vector_embed",
|
|
861
|
+
description: "Generate text embeddings. Returns a simple hash-based embedding for demos (use external APIs for production).",
|
|
862
|
+
group: "vector",
|
|
863
|
+
inputSchema: EmbedSchema,
|
|
864
|
+
annotations: readOnly("Vector Embed"),
|
|
865
|
+
icons: getToolIcons("vector", readOnly("Vector Embed")),
|
|
866
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
867
|
+
handler: async (params, _context) => {
|
|
868
|
+
const parsed = EmbedSchema.parse(params ?? {});
|
|
869
|
+
// Validate non-empty text
|
|
870
|
+
if (parsed.text === undefined || parsed.text === "") {
|
|
871
|
+
return {
|
|
872
|
+
success: false,
|
|
873
|
+
error: "text parameter is required and must be non-empty",
|
|
874
|
+
suggestion: "Provide text content to generate an embedding",
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
const dims = parsed.dimensions ?? 384;
|
|
878
|
+
const shouldSummarize = parsed.summarize ?? true;
|
|
879
|
+
const vector = [];
|
|
880
|
+
for (let i = 0; i < dims; i++) {
|
|
881
|
+
let hash = 0;
|
|
882
|
+
for (let j = 0; j < parsed.text.length; j++) {
|
|
883
|
+
hash = ((hash << 5) - hash + parsed.text.charCodeAt(j) + i) | 0;
|
|
884
|
+
}
|
|
885
|
+
vector.push(Math.sin(hash) * 0.5);
|
|
886
|
+
}
|
|
887
|
+
const magnitude = Math.sqrt(vector.reduce((sum, x) => sum + x * x, 0));
|
|
888
|
+
const normalized = vector.map((x) => x / magnitude);
|
|
889
|
+
// Summarize embedding if requested (default) to reduce LLM context size
|
|
890
|
+
const embeddingOutput = shouldSummarize
|
|
891
|
+
? truncateVector(normalized)
|
|
892
|
+
: normalized;
|
|
893
|
+
return {
|
|
894
|
+
embedding: embeddingOutput,
|
|
895
|
+
dimensions: dims,
|
|
896
|
+
textLength: parsed.text.length,
|
|
897
|
+
warning: "This is a demo embedding using hash functions. For production, use OpenAI, Cohere, or other embedding APIs.",
|
|
898
|
+
};
|
|
899
|
+
},
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
//# sourceMappingURL=advanced.js.map
|