From d2e03903c58ddf09244e33a6437c41f9214bd30f Mon Sep 17 00:00:00 2001 From: Zachary Lyon Date: Fri, 11 Sep 2026 13:05:43 -0700 Subject: [PATCH] feat(pi): package scaffold and MCP registration (PF-3852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the `@tiny-fish/pi` package manifest so the Pi coding agent can install TinyFish with `pi install npm:@tiny-fish/pi`. Skills land in the next commit; this is the registration surface only. Three decisions worth reviewing here, all verified against pi 0.84.4 and pi-mcp-adapter 2.32.1: | Field | Why | |---|---| | `directTools` | The adapter routes everything through a single `mcp` proxy tool by default (`direct-tools.ts:182-205`). Without this the package registers zero visible tools. Eight named rather than `true`, matching what the skills call and the adapter's own 5-20 guidance; the other ~11 stay reachable via the proxy. | | `X-API-Key: "${TINYFISH_API_KEY}"` | Key-only. Any `headers` key disables the adapter's OAuth auto-detect (`mcp-auth-flow.ts:1075`), so this route has no browser sign-in. Deliberate; the CLI route covers OAuth. | | no `type: "http"` | `ServerEntry` has no `type` field, only `httpTransport`. A bare `url` already means HTTP. | Note the interpolation form: `${TINYFISH_API_KEY}`, not the `${VAR:-}` default syntax the Claude plugin uses. The adapter's regex is `/\$\{(\w+)\}/`, which does not match a trailing `:-`, so that form would ship as a literal header. `X-TF-Client-Name`/`X-TF-Client-Version` follow the convention in the root README. The MCP route does not read them today — it reads only `x-tf-request-origin`, while the client-name headers are consumed by the v1 REST routes — so they are inert for now and carried for when it does. Verified they do not disturb the connection: a live session still authenticates and returns results with them present. Because the version is hardcoded there, it duplicates package.json's with nothing keeping the two in step, and a release would silently keep reporting the previous version. Guarded by a new `pi-versions-match` job in plugin-manifests-ci.yml, the same shape as the existing marketplace check; negative-tested by bumping package.json and confirming the job fails. The MCP URL carries no attribution params. `connectSourceSchema` has no value meaning "shipped inside a package", and `connect_attempt_id` is an install-level UUID — one baked into a tarball would be identical for every install, collapsing the whole population into a single attempt. Matches what claude/ and grok/ ship. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01CBf5rnVYQYcxE8bLjfQuUP --- .github/workflows/plugin-manifests-ci.yml | 21 +++++++++++ README.md | 1 + pi/LICENSE | 21 +++++++++++ pi/mcp.json | 24 +++++++++++++ pi/package.json | 43 +++++++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 pi/LICENSE create mode 100644 pi/mcp.json create mode 100644 pi/package.json diff --git a/.github/workflows/plugin-manifests-ci.yml b/.github/workflows/plugin-manifests-ci.yml index a9d20ee..87ef3d2 100644 --- a/.github/workflows/plugin-manifests-ci.yml +++ b/.github/workflows/plugin-manifests-ci.yml @@ -7,12 +7,14 @@ on: - ".github/workflows/plugin-manifests-ci.yml" - ".claude-plugin/**" - "claude/**" + - "pi/**" push: branches: [main] paths: - ".github/workflows/plugin-manifests-ci.yml" - ".claude-plugin/**" - "claude/**" + - "pi/**" permissions: contents: read @@ -36,3 +38,22 @@ jobs: echo "::error file=.claude-plugin/marketplace.json::plugin entry is $entry but claude/.claude-plugin/plugin.json is $plugin" exit 1 fi + + pi-versions-match: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + # mcp.json hardcodes the version it reports as X-TF-Client-Version; nothing else keeps + # it in step with package.json, so a release would silently report the previous version. + - name: MCP client version matches the package version + run: | + set -euo pipefail + pkg=$(jq -re '.version' pi/package.json) + hdr=$(jq -re '.mcpServers.tinyfish.headers["X-TF-Client-Version"]' pi/mcp.json) + echo "package.json=$pkg mcp.json=$hdr" + if [ "$pkg" != "$hdr" ]; then + echo "::error file=pi/mcp.json::X-TF-Client-Version is $hdr but pi/package.json is $pkg" + exit 1 + fi diff --git a/README.md b/README.md index c1867d4..76d8710 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ TinyFish Web Agent provides AI-powered web automation using natural language ins | [LangChain](./langchain) | `langchain-tinyfish` — TinyFish Search, Fetch, Web Agent, and Browser as LangChain tools | | [Google ADK](./google-adk) | `tinyfish-adk` — TinyFish tools for the Google Agent Development Kit | | [Hermes](./hermes) | `tinyfish-hermes` — TinyFish Search and Fetch as a [Hermes Agent](https://github.com/NousResearch/Hermes-Agent) web provider plugin | +| [Pi](./pi) | `@tiny-fish/pi` — TinyFish skills and MCP server for the [Pi coding agent](https://pi.dev) | | [n8n](./n8n) | Community node for the [n8n](https://n8n.io) workflow automation platform | ## Contribution guidelines diff --git a/pi/LICENSE b/pi/LICENSE new file mode 100644 index 0000000..cede851 --- /dev/null +++ b/pi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 TinyFish + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pi/mcp.json b/pi/mcp.json new file mode 100644 index 0000000..26ea811 --- /dev/null +++ b/pi/mcp.json @@ -0,0 +1,24 @@ +{ + "mcpServers": { + "tinyfish": { + "url": "https://agent.tinyfish.ai/mcp", + "headers": { + "X-API-Key": "${TINYFISH_API_KEY}", + "X-TF-Client-Name": "pi", + "X-TF-Client-Version": "0.1.0" + }, + "directTools": [ + "search", + "fetch_content", + "run_web_automation", + "run_web_automation_async", + "get_run", + "cancel_run", + "batch_status", + "batch_cancel", + "create_browser_session", + "close_browser_session" + ] + } + } +} diff --git a/pi/package.json b/pi/package.json new file mode 100644 index 0000000..1fc2ee5 --- /dev/null +++ b/pi/package.json @@ -0,0 +1,43 @@ +{ + "name": "@tiny-fish/pi", + "version": "0.1.0", + "description": "TinyFish for the Pi coding agent — free web search and page reading, plus goal-driven browser automation on live and logged-in sites. Skills work standalone; the bundled MCP server activates if you also install pi-mcp-adapter.", + "license": "MIT", + "homepage": "https://docs.tinyfish.ai", + "repository": { + "type": "git", + "url": "git+https://github.com/tinyfish-io/tinyfish-web-agent-integrations.git", + "directory": "pi" + }, + "author": { + "name": "TinyFish", + "email": "support@tinyfish.io", + "url": "https://tinyfish.ai" + }, + "keywords": [ + "pi-package", + "tinyfish", + "web-agent", + "browser-automation", + "web-scraping", + "data-extraction", + "search", + "fetch" + ], + "files": [ + "skills", + "rules", + "mcp.json", + "README.md", + "LICENSE" + ], + "publishConfig": { + "access": "public" + }, + "pi": { + "mcp": "./mcp.json", + "skills": [ + "./skills" + ] + } +}