mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-21 13:04:18 +02:00
Publish FastMCP 4.0.0b1 docs to gofastmcp.com (#4695)
This commit is contained in:
parent
8cf4506aa9
commit
0747ce0bc1
220 changed files with 12093 additions and 8314 deletions
15
.github/workflows/marvin-dedupe-issues.yml
vendored
15
.github/workflows/marvin-dedupe-issues.yml
vendored
|
|
@ -19,6 +19,13 @@ jobs:
|
|||
issues: write
|
||||
id-token: write
|
||||
|
||||
# TEMPORARY PIN — see the matching note in marvin-label-triage.yml.
|
||||
# Claude Code 2.1.216 broke every Bash call under the action's subprocess
|
||||
# isolation, which this workflow needs for all of its `gh` searching.
|
||||
# https://github.com/anthropics/claude-code/issues/79997
|
||||
env:
|
||||
PINNED_CLAUDE_CODE_VERSION: "2.1.215"
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
|
@ -91,9 +98,17 @@ jobs:
|
|||
- name: Clean up stale Claude locks
|
||||
run: rm -rf ~/.claude/.locks ~/.local/state/claude/locks || true
|
||||
|
||||
- name: Install pinned Claude Code
|
||||
id: pin-claude
|
||||
run: |
|
||||
curl -fsSL https://claude.ai/install.sh | bash -s -- "$PINNED_CLAUDE_CODE_VERSION"
|
||||
echo "path=$HOME/.local/bin/claude" >> "$GITHUB_OUTPUT"
|
||||
"$HOME/.local/bin/claude" --version
|
||||
|
||||
- name: Run Marvin dedupe command
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
path_to_claude_code_executable: ${{ steps.pin-claude.outputs.path }}
|
||||
github_token: ${{ steps.marvin-token.outputs.token }}
|
||||
bot_name: "Marvin Context Protocol"
|
||||
prompt: ${{ steps.dedupe-prompt.outputs.PROMPT }}
|
||||
|
|
|
|||
63
.github/workflows/marvin-label-triage.yml
vendored
63
.github/workflows/marvin-label-triage.yml
vendored
|
|
@ -27,6 +27,22 @@ jobs:
|
|||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
# TEMPORARY PIN — remove once upstream ships a fix.
|
||||
#
|
||||
# Claude Code 2.1.216 regressed the sandbox that claude-code-action wraps
|
||||
# every Bash call in when `allowed_non_write_users` is set: the mountpoint
|
||||
# walk fails closed, so every command — down to `true` — dies with
|
||||
# `bwrap: Can't create file at /home/.mcp.json: Permission denied`.
|
||||
# Marvin still reads the issue and picks correct labels, then cannot run
|
||||
# the helper that applies them, so triage silently applied zero labels
|
||||
# from 2026-07-20 onward while every run reported success.
|
||||
#
|
||||
# 2.1.215 is the last release without the regression.
|
||||
# https://github.com/anthropics/claude-code/issues/79997
|
||||
# https://github.com/anthropics/claude-code-action/issues/1547
|
||||
env:
|
||||
PINNED_CLAUDE_CODE_VERSION: "2.1.215"
|
||||
|
||||
steps:
|
||||
- name: Checkout base repository
|
||||
uses: actions/checkout@v7
|
||||
|
|
@ -142,10 +158,21 @@ jobs:
|
|||
- name: Clean up stale Claude locks
|
||||
run: rm -rf ~/.claude/.locks ~/.local/state/claude/locks || true
|
||||
|
||||
# Mirrors how the action installs Claude Code itself, minus the version
|
||||
# it hardcodes. Passing path_to_claude_code_executable makes the action
|
||||
# skip its own install and use this build.
|
||||
- name: Install pinned Claude Code
|
||||
id: pin-claude
|
||||
run: |
|
||||
curl -fsSL https://claude.ai/install.sh | bash -s -- "$PINNED_CLAUDE_CODE_VERSION"
|
||||
echo "path=$HOME/.local/bin/claude" >> "$GITHUB_OUTPUT"
|
||||
"$HOME/.local/bin/claude" --version
|
||||
|
||||
- name: Run Marvin for Issue Triage
|
||||
id: marvin
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
path_to_claude_code_executable: ${{ steps.pin-claude.outputs.path }}
|
||||
github_token: ${{ steps.marvin-token.outputs.token }}
|
||||
bot_name: "Marvin Context Protocol"
|
||||
prompt: ${{ steps.triage-prompt.outputs.PROMPT }}
|
||||
|
|
@ -173,7 +200,7 @@ jobs:
|
|||
# agent reaching for something never on the allowlist (falling back to
|
||||
# `gh issue view` when the API is down, say) is behaving normally, and
|
||||
# failing on that would cry wolf during every GitHub incident.
|
||||
- name: Fail if an allowlisted tool was denied
|
||||
- name: Fail if Marvin could not run its tools
|
||||
if: always() && steps.marvin.conclusion != 'skipped'
|
||||
env:
|
||||
EXECUTION_FILE: ${{ steps.marvin.outputs.execution_file }}
|
||||
|
|
@ -222,9 +249,41 @@ jobs:
|
|||
echo "::notice::Marvin was denied $total call(s), none of them to tools this workflow grants. That is expected when it probes for a tool we deliberately withhold; the allowlist is intact."
|
||||
fi
|
||||
|
||||
# A granted tool can also fail *after* the permission check, which the
|
||||
# denial count above cannot see. Claude Code 2.1.216 did exactly that:
|
||||
# the sandbox refused to build and every Bash call — including the
|
||||
# labeling helper — exited 1 with `bwrap: ...`, while the run stayed
|
||||
# green. Correlate results back to their Bash tool_use rather than
|
||||
# grepping the whole log, so an issue body quoting a sandbox error
|
||||
# cannot fail an otherwise healthy run.
|
||||
if ! sandbox=$(jq -sr '
|
||||
[ .[] | if type == "array" then .[] else . end ]
|
||||
| map(select(type == "object" and (.type == "assistant" or .type == "user")))
|
||||
| map(.message.content // []) | flatten
|
||||
| map(select(type == "object"))
|
||||
| . as $blocks
|
||||
| ( $blocks
|
||||
| map(select(.type == "tool_use" and .name == "Bash"))
|
||||
| map(.id) ) as $bash
|
||||
| $blocks
|
||||
| map(select(.type == "tool_result" and (.tool_use_id as $i | $bash | index($i))))
|
||||
| map(.content | tostring)
|
||||
| map(select(test("bwrap:|Failed to (start|create) sandbox")))
|
||||
| "\(length)\t\(.[0] // "" | gsub("[\t\n]"; " ") | .[0:200])"
|
||||
' "$file"); then
|
||||
echo "::error::Could not scan Marvin execution log for sandbox failures ($file)."
|
||||
exit 1
|
||||
fi
|
||||
IFS=$'\t' read -r sandbox_failures sandbox_sample <<<"$sandbox"
|
||||
|
||||
if [[ "$sandbox_failures" -gt 0 ]]; then
|
||||
echo "::error::Marvin's Bash tool failed $sandbox_failures time(s) inside the action's subprocess sandbox, so it could not apply labels: ${sandbox_sample}. This is an environment failure, not a prompt or allowlist problem — check whether the pinned Claude Code version (${PINNED_CLAUDE_CODE_VERSION}) still avoids the upstream sandbox regression."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload Marvin execution log
|
||||
if: always() && steps.marvin.conclusion != 'skipped'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: marvin-triage-execution-log
|
||||
path: |
|
||||
|
|
|
|||
2
.github/workflows/marvin-test-failure.yml
vendored
2
.github/workflows/marvin-test-failure.yml
vendored
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
private-key: ${{ secrets.MARVIN_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
|
|
|
|||
17
.github/workflows/publish-fastmcp-tasks.yml
vendored
17
.github/workflows/publish-fastmcp-tasks.yml
vendored
|
|
@ -23,13 +23,29 @@ jobs:
|
|||
fetch-depth: 0
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
# Maintenance branches predate the standalone fastmcp-tasks package and
|
||||
# resolve the `tasks` extra through fastmcp-slim instead. This workflow
|
||||
# runs from the default branch for every fastmcp-slim release, including
|
||||
# those tags, so detect the package rather than assume it is there.
|
||||
- name: Check whether this ref builds fastmcp-tasks
|
||||
id: package_present
|
||||
run: |
|
||||
if [ -d fastmcp_tasks ]; then
|
||||
echo "present=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "present=false" >> "$GITHUB_OUTPUT"
|
||||
echo "This ref has no fastmcp_tasks package; nothing to publish."
|
||||
fi
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
- name: Build fastmcp-tasks
|
||||
if: steps.package_present.outputs.present == 'true'
|
||||
run: uv build --package fastmcp-tasks
|
||||
|
||||
- name: Verify matching fastmcp-slim is published
|
||||
if: steps.package_present.outputs.present == 'true'
|
||||
run: |
|
||||
SLIM_VERSION=$(python - <<'PY'
|
||||
import email.parser
|
||||
|
|
@ -84,4 +100,5 @@ jobs:
|
|||
exit 1
|
||||
|
||||
- name: Publish fastmcp-tasks to PyPI
|
||||
if: steps.package_present.outputs.present == 'true'
|
||||
run: uv publish -v dist/fastmcp_tasks-*.tar.gz dist/fastmcp_tasks-*.whl
|
||||
|
|
|
|||
11
.github/workflows/publish-fastmcp.yml
vendored
11
.github/workflows/publish-fastmcp.yml
vendored
|
|
@ -134,17 +134,24 @@ jobs:
|
|||
# fastmcp-tasks is pinned via the optional `tasks` extra, so its
|
||||
# Requires-Dist entry carries an `extra == "tasks"` marker — unlike the
|
||||
# base slim dependency, do not skip marked entries here.
|
||||
#
|
||||
# Print nothing when there is no such pin. Release lines that resolve
|
||||
# the `tasks` extra through fastmcp-slim instead of a standalone
|
||||
# fastmcp-tasks package have nothing here to verify.
|
||||
for value in metadata.get_all("Requires-Dist", []):
|
||||
requirement, _, _marker = value.partition(";")
|
||||
match = re.fullmatch(r"fastmcp-tasks==([^;\s]+)", requirement.strip())
|
||||
if match:
|
||||
print(match.group(1))
|
||||
break
|
||||
else:
|
||||
raise RuntimeError("Could not find the fastmcp-tasks extra dependency")
|
||||
PY
|
||||
)
|
||||
|
||||
if [ -z "$TASKS_VERSION" ]; then
|
||||
echo "This build does not pin fastmcp-tasks; the [tasks] extra cannot be uninstallable, so there is nothing to verify."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for attempt in {1..12}; do
|
||||
if python - "$TASKS_VERSION" <<'PY'
|
||||
import json
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue