Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,41 @@ jobs:

- name: Type-level tests (tsd)
run: npm run test:types --workspace=modelparams

modelparams-mcp-pkg:
name: modelparams-mcp package (build + tests)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

# The MCP server imports the built catalog from the sibling package.
- name: Build modelparams
run: npm run build --workspace=modelparams

- name: Typecheck package
run: npm run typecheck --workspace=modelparams-mcp

- name: Build package
run: npm run build --workspace=modelparams-mcp

- name: Tests
run: npm test --workspace=modelparams-mcp

- name: Server starts and answers over stdio
run: |
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"ci","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| node packages/modelparams-mcp/dist/index.js 2>/dev/null \
| grep -q 'validate_model_params' \
|| { echo "::error::MCP server did not advertise its tools over stdio"; exit 1; }
68 changes: 57 additions & 11 deletions .github/workflows/release-modelparams.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
name: Release modelparams

# Publishes the `modelparams` npm package when the catalog or codegen pipeline
# changes on main. Versioning is driven by the same diff classifier
# (`findRemovedParams`) that `param-guard.yml` uses on PRs:
# Publishes the `modelparams` and `modelparams-mcp` npm packages when the catalog
# or codegen pipeline changes on main. Versioning is driven by the same diff
# classifier (`findRemovedParams`) that `param-guard.yml` uses on PRs:
# β€’ any param removed on a still-existing model β†’ MAJOR
# β€’ any other catalog change β†’ PATCH
# β€’ no semantic catalog change β†’ skipped
#
# Both packages ship in LOCKSTEP at the same version, and `modelparams-mcp` pins
# an exact `modelparams` dependency. That's deliberate: the MCP server answers
# from the catalog compiled into its dependency, so "which catalog does
# modelparams-mcp@x.y.z carry?" has to have one answer. It also avoids a caret
# trap β€” for 0.0.x versions `^0.0.1` means `>=0.0.1 <0.0.2`, which would freeze
# the server on the first catalog forever.
#
# Publishing both from one workflow (rather than two triggered by the same push)
# keeps the order deterministic: `modelparams` goes out before the package that
# depends on it.
#
# Tag-only release: the workflow never pushes to the (protected) main branch.
# The published version is the latest `modelparams@x.y.z` git tag, bumped by the
# classifier; the first release seeds from packages/modelparams/package.json.
# The version bump is applied in-CI for the tarball but is not committed back, so
# the git tags are the source of truth for the published version.
#
# Auth: npm OIDC trusted publishing (no token). Requires npm >= 11.5.1, which
# ships with Node 24. Configure the trusted publisher for the `modelparams`
# package on npmjs.com (Settings β†’ Trusted Publishers β†’ GitHub Actions β†’
# org=mnfst, repo=modelparams.dev, workflow=release-modelparams.yml).
# ships with Node 24. Each package needs its OWN trusted publisher on npmjs.com
# (Settings β†’ Trusted Publishers β†’ GitHub Actions β†’ org=mnfst,
# repo=modelparams.dev, workflow=release-modelparams.yml) β€” configure it for
# `modelparams-mcp` as well as `modelparams`, both pointing at this filename.
# Renaming this file breaks trusted publishing for both.

on:
push:
branches: [main]
paths:
- "models/**"
- "packages/modelparams/**"
- "packages/modelparams-mcp/**"
- "src/schema/model.ts"
- "src/data/load.ts"
- "src/data/removals.ts"
Expand Down Expand Up @@ -84,31 +98,63 @@ jobs:
- name: Type-level tests (tsd)
run: npm run test:types --workspace=modelparams

- name: Build MCP server
run: npm run build --workspace=modelparams-mcp

- name: MCP server tests
run: npm test --workspace=modelparams-mcp

# The catalog classifier only sees `models/**`. An MCP-only change is real
# work that still needs shipping, so force a patch when its source moved.
- name: Detect MCP-only changes
id: mcp
run: |
if git diff --quiet HEAD~1 HEAD -- packages/modelparams-mcp; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "::notice::modelparams-mcp source changed β€” forcing at least a patch release."
fi

- name: Compute next version
id: bump
run: npx tsx packages/modelparams/scripts/compute-version.ts
env:
BASE_REF: "HEAD~1"
FORCE_LEVEL: ${{ inputs.force_level }}
FORCE_LEVEL: ${{ inputs.force_level || (steps.mcp.outputs.changed == 'true' && 'patch' || '') }}

- name: Skip publish (no semantic change)
if: steps.bump.outputs.next == ''
run: echo "::notice::No semantic catalog change since the last release β€” nothing to publish."

- name: Set package version (no commit)
- name: Set package versions (no commit)
if: steps.bump.outputs.next != ''
env:
NEXT: ${{ steps.bump.outputs.next }}
run: npm version "$NEXT" --no-git-tag-version --allow-same-version --workspace=modelparams

- name: Publish to npm
run: |
npm version "$NEXT" --no-git-tag-version --allow-same-version --workspace=modelparams
npm version "$NEXT" --no-git-tag-version --allow-same-version --workspace=modelparams-mcp
# Pin the exact catalog this server was built and tested against.
npm pkg set "dependencies.modelparams=$NEXT" --workspace=modelparams-mcp
echo "modelparams-mcp depends on modelparams@$(npm pkg get dependencies.modelparams --workspace=modelparams-mcp)"

- name: Publish modelparams to npm
if: steps.bump.outputs.next != ''
run: npm publish --workspace=modelparams --provenance --access public

# Second, so the exact dependency it pins already resolves on the registry.
- name: Publish modelparams-mcp to npm
if: steps.bump.outputs.next != ''
run: npm publish --workspace=modelparams-mcp --provenance --access public

- name: Create GitHub release + tag
if: steps.bump.outputs.next != ''
uses: softprops/action-gh-release@v2
with:
tag_name: "modelparams@${{ steps.bump.outputs.next }}"
name: "modelparams@${{ steps.bump.outputs.next }}"
generate_release_notes: true
body: |
Published to npm:
- `modelparams@${{ steps.bump.outputs.next }}`
- `modelparams-mcp@${{ steps.bump.outputs.next }}` (pins `modelparams@${{ steps.bump.outputs.next }}`)
22 changes: 21 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ You don't need to know the schema to file one. A link to the official docs is th
- You can also use `{ not: <value> }` to say "any value except this one".
- See the [schema doc](docs/model-parameters-schema.md#applicability) for the exact rule syntax and evaluation semantics.

These rules are **enforced at runtime**, not just rendered on the site. The
`modelparams` package, the `/api/v1/validate` endpoint, and the MCP server all
reject parameter combinations your rules forbid. A rule that's too strict makes
people's valid requests fail validation, so check it against the provider's docs.
When a rule references a parameter the request didn't set, evaluation falls back
to that parameter's `default` β€” which is what the provider applies in its place.

6. **Auth-type rules of thumb:**
- **`api_key`:** list parameters from the official API reference. Don't invent ones the API doesn't accept.
- **`subscription`:** list user-facing toggles and presets the consumer can actually set. Skip implementation details.
Expand Down Expand Up @@ -173,12 +180,25 @@ The website code lives under `src/`:
- `src/build/` β€” SSG pipeline (renders pages, compiles assets, emits JSON API, generates a social card per page).
- `src/server/` β€” Express dev server.

Everything the catalog ships beyond the static site:

- `api/` β€” Vercel Functions. Currently `POST /api/v1/validate`. These serve paths the
static build doesn't emit; the rest of `/api/v1/*` stays static JSON from `dist/`.
- `packages/modelparams/` β€” the npm package: generated types plus the runtime
validation helpers. `src/generated/` is committed and CI checks it against the YAML,
so run `npm run codegen --workspace=modelparams` after changing the catalog.
- `packages/modelparams-mcp/` β€” the MCP server. Ships in lockstep with `modelparams`
and pins it exactly.
- `skills/` β€” agent skills, installable with `npx skills add mnfst/modelparams.dev`.

Conventions:

- TypeScript, ES modules, strict mode.
- No file over 300 lines, no function over 50 lines.
- Format with Prettier, lint with ESLint. `npm run format` and `npm run lint` will set you straight.
- Tests live under `tests/` and run with Vitest.
- Tests live under `tests/` and run with Vitest. Each package has its own suite;
`npm test --workspaces` runs them.
- `npm run typecheck` covers the site and `api/` (via `tsconfig.api.json`).

## Pull requests

Expand Down
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,40 @@ curl https://modelparams.dev/api/v1/params/gpt-5.5.json

Schema at `https://modelparams.dev/api/v1/schema.json`, per the [Model Parameters convention](docs/model-parameters-schema.md).

### Validate a request

POST the parameters you're about to send. You get back what's wrong β€” including combinations the provider rejects β€” and a corrected payload.

```bash
curl -s https://modelparams.dev/api/v1/validate \
-H 'Content-Type: application/json' \
-d '{"model":"claude-3-opus-20240229","params":{"temperature":0.5,"top_p":0.9}}'
```

```json
{
"valid": false,
"issues": [
{
"path": "top_p",
"code": "not_applicable",
"message": "top_p does not apply when temperature β‰  1",
"conflictsWith": ["temperature"]
}
],
"safeParams": { "temperature": 0.5 }
}
```

## Agents

```bash
npx -y modelparams-mcp # MCP server: 4 tools, stdio, no network needed
npx skills add mnfst/modelparams.dev # the companion agent skill
```

The MCP server exposes `validate_model_params`, `get_model_params`, `list_models`, and `find_models_supporting`. Details in the [package README](packages/modelparams-mcp/README.md). There's also [llms.txt](https://modelparams.dev/llms.txt) if you'd rather just point an agent at a URL.

## Adding a model

Drop a YAML file in `models/<provider>/`, open a PR, and CI validates it against the schema. Details in [CONTRIBUTING.md](CONTRIBUTING.md). Can't open a PR? [File an issue](https://github.com/mnfst/modelparams.dev/issues/new/choose) with a link to the docs.
Expand All @@ -58,7 +92,8 @@ npm install
npm run dev # http://localhost:3000
npm run build # β†’ dist/
npm run validate # check every YAML
npm test
npm test # site tests, including the /api/v1/validate function
npm test --workspaces # + both published packages
```

## License
Expand Down
Loading
Loading