Repository navigation
Description
Relocated from dezren39/darwin-nix#115 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Parent: #176
Summary
Two things: add four specific servers (Dropbox, Google Drive, Outlook, Tailscale), and give mcpx a channel for "you should add this" / "this one is slow, host it locally" so that the first thing is not a manual pipeline forever.
The second is the more interesting one, and the finding is that mcpx should not grow a curated vendor list. It already has registry search, live server add, and CLI→MCP adapters; what it is missing is the memory and the ranking — a record of what a user wanted and could not find, and enough metadata to answer "is there a better instance of this than the one I am using". A curated list of four servers is a snapshot that rots; a good search-add-record loop keeps working.
Original notes
- mcp-owned opencode api support
- add the dropboxMcp, googleDriveMcp, outlookMcp, tailscaleMcp
- please make an alias for the tailscaleMcp except it should not require auth it should accept the creds i already used to connect to it and the only skill it should provide is listTailnet and listHostnames
- accept user feedback, requests, routinely implement features/interfaces that are good idea. "you should add this mcp it's free." "this mcp is very good you should consider hosting it locally because the public one is slow and limited"
Current state (what mcpx does today, with file refs)
| capability | where |
|---|---|
| search the public MCP registry | GET /v1/registry/search, internal/registry/registry.go:153 (pins version=latest at :158; matches server names only, as a substring), mcpx registry search|show|add (internal/cli/registry.go:15) — there is no mcpx connect |
| add a registry server to config | mcpx registry add <name> prints the entry and the variables it needs; --write adds it (internal/cli/registry.go:92-124). No verify-it-starts step, no rollback. |
| add a server live, project or user scope | POST /v1/servers (internal/api/ops_settings.go:82) — command/args/env or url/headers/transport, plus mcpx extras |
| remove a server live | DELETE /v1/servers/{name} |
| expose one server as several filtered namespaces | aliasOf + mcpx.tools (docs/story.md §"Profiles and aliases") |
| wrap a CLI program as a server | internal/adapter, paths.adapters |
| wrap an OpenAPI service as a server | internal/openapi, paths.apis, mcpx api --spec |
| credentials | mcpauth.Auth on a server entry; ${VAR} expansion in APISpec.Headers; OAuth for remote servers is declared and not performed (docs/protocol.md §6) |
| per-server latency and error statistics | GET /v1/stats — calls, servers, instances, errors, sessions, volume, slowest |
| a feedback channel | none |
| a record of a search that found nothing | none |
The statistics row matters: mcpx already measures exactly the thing the note's second quote is about ("the public one is slow and limited"). It measures it and does nothing with it.
What exists for the four requested servers
Queried the official registry, https://registry.modelcontextprotocol.io/v0/servers?search=<name>, on 2026-09-30. Results are noisy — the same package is returned several times under different versions — and deduplicated here. (That is the raw API queried without version=latest. mcpx always sends the pin, internal/registry/registry.go:158, and gets distinct names — see #179.)
| requested | found | notes |
|---|---|---|
| Dropbox | io.github.pipeworx-io/dropbox ("Dropbox MCP Pack — wraps the Dropbox API v2"), ai.smithery/cindyloo-dropbox-mcp-server (search/browse/read), io.usefulapi/dropbox-sign (a different product — Dropbox Sign) |
no first-party Dropbox entry; all third-party |
| Google Drive | search=google drive → 0 results; search=gdrive → 0 results. Only com.mcparmory/google-drive surfaced, under search=drive |
no first-party Google entry in the registry. The best-known Drive server is the gdrive reference server from modelcontextprotocol/servers, which was moved to the archived set. Effectively: nothing well-maintained and official. |
| Outlook | io.github.chrischall/office-outlook-mcp (mail, calendar, contacts, tasks), io.github.0xka13b/microsoft-outlook-mcp (read/search/send), com.mintmcp/outlook-email, com.mintmcp/outlook-calendar |
no first-party Microsoft entry under this search. Microsoft ships MCP for other products; Outlook coverage here is third-party. |
| Tailscale | io.github.YawLabs/tailscale-mcp ("manage your tailnet from AI assistants"), ai.dinglebear/rtailscale (devices, routes, DNS, keys, users, ACLs — MCP and CLI), ai.dinglebear/tailscale-rmcp (Rust MCP server and CLI) |
no first-party Tailscale entry. |
Two conclusions:
- None of the four has a first-party server. Every option is community-maintained, of unknown quality, and requires handing it a credential to a fairly consequential account. That is a reason to prefer the thinnest possible wrapper, not the richest one.
- Three of the four have an excellent official CLI or HTTP API, which mcpx can already consume without any MCP server.
tailscalethe CLI coversstatus --json(hostnames, tailnet, devices) and the Tailscale API is documented and simple; Microsoft Graph and the Dropbox API v2 both publish OpenAPI-ish documents. Sointernal/adapterandinternal/openapiare a better route than adopting a third-party server: the declaration is reviewable, the credential handling is${VAR}expansion, and there is no extra process from an unknown author in the trust path.
For the specific tailscale request — an alias exposing only listTailnet and listHostnames — the cheapest correct answer is an adapter spec over the tailscale CLI, about fifteen lines:
{ "name": "tailscale", "command": "tailscale",
"tools": [
{ "name": "listTailnet", "args": ["status", "--json"], "json": true },
{ "name": "listHostnames", "args": ["status", "--json"], "json": true }
] }It requires no auth because the local tailscale CLI is already authenticated — which is the literal reading of "it should accept the creds i already used to connect to it". The renaming and narrowing that an alias over a real MCP server would need is the toolViews work in #114; the adapter route needs none of it, because an adapter declares its own tool names. Worth doing as the first proof that adapters are the right default for this class of request.
Approaches
Approach A — least recommended: ship a curated list of vendor servers in mcpx's defaults
Bundle known-good entries for Dropbox, Drive, Outlook, Tailscale and others in internal/defaults, so mcpx registry add dropbox just works.
Why not:
- It is a snapshot of a directory that already exists and is maintained by someone else. The registry is the curation layer; duplicating a slice of it into a Go binary means every entry rots at its own rate and a stale one is worse than no entry, because it carries mcpx's implicit endorsement.
- It makes mcpx an opinion about third-party code quality across products it does not use, for a trust decision (handing over a Dropbox or Microsoft 365 credential) that is genuinely consequential and genuinely the user's.
- It answers the wrong question. A user asking for "the Dropbox MCP" wants Dropbox capability, not a specific package. The registry answers "which packages exist"; nothing today answers "which of these should I use", and a hard-coded list does not answer it either — it just hides the question.
- It also scales badly: there are thousands of servers and four is not a stopping point anyone will respect.
Approach B — middle: make discovery and adoption good, and document the four as recipes
Improve what exists rather than adding a list:
- Registry metadata in search output. The registry carries more than name and description; surface what it has — package type, transport, remote-or-local, version recency, whether it is official. "Is this maintained" is the first question and today the answer requires leaving mcpx. Part of it is already fetched and thrown away: each result's
_metais decoded intolistResponse(internal/registry/registry.go:137-146) and dropped at:168-169. It carriesio.modelcontextprotocol.registry/officialwithstatus,publishedAt,updatedAtandisLatest(checked live 2026-09-30). Deduplicate registry results. The raw responses above return the same server up to nine times across versions.Struck (issues pass, 2026-09-30, at 05c78b2): mcpx never sees those duplicates.internal/registryshould collapse by name and show the newest version, which is a small, clearly-correct fix (visible directly in the query output quoted above).Searchpinsversion=lateston every query (internal/registry/registry.go:158), every caller goes through it, and five live searches returned all-distinct names (Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179). The duplicates belong to the un-pinned raw query above, which mcpx does not issue. What Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179 found instead, and owns:registry.pageSizeis only consulted whenlimit <= 0(:155), andnextCursoris parsed (:143) and dropped, so a search silently stops at one page.mcpx registry add <name>end to end (this issue first called itmcpx connect, which does not exist; the command ismcpx registry): search, pick, show what it will run and what credentials it wants —registry show/addalready do this much — add it at project or user scope, verify it starts and lists tools, and roll back if it does not.POST /v1/serversplus/v1/healthalready provide the rest.- Prefer an adapter or an OpenAPI declaration when one is available. When a requested capability has a well-known CLI or published API document, say so: "
tailscaleis installed; an adapter declaration needs no credential and no third-party process. Generate one?" That is a better default than adopting an unknown server, and it connects directly to the spec-generation work in Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114. - Ship the four as documented example declarations, in
docs/, not in defaults — copy-pasteable, reviewable, and obviously not endorsed-and-maintained by mcpx.
This is all deterministic and most of it is small.
Approach C — recommended: B, plus a recorded feedback loop that mcpx can actually act on
Do B. Then close the loop the second bullet is asking for — and note that the useful version of it is mostly evidence mcpx already has, not free text.
1. Record the misses. Every mcpx search and registry search that returned nothing or was followed by no call is a data point. Store them (the event store, #6, is the natural home) and expose mcpx feedback / GET /v1/feedback as the local list: "you searched for calendar 6 times in 3 sessions and never called a tool." That is a concrete, unarguable statement of a missing capability, derived at zero cost from telemetry that already flows through /v1/log.
2. Turn statistics into a recommendation. "This mcp is very good you should consider hosting it locally because the public one is slow and limited" is a measurement, and /v1/stats already has slowest, errors and volume per server. A mcpx doctor check — and doctor already exists (internal/cli/doctor.go) as the place mcpx tells you what is wrong — can say: "notion (remote): p95 4.2s over 340 calls, 6% errors. A local package exists in the registry. Switch?" Remote-versus-local is visible in the config (url versus command), and the registry says whether a local package is published. This is the single best item in this issue: it is deterministic, it uses only data mcpx already collects, and it produces exactly the advice the note quotes.
3. Accept explicit feedback as a first-class record. mcpx feedback "add a calendar mcp" / POST /v1/feedback, appended to a local file with the context mcpx can attach automatically (which servers are configured, which searches failed, what the daemon version is). Local by default and never transmitted anywhere. Its purposes, in order: it gives the user a place to put the thought, it gives mcpx prompt something to act on, and it gives a maintainer a file to paste into an issue if the user chooses to.
4. Let the prompt layer read it. With #113's intent --scope ops, "add the thing I keep failing to find" becomes: read the miss log, search the registry, propose a server or an adapter declaration, show the plan, add on confirmation. Every step is an existing declared operation; the model only chooses among them. That is "routinely implement features/interfaces that are good idea" in the only form that is safe — mcpx proposing, the user approving.
5. Explicitly out of scope: mcpx modifying itself in response to feedback. The note's "routinely implement features" could be read as self-modification. It should not be. The loop ends at a proposal a human accepts; anything past that is the arbitrary-provisioning question deferred in #113.
Recommended because it converts a vague "accept feedback" into three concrete, mostly-deterministic features built on data mcpx already has; because the slow-remote-server recommendation is genuinely valuable and genuinely cheap; and because it avoids taking on the maintenance and the implied endorsement of a vendor list.
Open questions
- Where do feedback and miss records live — the event store (Bump build/buck/preludes/buck2-prelude from
3a02ea3to4371899#6), a plain JSONL file in the state dir, or the log store? The log store has query, filtering and retention already; a separate file is simpler to hand to a maintainer. - Should a miss record capture the query text? It is the useful part and it is also the most sensitive thing in the file. Local-only mitigates it; an explicit opt-out setting is probably still required.
- Does
mcpx registry addverifying a server by starting it constitute running untrusted code before the user consented? Almost certainly — the consent has to come before the first launch, not after. - Is there a registry field for "official/verified"? The
io.github.*versuscom.*/ai.*namespacing implies provenance but does not assert maintenance. Partly answered: per entry,/v0/serversreturns_meta["io.modelcontextprotocol.registry/official"]with a lifecyclestatus(e.g.active) and dates — registry lifecycle, not a quality or verification signal. - Should mcpx ever propose self-hosting a remote server automatically (pull the package, run it locally, rewrite the config, keep the credential)? Attractive and a large step; the rollback story if the local one is worse must exist first.
- For Google Drive specifically: with no maintained server, is a Google Drive OpenAPI declaration (Drive API v3 publishes a discovery document) the better answer? Probably, and it generalises to every Google API at once.
Ease · Impact · Related
Ease M (S for richer metadata + the four example declarations — registry dedup struck, see #179; M for mcpx registry add end-to-end and the doctor recommendation; M for the feedback/miss store) · Impact medium-high — the doctor recommendation and the miss log are the parts that keep paying; the four servers are a day's config each once adapters are the route.
Depends on / related: #179 (registry search gaps: unreachable registry.pageSize, dropped nextCursor; disproved the dedup premise), #6 (event store, for miss records), #76 (ops/CLI parity for any new operation), #5 (config chain, for add scope). Siblings: #114 (toolViews.from is what an alias over a real tailscale MCP server would need; adapter/OpenAPI generation is the recommended route for all four), #109 (a miss is a search that found nothing — the two share the record), #113 (intent --scope ops is what acts on the feedback), #110.
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-861
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#115 (verbatim, oldest first):
@dezren39 · 2026-09-30T07:21:55Z
Integration pass. Placed in the DAG rooted at #181.
d956689tod460fcc#109 Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110 Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112 Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114@dezren39 · 2026-09-30T07:29:28Z
Integration pass — the registry-deduplication premise in Approach B is disproved. Strike item 2.
Verified at
8001f23and written up in #179.internal/registry/registry.go:158setsversion=latestunconditionally on every search, and every caller reaches the registry throughthat one query builder (
internal/cli/registry.go:38,221,internal/daemon/ops.go:287). Fivelive searches returned 3/3, 7/7, 19/19, 50/50 and 11/11 distinct names — zero duplicates.
The large duplicate counts are real but belong to the un-pinned query, which mcpx never issues:
without
version=latest,filesystemreturns 90 rows for 11 distinct names, a maximum of 72repeats of one package. That is almost certainly where the "up to nine times" figure came from.
Item 1 of Approach B — surfacing the registry metadata that is already fetched in search
output — is untouched by this and is still worth doing. Only the dedup half is obsolete.
Two genuine defects were found in the same 400 lines and are filed in #179 instead:
registry.pageSizeis consulted only insideif limit <= 0, so no ordinary caller can reach it;and
nextCursoris parsed off the response and dropped, so search silently truncates at one page.Tracked in the DAG at #181 · this issue sits under #176.
@dezren39 · 2026-09-30T11:57:50Z
Issues pass (2026-09-30, at 05c78b2).
Parent: #176.Searchpinsversion=latest(internal/registry/registry.go:158) and mcpx never sees duplicates. The "several times under different versions" sentence in the registry section now says it describes the un-pinned raw query. The Ease note drops "registry dedup"; still M / medium-high, and Nix Playwright E2E suite fails after vendoring dependencies #176 matches.mcpx connectdoes not exist. The command ismcpx registry search|show|add(internal/cli/registry.go:15;addprints or--writes an entry and lists required variables,:92-124). Item 3 and the open question now build onmcpx registry add._metais decoded (registry.go:137-146) and dropped (:168-169). Live, it carriesio.modelcontextprotocol.registry/officialwithstatus,publishedAt,updatedAtandisLatest. That partly answers the "official/verified" open question: it is a lifecycle status, not a quality signal.Related:adds Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179 and names siblings by number (Bump build/buck/preludes/buck2-prelude fromd956689tod460fcc#109 Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110 Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114). Labeldesignadded.@dezren39 · 2026-10-28T22:35:58Z
Triage verdict (task 2162, repo-health-nix-pilot): PARTIALLY LANDED + CONFIRMED remainder, RELOCATED — a feedback store with ranking influence exists in the new home, but it is not the channel this issue asked for, and none of the four servers has been added. mcpx-side routes in developing-today/code; no fix packet in this repo.
Verified against current main on both sides (nix
224c7b738e88c7a8e5d406987a7d88257e229db2, coded2cb60fe8e08cd6fee149b930187b610299c1fa7):enhancement,design— no hard-stop labels. Parent tracker Nix Playwright E2E suite fails after vendoring dependencies #176 is OPEN.pkgs/mcpxat HEAD; the extraction plan (planning/plans/mcpx-extraction.md, steps 4–5, lab-ops-hub container crawler accepts inet_aton IPv4 spellings (127.1, 2130706433, 0x7f.1) — loopback SSRF bypass in validate_crawl_url #468) records the build switch and deletion done 2026-10-19, and this repo now only builds mcpx from the pinned code rev.logstore.FeedbackStore(pkgs/mcpx/internal/logstore/feedback.go) persists interaction records with execution/retrieval scores in SQLite;POST /v1/feedback(internal/api/ops.go:651, "Submit quality feedback for a trace… for adaptive routing") attaches scores to a trace; interactions are recorded from the proxy and daemon paths (internal/daemon/routes_proxy.go:200,256,server.go:920); and the scores actually move ranking —SearchSemanticappliesToolFeedbackAdjustmentmultipliers (internal/daemon/registry.go:559-560). "mcpx measures and does nothing with it" is no longer true of call outcomes.logstore, the feedback routes, or the search path records a miss (the store records interactions and caller-submitted scores, not empty searches); (b) a "you should add this / host this locally, the public one is slow" request channel — there is no suggestion/request operation in the ops table, and the landed feedback targets a trace that already happened, not a capability that does not exist yet; (c) the "is there a better instance of this" answer built from the stats mcpx collects.mcpx.config.nix, and no shipped adapter spec in code — the issue's own cheapest proof, the ~15-linetailscaleCLI adapter exposinglistTailnet/listHostnames, does not exist in either repo (listTailnetappears nowhere). Per the issue's own conclusions, adding them is an adapter/openapi declaration plus handing a consequential account credential to it — a decision for the config owner, not a default to bundle (Approach A is the one it recommends against).Route: no
small_fixpacket in dezren39/nix. The mcpx-side remainder (search-miss record, request channel, better-instance ranking) belongs with the source in developing-today/code, referencing #115, via the #309 relocation pass; per the cross-repo rule, do not re-file it there. The four-server add stays a nix-side config decision for Drew when he wants one of them, with the tailscale adapter as the recommended first proof. #115 stays open on the nix side until then.dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 29, 2026
🤖 Agent note · done
Triage verdict — not a duplicate; scope confirmed on current main; split, best item enqueued first
Dedupe: no existing code issue covers this. #1982 (front codex-connectors for OAuth apps) and #1950 (OAuth authorization, 61 conformance rows) are adjacent to the four-servers half but are different work — neither records feedback/misses nor recommends from stats. Note a naming collision the follow-ups must respect:
mcpx feedbackalready exists (internal/cli/feedback.go) but it is trace scoring (retrieval/execution scores for a trace-id), not this issue's "you should add this" suggestion channel — the channel in item 3 below still does not exist.Scope check against current
pkgs/mcpxmain (2026-10-29, via GitHub API):aliasOffiltered namespaces, CLI adapters (internal/adapter) and OpenAPI wrapping (internal/openapi) all present as the issue describes — the adapter/OpenAPI route for the four servers is available today.GET /v1/statsper-server statistics present;internal/cli/doctor.gochecks cover runtime/git/settings/config/server commands — no stats-driven recommendation check exists.docs/ideas.md); the issue's ~15-line tailscale adapter spec remains unbuilt.mcpx feedbackcollision above).Split (issue stays open as the tracker):
feedbackcommand).Verification for the follow-up:
pkgs/mcpx: go test ./...via CI on its PR.25 remaining items
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
dezren39 commentedon Nov 4, 2026
agent-note:v1
state: picked up
queue: repo-health-code-pilot
task: 8142 (small_fix, worker repo-worker-code, lane code-n, direct execution lane)
by: repo-queue-worker-shift-n
at: 2026-11-04T02:25Z
Scope (task 8142, #1936 item 1 only): ship the tailscale adapter declaration from the issue body —
paths.adaptersspec over the localtailscaleCLI exposing onlylistTailnetandlistHostnames(tailscale status --json, json: true), no auth (the local CLI session is the credential). Fresh revalidation: issue #1936 OPEN, no hard-stop labels, no open PR for this item (PR #2597 was the separate doctor item, merged). Dropbox/Drive/Outlook declarations and the feedback loop are NOT in this task. Branch: queue/8142-1936-tailscale-adapter.Merge pull request #5245 from developing-today/queue/8142-1936-tailsc…
dezren39 commentedon Nov 4, 2026
agent-note:v1
state: done
queue: repo-health-code-pilot
task: 8142 (small_fix, worker repo-worker-code, lane code-n, direct execution lane)
by: repo-queue-worker-shift-n
at: 2026-11-04T02:12Z
Done: PR #5245 merged (merge commit 6a1a351) — ships the tailscale adapter declaration for #1936 item 1:
pkgs/mcpx/examples/tailscale.json(spec over the localtailscaleCLI, exactlylistTailnet+listHostnames, bothstatus --jsonwith json: true, no credential — the CLI's existing session is the auth), pinned byTestShippedTailscaleAdapterDeclarationinpkgs/mcpx/internal/cli/adapter_shipped_test.go, documented indocs/configuration.md.Verified before merge: targeted tests pass on the laptop (
go test ./internal/cli/ -run TestShippedTailscaleAdapterDeclaration,go test ./internal/adapter/),mcpx adapter checkagainst the shipped file reports "1 adapters, all runnable", Codex review completed on the merged head 82de3aa with no findings. The two guard checks were still queued at merge (fleet runner congestion, #2605); the change's substance was verified directly, per the standing merge directive.Issue #1936 stays open: Dropbox/Drive/Outlook declarations (gated on PR #4637 per the task 7801 triage) and the feedback/miss loop remain.