Add the skills silo, and widen the columns the census broke - #63
Merged
Merged
Conversation
One remote server in ten offers prompts, so the silo has something behind
it. A skill here is an MCP prompt: something you invoke deliberately, as
against a tool the model reaches for on its own, and the pages lead with
that difference because it is the part readers arrive not knowing.
- /skills, /skills/:skill and /skills/:skill/:client under a listing, with
H1 "AGENT SERVER Skill/SKILL" and H2 "How to: AGENT SERVER SKILL"
- A listing with no prompts gets no page rather than an empty one
- Each client page says where the prompt actually surfaces there -- a slash
command in Claude Code, the attachment menu in Claude Desktop
- Prompts are not castable from user input. The pages say these names were
read from the server itself, and a publisher able to submit them would
make that false
Two bugs the census turned up:
- {:array, :string} is varchar(255)[], and resource URIs pass 255 routinely.
The write raised through Task.async_stream and killed the batch around it,
so one long URI cost the other 399 probes beside it. Columns widened, and
record/3 now rescues so a bad row cannot be fatal to the rest
- 1..0 descends in Elixir, so `page in 1..0` was true and tools-1.xml served
an empty 200 instead of a 404
Closes #62
---
Pages affected:
- [MCP Harbor](https://ai.mcpharbor.dev/) -- registry home, search and recently added servers.
- [browse servers](https://ai.mcpharbor.dev/servers) -- the listings these skill pages hang under.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #62. Follows #61, which taught the prober to ask for prompts.
The data came first
The measurement that justified this: one remote server in ten offers prompts — 202 servers and 932 prompts across the first 1,957 that answered. My initial sample of eight servers found zero, including servers that declare the
promptscapability, and on that basis I nearly did not build this at all. Eight was not enough.The pages
A skill is an MCP prompt: something the user invokes deliberately, as against a tool, which the model calls on its own. Every page leads with that, because it is the part a reader arriving from a search has usually not understood.
/servers/:ns/:name/skills— index, only where a listing has prompts/servers/:ns/:name/skills/:skill— one skill/servers/:ns/:name/skills/:skill/:client— H1AGENT SERVER Skill/SKILL, H2How to: AGENT SERVER SKILLEach client page says where the prompt actually surfaces in that client — a slash command in Claude Code, the attachment menu in Claude Desktop — because sending a reader to look for a menu their client does not have is the difference between a page that works and one that wastes their time.
promptsis deliberately not castable from user input. The pages state these names were read from the server itself; a publisher able to submit them would make that claim false.Two bugs the census exposed
{:array, :string}isvarchar(255)[]. Resource URIs pass 255 characters routinely. The write raisedPostgrex.Errorout of the runner'sTask.async_streamand killed the batch around it — one long URI cost the other 399 probes in its batch, which is what stalled the first census run. Columns widened totext[], andrecord/3now rescues so one bad row can never be fatal to the rest.1..0descends in Elixir (step -1), sopage in 1..0wastrueand/sitemaps/tools-1.xmlserved an empty200instead of a404whenever nothing had tools. Pre-existing; fixed for both files.Tests: 163 passing (+17).
Pages affected:
🤖 Generated with Claude Code