{"id":"666eff70-44d0-4121-af33-4d11c59b5d12","slug":"dsh-postgres-expert","kind":"mcp","name":"dsh-postgres-expert","summary":"PostgreSQL expertise for DeepSeek Harness: 11 curated pg-aiguide skills from Tiger Data registered natively, plus the pg-aiguide MCP server for version-exact manual search.","owner":"mirelconstantin","repoUrl":"https://github.com/mirelconstantin/dsh-postgres-expert","license":"Apache-2.0","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-10-10T07:48:28.000Z","addedAt":"2026-10-21T05:17:57.900Z","logoUrl":"https://avatars.githubusercontent.com/u/92734558?u=4ae16142feba9dd2156e7f6332ed27d483f09c4e&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["databases","cloud-infra","search"],"tags":["codex","deepseek-harness","deepseek-harness-plugin","dsh","dsh-external","dsh-plugin","dsh-plugins","pgvector"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-27T01:14:37.764Z","sample":false,"url":"https://conduits.dev/tools/dsh-postgres-expert","language":"JavaScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/pazalo/.github/main/assets/pazalo-logo.png\" width=\"112\" alt=\"Pazalo\">\n</p>\n\n<h1 align=\"center\">dsh-postgres-expert</h1>\n\n<p align=\"center\">\n  <img src=\"https://img.shields.io/npm/v/dsh-postgres-expert-FFC24D?style=flat-square&logo=npm&logoColor=black\" alt=\"npm version\">\n  <img src=\"https://img.shields.io/npm/dw/dsh-postgres-expert-F0522C?style=flat-square&logo=npm&logoColor=white\" alt=\"npm downloads\">\n  <img src=\"https://img.shields.io/badge/Node-%3E%3D22.19-FFC24D?style=flat-square&logo=node&logoColor=black\" alt=\"Node\">\n  <img src=\"https://img.shields.io/badge/Skills-11-FFC24D?style=flat-square\" alt=\"Skills\">\n  <img src=\"https://img.shields.io/badge/Tests-26-FFC24D?style=flat-square\" alt=\"Tests\">\n  <img src=\"https://img.shields.io/badge/Licence-Apache--2.0-F0522C?style=flat-square\" alt=\"Licence\">\n</p>\n\n<p align=\"center\">\n  PostgreSQL expertise for DeepSeek Harness. Eleven curated skills from\n  Tiger Data's pg-aiguide, registered as native skills, plus the public MCP\n  server for version-exact manual search — so the model stops writing 2015-era\n  schemas from memory.\n</p>\n\n## Install\n\nAnyone can install this. It needs a DeepSeek Harness profile, and nothing else —\nno API key, no database and no account, because the only network call it makes is\nan optional documentation search against a public endpoint.\n\nFrom the GUI, paste this into **Add plugin**:\n\n```\ndsh-postgres-expert\n```\n\nOr from a terminal:\n\n```bash\ndsh plugin add dsh-postgres-expert\n```\n\nThat is a plain npm install. It needs neither git nor a GitHub account.\n\n**No build step is involved.** Every entry point ships as committed source, so\npnpm never has to run this package's scripts and you are never asked to\nallowlist a build. Restart the profile afterwards and three rows appear.\n\n<details>\n<summary>Asking an agent instead</summary>\n\nYou can also just say *\"install the `dsh-postgres-expert` plugin in this\nprofile\"* and the agent will run the same install for you — it has a\n`plugin_manager install_bundle` tool and writes the bundle for you. You do not\nneed this route, and it is not shorter; it is there because installing from an\nagent is occasionally the only option available, such as over a remote host.\n\nOne thing to know if you use it: installing a package means its code runs on\nyour machine, so the agent will ask for approval first. That prompt is the\npoint, not an obstacle.\n\n</details>\n\n<details>\n<summary>Installing by other routes</summary>\n\n| Route | Command |\n| --- | --- |\n| npm, the default | `dsh plugin add dsh-postgres-expert` |\n| Pinned to a version | `dsh plugin add dsh-postgres-expert@1.0.0` |\n| Pinned to a commit | `dsh plugin add github:mirelconstantin/dsh-postgres-expert#<sha>` |\n| Tarball | `dsh plugin add ./dsh-postgres-expert-1.0.0.tgz` |\n| Local checkout | `dsh plugin add /absolute/path/to/dsh-postgres-expert` |\n| As a profile dependency | see below |\n\nThe GitHub route needs nothing but git access to this repository. The npm route\nneeds neither git nor an account, and is what the command above uses.\n\nAs a profile dependency, add it to `package.json` and to `dsh.profile.bundles`:\n\n```json\n{\n  \"dependencies\": {\n    \"dsh-postgres-expert\": \"1.0.0\"\n  },\n  \"dsh\": {\n    \"profile\": {\n      \"bundles\": [\"@deepseek-ai/dsh-base\", \"@deepseek-ai/dsh-web-app\", \"dsh-postgres-expert\"]\n    }\n  }\n}\n```\n\n`dsh plugin add` does both of those edits for you.\n\n</details>\n\n## What it adds\n\n| Row | What it does |\n| --- | --- |\n| `postgres-expert-skills` | registers the 11 vendored skills on `ctx.skills` |\n| `postgres-expert-prompt` | the system-prompt section that makes the guidance known |\n| `postgres-expert-mcp` | connects the public pg-aiguide MCP server over Streamable HTTP |\n\nThe rows are independent. **`postgres-expert-mcp` is the only one that touches\nthe network**, so disabling it leaves the curated skills working entirely\noffline:\n\n```yaml\n- id: postgres-expert-mcp\n  disabled: true\n```\n\nOverriding that row replaces its whole `config` object, so re-declare every\nfield you still want. The fields are the\n[`@deepseek-ai/dsh-mcp-client` configuration](https://github.com/deepseek-ai/deepseek-harness/blob/main/docs/config-catalog.md#deepseek-aidsh-mcp-client):\n`transport`, `serverName`, `url`, `headers`, `toolCallTimeoutMs`,\n`failOnStartupError`, `maxInstructionBytes` and `reconnect`.\n\n## The skills\n\n| Skill | Covers |\n| --- | --- |\n| `postgres` | umbrella router; points at the right reference for any PostgreSQL task |\n| `design-postgres-tables` | data types, constraints, indexes, JSONB, partitioning |\n| `design-postgis-tables` | spatial design, geometry vs geography, SRIDs, spatial indexes |\n| `schema-exploration` | read-only exploration of an existing database through `pg_catalog` |\n| `postgres-database-migration` | zero-downtime DDL, lock levels, backfills, rollback |\n| `pgvector-semantic-search` | vector indexes, filtered search, tuning |\n| `postgres-hybrid-text-search` | BM25 and semantic search fused with RRF |\n| `setup-timescaledb-hypertables` | hypertables, compression, retention, continuous aggregates |\n| `find-hypertable-candidates` | SQL that scores existing tables for hypertable conversion |\n| `migrate-postgres-tables-to-hypertables` | partition-column choice, in-place vs blue-green, validation |\n| `timescaledb-hyperfunctions` | hyperfunctions for aggregation and analysis |\n\n## How they load themselves\n\nYou do not have to invoke a skill, and you do not have to remember a name. The\nharness does the routing, and it happens before the model ever decides anything:\n\n1. **Every skill announces itself.** At the first step of a session the harness\n   injects an `<available_skills>` catalog carrying each skill's name and\n   description — nothing else, no bodies. Each session gets this\n   automatically.\n2. **The descriptions are the routing table.** They are written for it: pg-aiguide\n   packs each description with trigger phrases and a keyword line (`PostgreSQL,\n   Postgres, schema, table design, indexes, constraints, hypertable, semantic\n   search, …`). That is what makes the match, not anything this plugin does.\n3. **The model loads the one it needs.** When the task is PostgreSQL, the model\n   calls `skill({ name })` by itself. That is the whole mechanism.\n\nSo \"when it is about postgres\" is already the behaviour: ask for a schema and\nthe model loads `postgres` or `design-postgres-tables` on its own. Ask about\nReact and nothing loads, because the catalog is the only thing in the prompt.\n\nThis plugin's own `postgres-expert-prompt` section reinforces it by naming the\nskills and the MCP tool, so the model does not have to infer the tools exist.\n\nThe one thing this cannot do is override a deliberate restriction: a preset's\n`tools.restrict({ allow: [...] })`, a subagent's `toolFilter` or a disabled\n`postgres-expert-skills` row removes the skills from that scope, and the prompt\nsection withdraws itself with them rather than advertising tools it cannot\nreach.\n\nBodies load on demand, so a session that never touches PostgreSQL pays nothing\nfor any of this.\n\n## The MCP connection\n\nThe harness connects to `https://mcp.tigerdata.com/docs`, negotiates the\nprotocol, discovers the tools and exposes each as an ordinary harness tool with\ncancellation, permission checks and recorded results. It does not host or\nsupervise the server — Tiger Data runs it.\n\nUpstream exposes exactly two tools:\n\n| Tool | Arguments |\n| --- | --- |\n| `mcp__pg-aiguide__search_docs` | `source`, `query`, optional `limit` (default 20) and `semanticWeight` (0 keyword → 1 semantic, default 0.7) |\n| `mcp__pg-aiguide__view_skill` | `name`, optional `path` |\n\n`source` carries **both corpus and version in one value** — `tiger`,\n`postgres_14` … `postgres_18`, `postgis_3.3` … `postgis_3.6`. There is no\nseparate version argument.\n\n`view_skill` overlaps with the skills vendored here, which is why the skills are\nregistered natively rather than read back over MCP.\n\nDiscovery is asynchronous: after a restart, wait for the `mcp__pg-aiguide__*`\ntools before sending the first prompt that needs them. If the endpoint is\nunreachable the bundle still loads, `failOnStartupError: false` keeps it that\nway, and the reconnect policy retries with backoff.\n\n## Staying current\n\nThe vendored skills under `assets/skills/` are what the plugin serves, so a copy\nthat is not synced is a package serving stale advice.\n\n**`assets/upstream.json` is the provenance.** It records the upstream commit, a\nSHA-256 digest per file, and the licence the copy was taken under — so the exact\nupstream state this package corresponds to is reviewable without fetching\nanything.\n\n```bash\nnpm run sync          # rewrite assets/skills/ and the pin from upstream\nnpm run sync:check    # fail if the vendored tree differs from what upstream gives\nnpm test              # behaviour tests over the catalogue and the sync helpers\n```\n\nA GitHub Actions workflow runs `sync` daily and opens a pull request when\nupstream has moved. CI runs `sync:check` on **Linux and Windows** on every push\nand pull request, so a package cannot be published against a stale mirror.\n\n## Releasing\n\nMerging an upstream sync is not enough on its own: the registry serves a fixed\ntarball, so a new upstream state needs a new npm version before anyone receives\nit.\n\n```bash\nnpm run prepublish      # every gate, without publishing\nnpm version patch       # 1.0.0 -> 1.0.1\nnpm publish\ngit push --follow-tags\n```\n\n`npm publish` runs `scripts/prepublish.mjs` first, and refuses if any of it\nfails. A published name and version can never be reused, even after an\nunpublish, so the gate checks that the version is free on the registry, that the\nworking tree is committed, and that the tag points at HEAD — otherwise the\nregistry and the repository would describe different code under the same\nversion.\n\n<details>\n<summary>How the sync reads upstream</summary>\n\nOne repository tarball, with the sha resolved by `git ls-remote` — so it needs no\nGitHub token and cannot exhaust the API rate limit on a schedule. Two details of\nthe upstream tree are handled explicitly:\n\n- **Symlinks are materialised.** pg-aiguide's `postgres` umbrella skill points\n  its `references/` at the sibling skills with relative symlinks. Those links do\n  not survive every checkout or npm publish, so their contents are copied into\n  place and the vendored tree is identical on every platform.\n- **Only markdown below `skills/` is copied**, so the output stays reviewable.\n\n</details>\n\n## Licence and attribution\n\nThe vendored skills are redistributed **unmodified** under the Apache License\n2.0 from [timescale/pg-aiguide](https://github.com/timescale/pg-aiguide). See\n[LICENSE](LICENSE) and [NOTICE](NOTICE); the upstream copyright notice is\nretained verbatim as that licence requires.\n\nThis plugin configures a connection to a public MCP server operated by Tiger\nData. It vendors no server code and sends no telemetry.\n\n`icon.svg` is Pazalo's logo.\n\n## Layout\n\n```\ncordis.patch.yml            the bundle: three independent rows\nicon.svg                    the plugin panel's row image\nsrc/catalog.js              reads the vendored skills and their frontmatter\nsrc/entry-skills.js         loader entry registering the skills\nsrc/entry-prompt.js         loader entry publishing the guidance section\nsrc/prompt.js               the guidance text and its visibility check\nassets/skills/              the vendored pg-aiguide skills (synced, not edited)\nassets/upstream.json        the upstream commit and a digest per file\nscripts/sync-upstream.mjs   the vendoring tool\nscripts/check-patch.mjs     CI gate: bundle patch, exports and icon\ntest/plugin.test.js         behaviour tests\n```\n\nNever edit anything under `assets/skills/` by hand: the next sync overwrites it\nand `sync:check` fails on the difference. Change upstream, or change this\nplugin's own source.\n\n<p align=\"center\">\n  <sub>Plugin © 2026 dsh-postgres-expert contributors<br>\n  Skills © 2025 Timescale, Inc., d/b/a Tiger Data — Apache-2.0</sub>\n</p>\n"}