Thanks for your interest in contributing. This repository is an npm workspaces monorepo publishing three packages:
| npm package | Import | Directory |
|---|---|---|
@authplane/sdk |
@authplane/sdk (subpath exports: ./core, ./auth) |
packages/sdk/ |
@authplane/mcp |
@authplane/mcp |
packages/mcp/ |
@authplane/fastmcp |
@authplane/fastmcp |
packages/fastmcp/ |
Adapters depend on @authplane/sdk. A single tagged release publishes all three at the same version (see RELEASE_POLICY.md).
- Bugs: open a bug report. Include package name, version, Node version, and a minimal reproduction.
- MCP client compatibility: use the MCP Compatibility Report template.
- Feature requests: open a feature request. Describe the problem, then the proposed solution.
- Security vulnerabilities: do not open a public issue. See SECURITY.md.
- Node.js 22 LTS (or newer)
- npm 10.x (bundled with Node 22) — the repo uses npm workspaces; pnpm/yarn are not supported
git
Clone the repo and install the workspace:
git clone https://github.com/AuthPlane/ts-sdk.git
cd ts-sdk
npm cinpm ci installs against the committed package-lock.json. Use npm install only when deliberately updating dependencies — otherwise prefer ci for reproducibility.
Run the same checks CI runs before opening a PR.
Lint and format (biome):
npm run lint # biome lint --error-on-warnings
npm run format # biome format (writes changes)npm run lint runs across all three workspace packages. Use npm run format to auto-fix formatting.
Type-check and build (tsc):
npm run typecheck # same as: tsc -b
npm run build # same as: tsc -bThe workspace uses TypeScript project references. tsc -b at the root (or in any package) walks the reference graph — it builds @authplane/sdk first, then @authplane/mcp and @authplane/fastmcp. Adapter packages resolve cross-package types directly from sdk's source, so you never need to manually rebuild the SDK before working on an adapter.
Incremental state lives in each package's tsconfig.tsbuildinfo; repeat invocations only recompile what changed. Clean state: rm -rf packages/*/dist packages/*/tsconfig.tsbuildinfo.
typecheck and build are the same command today (tsc -b emits .d.ts as a byproduct of type-checking with project references). Keeping two script names for habit and future divergence.
Tests (vitest):
npm test # all three workspaces
npm run test:coverage # same, with v8 coverage outputIndividual workspaces:
npm test -w @authplane/sdk
npm test -w @authplane/mcp
npm test -w @authplane/fastmcpCoverage target: ≥ 85% on statements, branches, functions, and lines for every workspace — enforced in CI via the shared vitest config (vitest.coverage.shared.ts).
Conformance tests (shared catalog required):
@authplane/sdk's conformance suite (packages/sdk/conformance-tests/) validates the SDK against the shared OAuth SDK Conformance Catalog, which lives in AuthPlane/conformance. Clone that repo as a sibling of your ts-sdk/ clone:
# From the directory that contains your ts-sdk/ clone
git clone https://github.com/AuthPlane/conformance.gitExpected layout:
parent-dir/
├── ts-sdk/
└── conformance/
└── oauth-sdk-conformance-catalog.yaml
With that layout in place, npm test auto-discovers the catalog — no configuration required. Override the path with CONFORMANCE_CATALOG_PATH if the catalog lives elsewhere:
CONFORMANCE_CATALOG_PATH=/path/to/oauth-sdk-conformance-catalog.yaml \
npm run test -w @authplane/sdkIf the catalog isn't available at all, skip the two catalog-dependent tests with:
AUTHPLANE_CONFORMANCE_SKIP_CATALOG=1 npm testcatalogAlignment.test.ts and z_conformanceReport.test.ts then report as skipped; the rest of the SDK suite runs as normal. Without either the catalog present or the skip flag set, those two tests fail with a clear error.
Package pack smoke test:
cd packages/sdk && npm pack
cd ../mcp && npm pack
cd ../fastmcp && npm packProduces .tgz tarballs locally. release.yml and publish-npm.yml run this as part of validation; npm publish is never run locally against the real registry.
- Branch off
main. Release branches (release/v*,hotfix/v*) are managed by the release flow — see RELEASE_POLICY.md. - PR titles follow Conventional Commits:
feat:,fix:,docs:,ci:,deps:,refactor:,test:,chore:. - Link any related GitHub issue in the PR description (e.g.,
Fixes #123). - Fill out the PR template (summary, testing, checklist).
- Keep PRs focused. Large, multi-theme PRs are hard to review and easy to stall.
User-facing changes go in CHANGELOG.md under the [Unreleased] heading. Follow the Keep a Changelog format. Release tooling moves entries from [Unreleased] to the release version on tag.
All workflow actions should be SHA-pinned with a version comment:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2When editing or adding a workflow, run pinact to pin any new uses: lines before committing:
pinact runDependabot opens weekly PRs to bump the SHAs (see .github/dependabot.yml).
The end-to-end demo exercises the FastMCP and MCP adapters against a local Authplane authorization server.
Prerequisites:
- OAuth server running locally on
:9000/:9001with client credentials, token exchange, and DPoP enabled. - Demo client registration with required grant types and scopes.
- Adapter demo server (
packages/fastmcp/demo/run.shorpackages/mcp/demo/run.sh). - Demo client execution (matrix client).
Entry points:
packages/fastmcp/demo/run.shpackages/mcp/demo/run.sh
Helper scripts in scripts/ boot a local authserver and run a smoke check:
# Start local authserver and register client/scopes/user.
bash scripts/manual-e2e-setup.sh
# Smoke against the MCP adapter (default).
bash scripts/manual-e2e-smoke.sh --skip-setup
# Smoke against the FastMCP adapter.
bash scripts/manual-e2e-smoke.sh --adapter fastmcp --skip-setupOptional overrides:
AUTHSERVER_DIR=/path/to/authserverISSUER_URL=http://localhost:9000RESOURCE_URL=http://localhost:8080/mcp
client_credentials grant is not enabled— OAuth server is missingAUTHPLANE_CLIENT_CREDENTIALS_ENABLED=true.client is not authorized for this grant type— client registration is missingurn:ietf:params:oauth:grant-type:token-exchange.requested scope is invalid or not allowed— requested scopes are not registered or assigned to the demo client.invalid API key— admin API requests are using a different key than the server startup key.
Be kind. Disagree on substance, not people. Projects that aren't kind don't last.