This repository is a pnpm + Turborepo monorepo for public @transcend-io/* TypeScript packages/.
The root package is private. Publishable packages live in packages/.
Install mise, then run:
mise trust mise.toml
mise install
mise run bootstrapmise.toml pins the Node version for local development, devcontainers, and CI. package.json
pins the exact pnpm version.
The repo uses oxc for linting and oxfmt for formatting.
- You should install the
oxc.oxc-vscodeextension to get the best experience. - You should disable ESLint and Prettier extensions, if you have them installed. You can disable them for this repository only by right-clicking the extension and selecting "Disable (Workspace)".
- Run
mise run bootstrapafter cloning and whenever dependencies change. - Make your change in the relevant package.
- Add a changeset when your change touches package code under
packages/. - Merge your feature PR into
main. - CI will automatically open a release PR.
- If you wish to release immediately, merge the release PR to publish to npm.
pnpm build: build workspace packages withtsdownpnpm test: run package tests with Vitestpnpm quality: run repo-wide verification checks and typecheckpnpm quality:fix: auto-fix formatting and lint issues where possible, then run the remaining quality checkspnpm changeset: create a changeset file
Additional checks:
pnpm typecheck: run TypeScript checks across workspace packagespnpm lint: runoxlintacross the repopnpm lint:fix: runoxlint --fixacross the repopnpm format: format the repo withoxfmtpnpm format:check: verify formatting withoxfmt --checkpnpm check:changeset: validate changeset coverage for publishable package changespnpm check:packages: validate shared package metadata and layout conventionspnpm check:exports: validate published package shape withattwpnpm check:publint: validate published package compatibility and packaging metadatapnpm check:deps: enforce dependency version policy
pnpm quality intentionally excludes pnpm check:changeset, since that check compares the current branch to its base and is mainly useful in pull request workflows.
Release and maintenance:
pnpm changeset:version: apply pending changesets to versions and changelogspnpm changeset:version:release: apply pending changesets and reformat the repopnpm release: build and publish packages
Use pnpm --filter or (pnpm -F for short) when you only need to work on one package:
pnpm -F cli startSee pnpm Filtering for more examples.
Note
- You do NOT need to manually version packages in your PRs. Instead, you need to create a changeset file via
pnpm changeset. - Your feature PR does NOT automatically publish to npm. Instead, CI opens a release PR after your feature PR is merged.
Stable releases are driven by Changesets and the Release workflow:
-
Developers merge feature PRs with changesets into
main. -
The
Releaseworkflow automatically opens a release PR, titled "Version Packages".Or, if there's already an open release PR, then that PR will be updated instead.
In a release PR:
- Each changeset file (at
.changeset/*.md) is turned into a change entry in each package'sCHANGELOG.mdfile, and the changeset file is deleted. - Package versions are bumped accordingly.
- Here's an example of a release PR.
- Each changeset file (at
-
When the release PR is merged, the
Releaseworkflow publishes the packages to npm.
Thus, after you merge a feature PR, you can either:
- Merge the subsequent release PR to publish to npm if you want it released immediately, or
- Wait a few feature PRs build up, before merging a release PR and publishing to npm (this also allows you to split up your changes into multiple PRs without releasing).
Changesets record release intent.
Create one with:
pnpm changesetAdd a changeset when changes to a package under packages/ would require a new version to be published to npm.
scripts/check-changeset.ts enforces this on pull requests. It only requires coverage for changed publishable packages, and it ignores:
- private packages (i.e. packages with
"private": truein theirpackage.json) - package
README.mdchanges - test files
- generated
dist/output node_modules/and.turbo/- See
scripts/check-changeset.tsfor the full list of ignored files.
If a PR changes a publishable package, each changed publishable package must be mentioned in at least one changeset frontmatter block. Otherwise, CI fails.
Pull requests also get preview packages via pkg.pr.new, which you'll see as an automated bot comment in your PR. Use those when another repo or environment needs to test package changes before a stable release. Obviously, you should never use these preview releases in production.
This repo is set up for npm trusted publishing via GitHub OIDC. The workflow has id-token: write,
and normal publishing should not require a long-lived NPM_TOKEN. Each published package still has
to be configured in npm to trust this repository and workflow.
If npm trusted publishing is not configured for a package, the release workflow will build and version correctly but fail at publish time.
release.yml also supports workflow_dispatch. Use that for reruns or recovery, not as the normal
release path.
This repo uses Turborepo, which caches package.json script outputs. Try running pnpm build twice to see the cache in action.
Note
Remote caching is not yet configured.
CI and release workflows can use Turbo remote caching when secrets.TURBO_TOKEN and
vars.TURBO_TEAM are configured. Local development does not require remote cache.
After a normal install from the repo root, Husky configures local Git hooks automatically.
pre-commit: runspnpm quality:fixand aborts if it updates tracked filespre-push: runspnpm test
These hooks are local guardrails. CI still runs the canonical repo checks on pull requests and releases.
If you install dependencies with scripts disabled, rerun pnpm run prepare from the repo root
before committing.
Shared dependency versions live in pnpm-workspace.yaml catalogs.
Guidelines:
- prefer
catalog:for shared toolchain dependencies - prefer
workspace:*for dependencies between local packages - keep additions consistent with the single-version policy enforced by
syncpack
On pull requests, GitHub Actions runs:
CI:CI / globaljob: runs all the standard commands across each package such asbuildandtestcommands.CI / <package-name>jobs: some packages may have their own jobs to add unique checks, such as theCI / cli, which ensures that generated CLI files are up to date.
Preview Releasesee Preview Releases for more.
New, reviewable commits pushed will dismiss previous pull request review approvals. As a public repository, we want to ensure that all changes are reviewed and approved by at least one team member.
This repo uses the GitHub Merge Queue feature to automatically merge pull requests when CI passes.
Transcend Team:
- See our HOWTO: Migrate a repo to transcend-io/tools.
- If this is a net-new npm package, it needs to first be created here, and it needs trusted publishing set up (see the HOWTO guide above for more on that). Once that is done, it should publish successfully the next time a release PR merges with a changeset for that package.
New packages should match the shape used in packages/sdk and packages/utils.
For a new package:
- Create
packages/<name>/package.json. - Add
tsconfig.json,tsdown.config.ts, andsrc/index.ts. - Add tests when the package has behavior worth validating.
- Add the package to the root
tsconfig.jsonreferences list. - Use
workspace:*for dependencies on other local packages. - Use
catalog:for shared tool dependencies.
Current package conventions:
- ESM-only packages with
"type": "module" - published entrypoints served from
dist/ @transcend-io/sourceexport condition for live source resolution inside the monorepobuild,test,typecheck, andcheck:exportsscripts in each package- publishable packages also provide a
check:publintscript pnpm check:packagesenforces shared package metadata, required package files, and roottsconfig.jsonreferences- publishable packages include
homepage,repository, andauthormetadata - released publishable packages keep a
CHANGELOG.md
MCP (Model Context Protocol) server packages live under packages/mcp/. They let AI agents interact with the Transcend platform. See the root README.md for a full list of packages and their purpose.
packages/mcp/
mcp-server-core/ # Shared infrastructure (GraphQL base, REST client, validation, types)
mcp-server-admin/ # Domain: org, users, API keys
mcp-server-assessments/
mcp-server-consent/
mcp-server-discovery/
mcp-server-dsr/
mcp-server-inventory/
mcp-server-preferences/
mcp-server-workflows/
mcp-server/ # Unified server that re-exports all domain tools
Each domain package provides a standalone CLI and can be installed independently. The unified mcp-server package composes all domains via ToolRegistry.
MCP servers read TRANSCEND_API_KEY (and optional URL overrides) from the environment. For local runs from this repository, use root secret.env (gitignored):
cp secret.env.example secret.env
# Edit secret.env — set at least TRANSCEND_API_KEYLoad variables into your shell before pnpm (from the repository root):
set -a && source ./secret.env && set +aOr run a built CLI via scripts/mcp-run.sh, which sources secret.env when the file exists:
./scripts/mcp-run.sh ./packages/mcp/mcp-server-consent/dist/cli.mjsUse the path to the dist/cli.mjs for the server you built. See each package README under packages/mcp/ for Turbo build filters.
Use pnpm --filter the same way as any other package. For build, prefer a Turbo filter with a trailing ... so mcp-server-core and other dependencies are built when needed:
pnpm exec turbo run build --filter="@transcend-io/mcp-server-consent..."
pnpm -F @transcend-io/mcp-server-consent test
pnpm -F @transcend-io/mcp-server-consent typecheckAll MCP servers require:
TRANSCEND_API_KEY— your Transcend API key
Optional overrides:
TRANSCEND_API_URL— Sombra REST API base URL (default:https://multi-tenant.sombra.transcend.io)TRANSCEND_GRAPHQL_URL— GraphQL API base URL (default:https://api.transcend.io)
For local development, define these in secret.env (copy from secret.env.example at the repository root). Do not commit secret.env.
- Create a new file under the domain's
src/tools/directory (e.g.src/tools/consent_new_tool.ts). - Export a
create*Tool(clients: ToolClients): ToolDefinitionfactory function following the existing pattern. - Register it in the domain's
src/tools/index.tsby importing and adding it to the returned array. - If the tool needs new input validation, add a Zod schema to
src/schemas.ts. - If the tool calls a new API endpoint, extend the domain's GraphQL mixin (
src/graphql.ts) or the shared REST client inmcp-server-core. - Add or extend tests in the domain package's
tests/directory. - The unified
mcp-serverpackage picks up the new tool automatically through itsToolRegistry.
MCP packages are publishable. Run pnpm changeset when your change modifies package code under packages/mcp/, just like any other publishable package.