gantree

Custom MCP servers

The Tools grid is the yard catalog (search, math, maps, …). A custom server is still a first-class grant: it is a [[server]] in that crane’s mcp.toml. There is no /mcp/add?url= route.

Chat stays Telegram. Gantree only writes files and runs gantry tools-fetch.


A. Build one — clone an existing MCP

Do not start from a blank Go module. Fork or copy a sibling that already speaks stdio, ships a static binary, and prints shape.

You need Clone this Why
No secrets mcp-go-math Smallest: evaluate + convert, empty env_keys
One API key google-maps-mcp host-manifest + GOOGLE_MAPS_API_KEY
OAuth hop go-strava-mcp auth_args + PKCE paste (url / exchange)

Keep:

Rename name / command / tool prefixes. Do not reuse maps or math.

host-manifest (required)

The binary must exit 0 and print one JSON object on stdout:

CGO_ENABLED=0 go run . host-manifest
{
  "name": "rentals",
  "command": "rentals-search-mcp",
  "env_keys": ["RENTCAST_API_KEY"],
  "blurb": "US listings. One RentCast key."
}

Optional fields: args, auth_args, auth_flow (pkce | device | mfa), home_only, download_url, download_tag. First arg host-manifest must not start the stdio server.

If the tool needs a browser hop, implement the same auth argv as ai-gantry auth.md and set auth_args (e.g. ["auth"]). Static keys stay in .env — never /auth rentals <apikey>.

Publish a GitHub release so tools-fetch can GET the tarball.


B. Define it for gantree

Hand-edit that crane’s gantries/<slug>/mcp.toml. Listed = granted.

[[server]]
name = "rentals"
command = "rentals-search-mcp"
env_keys = ["RENTCAST_API_KEY"]
download_tag = "latest"
download_url = "https://github.com/you/rentals-search-mcp/releases/download/{tag}/rentals-search-mcp_{version}_{os}_{arch}.tar.gz"
# auth_args = ["auth"]   # only if the binary has an OAuth/login hop

Placeholders in download_url: {tag} {version} {os} {arch}. download_tag = "latest" only works when the URL is https://github.com/<owner>/<repo>/….

Then on the crane dashboard:

  1. Put required keys in the crane .env (Secrets lists catalog env_keys, plus any env_keys you wrote on that [[server]])
  2. recreate — fetches bins into /data/bin, prunes leftovers not in mcp.toml, reloads MCP (PATH includes /data/bin). The tools-fetch button is the same install, without reload.

Doctor / skip hints follow missing env and auth_args.

On a compose console the MCP binary is not on PATH, so gantree uses the last-known host-manifest shape until tools-fetch lands a bin. Live <binary> host-manifest still wins when it can run.

Yard catalog (optional)

The toggle grid reads lib/yard/tools/packages.ts. Add a row there if this yard should offer the server to every crane (name, command, GitHub downloadUrl, clone repo for go run . host-manifest). Shape still comes from the binary; last-known JSON is only a fallback when the console cannot run it. Do not invent keys in packages.ts.

Until that row exists, User B’s MCP will not appear as a checkbox — only as a [[server]] you wrote. Set env_keys on that server so Secrets grows the fields.