cocoon-mcp 0.4.0a4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. cocoon_mcp-0.4.0a4/.github/workflows/build-agent-contexts.yml +57 -0
  2. cocoon_mcp-0.4.0a4/.gitignore +12 -0
  3. cocoon_mcp-0.4.0a4/PKG-INFO +124 -0
  4. cocoon_mcp-0.4.0a4/README.md +106 -0
  5. cocoon_mcp-0.4.0a4/data/registry.json +97423 -0
  6. cocoon_mcp-0.4.0a4/docs/postmortems/2026-05-19-hermes-telegram-flight-search.md +225 -0
  7. cocoon_mcp-0.4.0a4/pyproject.toml +43 -0
  8. cocoon_mcp-0.4.0a4/scripts/build_agent_contexts.py +304 -0
  9. cocoon_mcp-0.4.0a4/scripts/e2e_smoke.py +144 -0
  10. cocoon_mcp-0.4.0a4/skill/SKILL.md +212 -0
  11. cocoon_mcp-0.4.0a4/skill/sources.json +22 -0
  12. cocoon_mcp-0.4.0a4/src/cocoon/__init__.py +12 -0
  13. cocoon_mcp-0.4.0a4/src/cocoon/__main__.py +4 -0
  14. cocoon_mcp-0.4.0a4/src/cocoon/agent_context.py +162 -0
  15. cocoon_mcp-0.4.0a4/src/cocoon/argv.py +70 -0
  16. cocoon_mcp-0.4.0a4/src/cocoon/auth.py +59 -0
  17. cocoon_mcp-0.4.0a4/src/cocoon/catalog.py +395 -0
  18. cocoon_mcp-0.4.0a4/src/cocoon/cli.py +468 -0
  19. cocoon_mcp-0.4.0a4/src/cocoon/data/dev_catalog.json +133 -0
  20. cocoon_mcp-0.4.0a4/src/cocoon/errors.py +40 -0
  21. cocoon_mcp-0.4.0a4/src/cocoon/materialize.py +180 -0
  22. cocoon_mcp-0.4.0a4/src/cocoon/paths.py +40 -0
  23. cocoon_mcp-0.4.0a4/src/cocoon/sandbox/__init__.py +40 -0
  24. cocoon_mcp-0.4.0a4/src/cocoon/sandbox/linux.py +65 -0
  25. cocoon_mcp-0.4.0a4/src/cocoon/sandbox/macos.py +63 -0
  26. cocoon_mcp-0.4.0a4/src/cocoon/sandbox/policy.py +20 -0
  27. cocoon_mcp-0.4.0a4/src/cocoon/search.py +73 -0
  28. cocoon_mcp-0.4.0a4/src/cocoon/server.py +219 -0
  29. cocoon_mcp-0.4.0a4/tests/conftest.py +24 -0
  30. cocoon_mcp-0.4.0a4/tests/test_agent_context.py +157 -0
  31. cocoon_mcp-0.4.0a4/tests/test_argv.py +76 -0
  32. cocoon_mcp-0.4.0a4/tests/test_auth.py +50 -0
  33. cocoon_mcp-0.4.0a4/tests/test_catalog.py +286 -0
  34. cocoon_mcp-0.4.0a4/tests/test_cli.py +285 -0
  35. cocoon_mcp-0.4.0a4/tests/test_errors.py +34 -0
  36. cocoon_mcp-0.4.0a4/tests/test_materialize.py +112 -0
  37. cocoon_mcp-0.4.0a4/tests/test_paths.py +27 -0
  38. cocoon_mcp-0.4.0a4/tests/test_sandbox.py +62 -0
  39. cocoon_mcp-0.4.0a4/tests/test_search.py +34 -0
  40. cocoon_mcp-0.4.0a4/tests/test_server.py +176 -0
@@ -0,0 +1,57 @@
1
+ name: Build catalog registry
2
+
3
+ # Daily cron + manual trigger. Harvests each CLI's tools-manifest.json
4
+ # from printing-press-library, generates synthetic stubs for the ~30%
5
+ # of CLIs without a manifest, aggregates into data/registry.json at the
6
+ # repo root, and commits if changed.
7
+ #
8
+ # Cocoon's runtime fetches that file (default URL: raw.githubusercontent.com
9
+ # of cocoon's main branch; overridable via $COCOON_CATALOG_URL) and caches
10
+ # it locally with 24h TTL. The wheel doesn't ship the file — upstream
11
+ # refreshes propagate to users on their next cache expiry without
12
+ # requiring a cocoon release.
13
+ #
14
+ # Pure HTTP fetches, no Go toolchain, ~5s wall-clock for ~149 entries.
15
+
16
+ on:
17
+ schedule:
18
+ - cron: "17 6 * * *" # 06:17 UTC daily — off the hour to avoid cron pile-up
19
+ workflow_dispatch:
20
+
21
+ permissions:
22
+ contents: write
23
+
24
+ jobs:
25
+ build:
26
+ runs-on: ubuntu-latest
27
+ timeout-minutes: 10
28
+ concurrency:
29
+ group: build-catalog-registry
30
+ cancel-in-progress: false
31
+ steps:
32
+ - uses: actions/checkout@v5
33
+
34
+ - name: Set up Python + uv
35
+ uses: astral-sh/setup-uv@v7
36
+ with:
37
+ enable-cache: true
38
+
39
+ - name: Install cocoon deps
40
+ run: uv sync --extra dev
41
+
42
+ - name: Harvest catalog
43
+ run: |
44
+ uv run python scripts/build_agent_contexts.py
45
+ wc -c data/registry.json
46
+
47
+ - name: Commit if changed
48
+ run: |
49
+ if git diff --quiet data/registry.json; then
50
+ echo "no changes to data/registry.json"
51
+ exit 0
52
+ fi
53
+ git config user.name "github-actions[bot]"
54
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
55
+ git add data/registry.json
56
+ git commit -m "data: refresh catalog registry [skip ci]"
57
+ git push
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ .mypy_cache/
9
+ .venv/
10
+ .coverage
11
+ htmlcov/
12
+ uv.lock
@@ -0,0 +1,124 @@
1
+ Metadata-Version: 2.4
2
+ Name: cocoon-mcp
3
+ Version: 0.4.0a4
4
+ Summary: Execution runtime for named third-party APIs: one MCP tool that calls 140+ printing-press CLIs on demand, sandboxed per call, with per-API auth scoping and readiness-aware discovery.
5
+ Project-URL: Repository, https://github.com/vu1n/cocoon
6
+ Project-URL: Skill, https://github.com/vu1n/cocoon/tree/main/skill
7
+ Project-URL: Issues, https://github.com/vu1n/cocoon/issues
8
+ Author: vu1n
9
+ License: MIT
10
+ Keywords: agent,claude,mcp,printing-press,sandbox
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: httpx>=0.27
13
+ Requires-Dist: mcp>=1.2
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
16
+ Requires-Dist: pytest>=8.0; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # cocoon
20
+
21
+ One MCP tool (and matching CLI) that lets an agent discover, auto-install, sandbox, and call any API in the [printing-press](https://github.com/mvanhorn/cli-printing-press) corpus — without per-API install steps, without per-API MCP server fan-out.
22
+
23
+ The agent-facing protocol is documented in [`skill/SKILL.md`](skill/SKILL.md). This repo holds both the runtime and the skill that ships with it.
24
+
25
+ ## What it does
26
+
27
+ Register cocoon once with your MCP host. The agent then sees a **single tool**, `cocoon(action, ...)`, that multiplexes four operations:
28
+
29
+ ```python
30
+ cocoon(action="find", query="create a linear issue")
31
+ cocoon(action="describe", api="linear", tool="issues.create")
32
+ cocoon(action="call", api="linear", tool="issues.create",
33
+ args={"title": "x", "team_id": "y"})
34
+ cocoon(action="list", filter="payments")
35
+ ```
36
+
37
+ On first `call` for any API, cocoon downloads the per-platform prebuilt `<api>-pp-cli` binary from printing-press-library's GitHub release (tag `<api>-current`), caches it under `~/.cache/cocoon/bin/<api>/`, and executes it in a per-call sandbox (bubblewrap on Linux, Seatbelt on macOS) with only that API's credentials scoped into the environment. The agent never takes a separate install step.
38
+
39
+ The CLI mirrors the same operations as subcommands for terminal use:
40
+
41
+ ```sh
42
+ cocoon find "create a linear issue"
43
+ cocoon describe linear issues.create
44
+ cocoon call linear issues.create --arg title=x --arg team_id=y
45
+ cocoon list --filter payments
46
+ ```
47
+
48
+ ## Install
49
+
50
+ ```sh
51
+ # `cocoon-mcp` is the PyPI distribution name; `cocoon` is the installed CLI.
52
+ uvx --from cocoon-mcp cocoon init # register via `claude mcp add`
53
+ uvx --from cocoon-mcp cocoon doctor # check sandbox + catalog state
54
+ uvx --from cocoon-mcp cocoon auth linear --token lin_… # write per-API credentials
55
+ ```
56
+
57
+ For a local install pointing at a checkout instead of PyPI:
58
+
59
+ ```sh
60
+ cocoon init --command "$(which cocoon) serve"
61
+ # or, running from the repo:
62
+ cocoon init --command "uv run --directory /path/to/cocoon cocoon serve"
63
+ ```
64
+
65
+ `cocoon init` shells out to `claude mcp add cocoon --scope user`, which writes the user-scope entry to `~/.claude.json`. (Older `~/.claude/mcp.json` is not read by modern Claude Code.) For other MCP hosts, use `cocoon init --print` to get both a shell command and a JSON snippet.
66
+
67
+ **Requirements**: Python 3.11+, network access to GitHub Releases (cocoon downloads `<api>-pp-cli` binaries on first use), and `bubblewrap` (Linux) or `sandbox-exec` (built-in macOS) for execution sandboxing. `cocoon init` additionally needs the `claude` CLI on PATH. **No Go toolchain required** — prebuilt binaries are downloaded directly from upstream's release artifacts.
68
+
69
+ ### Bash-fallback mode
70
+
71
+ If the MCP cocoon tool is unavailable for any reason (host-side misregistration, server restart-in-progress, hermes terminal-only mode), the agent can fall back to invoking the `cocoon` CLI directly via its terminal tool. Set `COCOON_AGENT_MODE=1` in the subprocess env to get structured JSON on stdout and stderr instead of human-formatted text — including argparse-level errors as `{"error": "invalid_arguments", ...}` rather than free-text "the following arguments are required". The agent can branch on stable error codes instead of grepping stderr.
72
+
73
+ ## Layout
74
+
75
+ ```
76
+ src/cocoon/
77
+ server.py MCP server: one `cocoon` tool dispatching on action
78
+ cli.py cocoon {serve, init, auth, doctor, catalog, find, describe, call, list}
79
+ catalog.py catalog fetch, BM25 search, list/describe, auth_type lookup
80
+ search.py BM25 ranker (vendored, ~30 lines)
81
+ materialize.py download prebuilt `<api>-pp-cli` from GitHub Releases, cache under bin/
82
+ auth.py per-API JSON credential files at ~/.cache/cocoon/auth/
83
+ argv.py dict -> CLI argv translation (dotted tool names → cobra subcommands)
84
+ paths.py centralized cache-path resolution (no side effects)
85
+ errors.py structured error types matching the skill's failure modes
86
+ sandbox/
87
+ policy.py SandboxPolicy dataclass
88
+ linux.py bubblewrap execution
89
+ macos.py Seatbelt (sandbox-exec) execution
90
+ __init__.py platform dispatch + doctor probe
91
+
92
+ skill/
93
+ SKILL.md agent-facing protocol (what the model reads to learn cocoon)
94
+ sources.json upstream attributions for drift tracking
95
+
96
+ scripts/
97
+ e2e_smoke.py 4-scenario end-to-end test against the real installed CLI
98
+
99
+ tests/ unit tests; no external deps (catalog/auth/sandbox/argv/CLI)
100
+ ```
101
+
102
+ ## Development
103
+
104
+ ```sh
105
+ uv sync --extra dev
106
+ uv run pytest # ~90 unit tests
107
+ uv run python scripts/e2e_smoke.py # end-to-end against hackernews
108
+ ```
109
+
110
+ The e2e script installs `hackernews-pp-cli` if missing (~20s on first run), then exercises the four scenarios: installed/direct, installed-via-discovery, uninstalled-via-discovery, uninstalled-via-direct-call.
111
+
112
+ ## Status
113
+
114
+ v0.4 candidate — single-tool MCP shape, seamless prebuilt-binary install (~2–3s cold-start vs the ~20s `go install` of v0.3), full CLI mirror, 145 unit tests, e2e proven end-to-end against real GitHub Release downloads. The bundled catalog covers ~96 APIs (harvested from each CLI's published `tools-manifest.json`); a daily GitHub Action keeps it fresh.
115
+
116
+ Outstanding:
117
+
118
+ - ~39 CLIs in the upstream library lack a `tools-manifest.json` (hand-rolled CLIs without OpenAPI input). They're hidden from `find`/`list` via the installability filter. A Phase-2 build path running `<binary> agent-context` post-install could backfill them.
119
+ - Upstream doesn't publish `checksums.txt` alongside release binaries (goreleaser is configured for it but the upload step is missing). cocoon relies on GitHub-HTTPS trust today; an upstream PR adding the checksum upload would let cocoon do sha256 verification.
120
+ - `cocoon prefetch` subcommand + activity-mining for warm caches before the agent asks — postmortem P2.
121
+ - Calibrated `COCOON_FIND_MIN_SCORE` floor once we have real query logs.
122
+ - Egress allowlist via outbound proxy (Claude Code pattern) — v1.1.
123
+ - Bring-your-own-OpenAPI-spec registration — v1.1 with codegen sandboxing.
124
+ - The `npx -y @mvanhorn/printing-press install` shortcut is upstream-broken (registry validation fails on a malformed entry); not relevant for cocoon anymore since we don't shell out to npx or `go install`.
@@ -0,0 +1,106 @@
1
+ # cocoon
2
+
3
+ One MCP tool (and matching CLI) that lets an agent discover, auto-install, sandbox, and call any API in the [printing-press](https://github.com/mvanhorn/cli-printing-press) corpus — without per-API install steps, without per-API MCP server fan-out.
4
+
5
+ The agent-facing protocol is documented in [`skill/SKILL.md`](skill/SKILL.md). This repo holds both the runtime and the skill that ships with it.
6
+
7
+ ## What it does
8
+
9
+ Register cocoon once with your MCP host. The agent then sees a **single tool**, `cocoon(action, ...)`, that multiplexes four operations:
10
+
11
+ ```python
12
+ cocoon(action="find", query="create a linear issue")
13
+ cocoon(action="describe", api="linear", tool="issues.create")
14
+ cocoon(action="call", api="linear", tool="issues.create",
15
+ args={"title": "x", "team_id": "y"})
16
+ cocoon(action="list", filter="payments")
17
+ ```
18
+
19
+ On first `call` for any API, cocoon downloads the per-platform prebuilt `<api>-pp-cli` binary from printing-press-library's GitHub release (tag `<api>-current`), caches it under `~/.cache/cocoon/bin/<api>/`, and executes it in a per-call sandbox (bubblewrap on Linux, Seatbelt on macOS) with only that API's credentials scoped into the environment. The agent never takes a separate install step.
20
+
21
+ The CLI mirrors the same operations as subcommands for terminal use:
22
+
23
+ ```sh
24
+ cocoon find "create a linear issue"
25
+ cocoon describe linear issues.create
26
+ cocoon call linear issues.create --arg title=x --arg team_id=y
27
+ cocoon list --filter payments
28
+ ```
29
+
30
+ ## Install
31
+
32
+ ```sh
33
+ # `cocoon-mcp` is the PyPI distribution name; `cocoon` is the installed CLI.
34
+ uvx --from cocoon-mcp cocoon init # register via `claude mcp add`
35
+ uvx --from cocoon-mcp cocoon doctor # check sandbox + catalog state
36
+ uvx --from cocoon-mcp cocoon auth linear --token lin_… # write per-API credentials
37
+ ```
38
+
39
+ For a local install pointing at a checkout instead of PyPI:
40
+
41
+ ```sh
42
+ cocoon init --command "$(which cocoon) serve"
43
+ # or, running from the repo:
44
+ cocoon init --command "uv run --directory /path/to/cocoon cocoon serve"
45
+ ```
46
+
47
+ `cocoon init` shells out to `claude mcp add cocoon --scope user`, which writes the user-scope entry to `~/.claude.json`. (Older `~/.claude/mcp.json` is not read by modern Claude Code.) For other MCP hosts, use `cocoon init --print` to get both a shell command and a JSON snippet.
48
+
49
+ **Requirements**: Python 3.11+, network access to GitHub Releases (cocoon downloads `<api>-pp-cli` binaries on first use), and `bubblewrap` (Linux) or `sandbox-exec` (built-in macOS) for execution sandboxing. `cocoon init` additionally needs the `claude` CLI on PATH. **No Go toolchain required** — prebuilt binaries are downloaded directly from upstream's release artifacts.
50
+
51
+ ### Bash-fallback mode
52
+
53
+ If the MCP cocoon tool is unavailable for any reason (host-side misregistration, server restart-in-progress, hermes terminal-only mode), the agent can fall back to invoking the `cocoon` CLI directly via its terminal tool. Set `COCOON_AGENT_MODE=1` in the subprocess env to get structured JSON on stdout and stderr instead of human-formatted text — including argparse-level errors as `{"error": "invalid_arguments", ...}` rather than free-text "the following arguments are required". The agent can branch on stable error codes instead of grepping stderr.
54
+
55
+ ## Layout
56
+
57
+ ```
58
+ src/cocoon/
59
+ server.py MCP server: one `cocoon` tool dispatching on action
60
+ cli.py cocoon {serve, init, auth, doctor, catalog, find, describe, call, list}
61
+ catalog.py catalog fetch, BM25 search, list/describe, auth_type lookup
62
+ search.py BM25 ranker (vendored, ~30 lines)
63
+ materialize.py download prebuilt `<api>-pp-cli` from GitHub Releases, cache under bin/
64
+ auth.py per-API JSON credential files at ~/.cache/cocoon/auth/
65
+ argv.py dict -> CLI argv translation (dotted tool names → cobra subcommands)
66
+ paths.py centralized cache-path resolution (no side effects)
67
+ errors.py structured error types matching the skill's failure modes
68
+ sandbox/
69
+ policy.py SandboxPolicy dataclass
70
+ linux.py bubblewrap execution
71
+ macos.py Seatbelt (sandbox-exec) execution
72
+ __init__.py platform dispatch + doctor probe
73
+
74
+ skill/
75
+ SKILL.md agent-facing protocol (what the model reads to learn cocoon)
76
+ sources.json upstream attributions for drift tracking
77
+
78
+ scripts/
79
+ e2e_smoke.py 4-scenario end-to-end test against the real installed CLI
80
+
81
+ tests/ unit tests; no external deps (catalog/auth/sandbox/argv/CLI)
82
+ ```
83
+
84
+ ## Development
85
+
86
+ ```sh
87
+ uv sync --extra dev
88
+ uv run pytest # ~90 unit tests
89
+ uv run python scripts/e2e_smoke.py # end-to-end against hackernews
90
+ ```
91
+
92
+ The e2e script installs `hackernews-pp-cli` if missing (~20s on first run), then exercises the four scenarios: installed/direct, installed-via-discovery, uninstalled-via-discovery, uninstalled-via-direct-call.
93
+
94
+ ## Status
95
+
96
+ v0.4 candidate — single-tool MCP shape, seamless prebuilt-binary install (~2–3s cold-start vs the ~20s `go install` of v0.3), full CLI mirror, 145 unit tests, e2e proven end-to-end against real GitHub Release downloads. The bundled catalog covers ~96 APIs (harvested from each CLI's published `tools-manifest.json`); a daily GitHub Action keeps it fresh.
97
+
98
+ Outstanding:
99
+
100
+ - ~39 CLIs in the upstream library lack a `tools-manifest.json` (hand-rolled CLIs without OpenAPI input). They're hidden from `find`/`list` via the installability filter. A Phase-2 build path running `<binary> agent-context` post-install could backfill them.
101
+ - Upstream doesn't publish `checksums.txt` alongside release binaries (goreleaser is configured for it but the upload step is missing). cocoon relies on GitHub-HTTPS trust today; an upstream PR adding the checksum upload would let cocoon do sha256 verification.
102
+ - `cocoon prefetch` subcommand + activity-mining for warm caches before the agent asks — postmortem P2.
103
+ - Calibrated `COCOON_FIND_MIN_SCORE` floor once we have real query logs.
104
+ - Egress allowlist via outbound proxy (Claude Code pattern) — v1.1.
105
+ - Bring-your-own-OpenAPI-spec registration — v1.1 with codegen sandboxing.
106
+ - The `npx -y @mvanhorn/printing-press install` shortcut is upstream-broken (registry validation fails on a malformed entry); not relevant for cocoon anymore since we don't shell out to npx or `go install`.