Skip to content

Add initial experiments from latest fork implementations of Goose (host application) and GitHub MCP server - #125

Open
olaservo wants to merge 6 commits into
mainfrom
feature/goose-sep2640-findings
Open

Add initial experiments from latest fork implementations of Goose (host application) and GitHub MCP server#125
olaservo wants to merge 6 commits into
mainfrom
feature/goose-sep2640-findings

Conversation

@olaservo

Copy link
Copy Markdown
Member

Adds a simple test harness and initial results from running a modified version of Goose loading skills from a forked GitHub MCP server.

Also adds diagrams for the fork implementations used in this experiment:

  • Goose: documents the skills-over-mcp implementation path alongside existing paths for tools, resources, and file-based skills
  • GitHub MCP Server: similarly to above - documents the skills-over-mcp implementation path alongside tools and other resources

Note that these are still experimental and will probably change before being released.

olaservo and others added 6 commits August 16, 2026 18:47
Clean-slate restart of the experiments tree, goose host only. One
single-file runner records wire-level discoverability (capability
declaration + skills/list probe), model-level discoverability (skill
names enumerated from instructions), and usage (tool calls, skills
loaded, resources read), with optional expect checks. Two scenarios
(name load, URI load) pass against github/github-mcp-server#3046 with
goose branch skills-sep-2640-port; first results committed.

Earlier multi-host harnesses remain on feature/resource-sep-early-findings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: olaservo <olahungerford@gmail.com>
Both sides moved to the b405ba5 resources contract ({uri, digest, size}
or "dynamic", resultType on 2026-07-28+ sessions). The harness now
records protocolVersion, resultType, and per-entry size on the wire
probe, adds a resources_sized expectation, and grades `loaded` on the
`# Loaded Skill:` frame in the tool result rather than on the call
being made.

First rerun failed: goose's upstream OAuthStepUpClient wrapper did not
forward skills_list/skills_get/directory_read, so every streamable HTTP
server reported "Transport closed". Fixed in goose at fdf9ae6c; both
scenarios pass against github-mcp-server feature/agent-skills-v2 at
7d4ae593. Results from the older builds are dropped.

Adds the goose and github-mcp-server surface diagrams, and a
check-diagram skill that verifies a diagram's claims against the tip of
the branch its README names.

Claude-Session: https://claude.ai/code/session_017L3xguMgzVZQNrzu2AvKX2
Signed-off-by: olaservo <olahungerford@gmail.com>
Claude-Session: https://claude.ai/code/session_017L3xguMgzVZQNrzu2AvKX2
Signed-off-by: olaservo <olahungerford@gmail.com>
Claude-Session: https://claude.ai/code/session_017L3xguMgzVZQNrzu2AvKX2
Signed-off-by: olaservo <olahungerford@gmail.com>
…pace

Three scenarios against https://olaservo-skills-over-mcp-demo.hf.space/mcp:
discovery + load, the unlisted skill reached through the server's
instructions pointer and skills/get, and a supporting file loaded through
the digest + size gate. All pass with goose fdf9ae6c.

Harness: bearer_cmd is now opt-in (absent means no Authorization header),
a resources_read expectation, tool lines with an owning extension
("▸ read_resource extensionmanager") are parsed, and `loaded` accepts the
"# Loaded:" supporting-file frame.

Claude-Session: https://claude.ai/code/session_017L3xguMgzVZQNrzu2AvKX2
Signed-off-by: olaservo <olahungerford@gmail.com>
…arness

Same goose (fdf9ae6c) and server (7d4ae593); both scenarios pass.

Claude-Session: https://claude.ai/code/session_017L3xguMgzVZQNrzu2AvKX2
Signed-off-by: olaservo <olahungerford@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Goose-based scenario harness and results for exercising SEP-2640 skills served by the GitHub MCP server and a public demo server.

Changes:

  • Adds scenarios and a Python runner for discovery, loading, and supporting files.
  • Records initial experiment results.
  • Documents host/server flows with READMEs and diagrams.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
experiments/README.md Introduces the experiment suite and servers.
experiments/sep-2640-github-mcp-server-surfaces.svg Diagrams GitHub MCP server skill surfaces.
experiments/goose/README.md Documents the Goose harness and scenario format.
experiments/goose/sep-2640-goose-surfaces.svg Diagrams Goose skill discovery and loading.
experiments/goose/run_scenario.py Implements probing, execution, parsing, and checks.
experiments/goose/scenarios/uri-load.yaml Tests loading by URI.
experiments/goose/scenarios/discovery-and-load.yaml Tests GitHub skill discovery and loading.
experiments/goose/scenarios/demo-unlisted-skill.yaml Tests an unlisted skill.
experiments/goose/scenarios/demo-supporting-file.yaml Tests supporting-file loading.
experiments/goose/scenarios/demo-discovery-and-load.yaml Tests public demo discovery and loading.
experiments/goose/results/uri-load.20260827-190213.json Records URI-loading results.
experiments/goose/results/discovery-and-load.20260827-190206.json Records GitHub discovery results.
experiments/goose/results/demo-unlisted-skill.20260825-205215.json Records unlisted-skill results.
experiments/goose/results/demo-supporting-file.20260825-205332.json Records supporting-file results.
experiments/goose/results/demo-discovery-and-load.20260825-205208.json Records demo discovery results.
Suppressed comments (4)

experiments/goose/run_scenario.py:51

  • The probe sends skills/list without completing the MCP initialization lifecycle. After initialize, an HTTP client must send notifications/initialized, retain any returned MCP-Session-Id, and include both that session ID and the negotiated MCP-Protocol-Version on subsequent requests. A conforming stateful server may reject the current probe even though these two stateless demo servers accept it.
    init = rpc(endpoint, token, "initialize", {
        "protocolVersion": "2026-07-28",
        "capabilities": {},
        "clientInfo": {"name": "sep2640-harness", "version": "0"},
    }, 1)

experiments/goose/run_scenario.py:188

  • The subprocess return code is discarded, so a Goose crash can still produce a passing harness result when the configured checks are wire-only (or empty, which the documented scenario format permits). Return and record proc.returncode, and include a mandatory successful-process check in result["passed"].
        env=env,
        capture_output=True,
        timeout=600,
    )
    return (proc.stdout + proc.stderr).decode("utf-8", "replace")

experiments/goose/run_scenario.py:252

  • A substring search does not prove the model enumerated the skill. In these scenarios the loaded skill name also appears in the load_skill transcript and later prose, so this check can pass even when that name was omitted from the requested list. Match a standalone enumeration line (or parse assistant reply segments) instead.
        check(f"enumerated by model: {name}", name in output, "searched reply text")

experiments/goose/run_scenario.py:58

  • The 16-page guard silently returns a truncated catalog when a valid server has another cursor. That can make discovery checks and recorded results incomplete while still reporting success. Keep the safety bound, but fail explicitly when nextCursor remains after the final allowed page.
        while page < 16:

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +37 to +41
raw = urllib.request.urlopen(req, timeout=30).read().decode("utf-8", "replace")
for line in raw.splitlines():
if line.startswith("data: "):
raw = line[len("data: "):]
break

![Skills, MCP-served skills, MCP resources, and MCP tools in goose](sep-2640-goose-surfaces.svg)

How goose (`skills-sep-2640-port`) exposes SEP-2640 to the model: local and MCP-served skills share one prompt list and one `load_skill` tool that routes by origin; MCP loads pass through the verification gate (sha256 + size per file, frontmatter identity, unlisted-file refusal, one `skills/get` retry); `read_resource` reads raw content from any server with no verification or skill activation; prefixed MCP tools pass straight through to `tools/call`. `"dynamic"` entries skip the gate.

- A goose build with skills-over-MCP support: branch `skills-sep-2640-port` of https://github.com/olaservo/goose (`cargo build -p goose-cli`). Point the harness at the binary with `--goose` or `GOOSE_BIN`. Use `fdf9ae6c` or later: the 2026-08-21/24 upstream merges left `OAuthStepUpClient` without `skills_list`/`skills_get`/`directory_read` forwarding, so every streamable HTTP server reported `Transport closed`.
- A running SEP-2640 server. Reference: draft PR [github/github-mcp-server#3046](https://github.com/github/github-mcp-server/pull/3046), branch `olaservo:feature/agent-skills-v2` (`09ea2f9f` or later for the b405ba5 `size`/`"dynamic"` contract) — `go build -o github-mcp-server-skills.exe ./cmd/github-mcp-server`, then `./github-mcp-server-skills.exe http --port 8082`. The harness never starts the server; it connects to the scenario's `mcp_server.endpoint`.
- Auth: when the scenario sets `mcp_server.bearer_cmd`, it is run once and its output sent as a `Authorization: Bearer …` header by both the wire probe and goose. Omit it for unauthenticated servers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants