registry/internal/database/migrations/003_simplify_to_key_value.sql
adam jones 218b0b422d
Implement flattened _meta format for server extensions (#331)
## Summary

This PR implements the flattened `_meta` format for server extensions as
discussed in #284, replacing the confusing wrapper format with a clean
single-file approach.

**Before (wrapper format):**
```json
{
  "server": { "name": "my-server", "description": "..." },
  "x-publisher": { "build_info": "..." },
  "x-io.modelcontextprotocol.registry": { "id": "...", "published_at": "..." }
}
```

**After (flattened format):**
```json
{
  "name": "my-server",
  "description": "...",
  "_meta": {
    "publisher": { "build_info": "..." },
    "io.modelcontextprotocol.registry": { "id": "...", "published_at": "..." }
  }
}
```

## Key Changes

- **Flattened Format**: Single `ServerJSON` file with structured `_meta`
field
- **Better DX**: Publishers maintain one file instead of separate
server.json + extensions.json
- **MCP Compliance**: Uses standard `_meta` mechanism instead of `x-*`
prefixes
- **Simplified Database**: PostgreSQL now uses simple `id, value` table
structure
- **Type Safety**: Structured `ServerMeta` with known extension fields

## Database Migration

Added migration `003_simplify_to_key_value.sql` that drops the complex
relational structure and creates a simple key-value table. This
significantly simplifies database management.

## Testing

- All core tests passing (validators, service layer)
- Schema validation working for all 10 examples
- Seed data successfully migrated (396 entries)
- Publishing functionality verified

Fixes #284
2025-09-01 19:27:23 +01:00

24 lines
No EOL
1.2 KiB
SQL

-- Simplify database to simple key-value table with id, value
-- This migration drops all existing data and creates a clean simple structure
-- Drop old tables and functions
DROP TRIGGER IF EXISTS update_server_extensions_on_server_update ON servers;
DROP FUNCTION IF EXISTS update_server_extensions_updated_at();
DROP TRIGGER IF EXISTS update_servers_updated_at ON servers;
DROP FUNCTION IF EXISTS update_updated_at_column();
DROP TABLE IF EXISTS server_extensions;
DROP TABLE IF EXISTS servers;
-- Create new simple servers table
CREATE TABLE servers (
id VARCHAR(255) PRIMARY KEY, -- Use registry metadata ID as primary key
value JSONB NOT NULL -- Complete ServerJSON as JSONB
);
-- Create essential indexes for performance
CREATE INDEX idx_servers_id ON servers (id);
CREATE INDEX idx_servers_name_latest ON servers ((value->>'name'), (value->'_meta'->'io.modelcontextprotocol.registry'->>'is_latest'))
WHERE (value->'_meta'->'io.modelcontextprotocol.registry'->>'is_latest')::boolean = true;
CREATE INDEX idx_servers_updated_at ON servers ((value->'_meta'->'io.modelcontextprotocol.registry'->>'updated_at'));
CREATE INDEX idx_servers_remotes ON servers USING GIN((value->'remotes'));