Public: anyone can read this; the crew can change it.

The here manifest's explore and search actions name the MCP argument q, so an agent calls the tool the way llms.txt says #9103

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/9098-the-here-manifest-s-explore-and-search-a → main 2 commits fork

  • Merged. scout/9098-the-here-manifest-s-explore-and-search-a was merged into main as ef4db5d.

Review

Sign in to review this change.
2 files changed +15 −0
src/actions/here.ts +5
@@ -45,6 +45,8 @@ export interface Action {
4545 readonly http?: string;
4646 /** The MCP tool that does the same, when there is one. */
4747 readonly mcp?: string;
48 /** The arguments that tool takes here, plain data (`{ q }` for a filter). */
49 readonly mcpArgs?: Readonly<Record<string, string>>;
4850 /** The shell command that does the same, when the forge's SSH is on. */
4951 readonly ssh?: string;
5052 /** `true`: needs an account the caller does not have; `false`: needs none. */
@@ -271,6 +273,7 @@ function pageRead(page: "explore" | "search", path: string): Action {
271273 do: `${page === "explore" ? "browse the forge" : "search the forge"}${q === "" ? "" : `: ${q.slice(0, 200)}`}`,
272274 http,
273275 mcp: page,
276 mcpArgs: { q: q.slice(0, 200) },
274277 };
275278 }
276279
@@ -288,11 +291,13 @@ function forgeActions(
288291 do: "explore apps and repositories",
289292 http: "GET /api/v1/explore?q=",
290293 mcp: "explore",
294 mcpArgs: { q: "" },
291295 },
292296 {
293297 do: "search issues, pulls, repositories and code",
294298 http: "GET /api/v1/search?q=",
295299 mcp: "search",
300 mcpArgs: { q: "" },
296301 },
297302 { do: "list public repositories", http: "GET /api/v1/repos" },
298303 {
test/here-manifest.test.ts +10
@@ -356,6 +356,16 @@ describe("the manifest: what you can do here, as who you are", () => {
356356 expect(other.actions[0].do).toBe("explore apps and repositories");
357357 });
358358
359 test("the explore and search actions name the MCP argument q", async () => {
360 const e = (await manifest("/explore?q=kind:app")).body;
361 expect(e.actions[0].mcpArgs).toEqual({ q: "kind:app" });
362 const long = (await manifest(`/search?q=${"x".repeat(300)}`)).body;
363 expect(long.actions[0].mcpArgs.q).toHaveLength(200);
364 const f = (await manifest("/")).body;
365 for (const tool of ["explore", "search"])
366 expect(f.actions.find((a: any) => a.mcp === tool).mcpArgs).toHaveProperty("q");
367 });
368
359369 test("it is small", async () => {
360370 for (const who of [undefined, "carol", "wes", "alice", "bot"]) {
361371 const res = await here("/acme/game", who);

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs