npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

certifico-mark

v0.2.0

Published

MCP server (stdio) for the Certifico assessment marking API

Readme

certifico-mark

MCP server that drives the Certifico assessment marking API from Claude Code / Claude Cowork. It runs in two modes:

  • Local (stdio, default): runs on your machine via npx. Authenticate via a device-code flow, point it at a folder of assessment files, spend credits through the existing API, and get marked result PDFs downloaded locally.
  • Remote (Streamable HTTP): a hosted Docker service at https://mcp.certifico.com.au/mcp. Stateless: every request must carry your Certifico access token as a bearer header; nothing is stored server-side.

Everything also stays visible in the Certifico web dashboard, because the MCP uses the exact same API as the frontend.

Local (stdio) - default

claude mcp add certifico-mark -- npx -y certifico-mark

Install in Claude Desktop

For a point-and-click install (no terminal needed): download the .mcpb extension from certifico.com.au/claude, then double-click the downloaded file (or drag it into Claude Desktop > Settings > Extensions) to install it. Open a chat and ask it to sign you in: the login tool opens the approval page in your browser with the code already filled in, and sign-in completes by itself as soon as you press Confirm.

Remote (Streamable HTTP)

claude mcp add --transport http certifico-mark https://mcp.certifico.com.au/mcp

Every request needs Authorization: Bearer <certifico access token> (configure it as a header in your MCP client). Without a valid header the server answers 401 with instructions for the device flow. In HTTP mode:

  • login / login_complete / logout / whoami are not exposed: auth comes entirely from the header.
  • mark_folder and download_results (which need your local disk) are replaced by mark_files (upload files as base64, same 200-file / 50 MB caps) and get_download_links (authenticated per-assessment PDF URLs + the batch ZIP URL).
  • Tokens are never auto-refreshed and never stored on the server. When your access token expires, the API's 401 is surfaced to you; obtain a fresh token via the device flow.

Running the remote server

certifico-mark serve --port 8080     # or: MCP_TRANSPORT=http PORT=8080 certifico-mark

Endpoints: POST /mcp (MCP Streamable HTTP), GET /healthzok.

Docker (image built from the included Dockerfile), joining the vetass-api production network:

services:
  certifico-mark-mcp:
    build: ./certifico-mark
    restart: unless-stopped
    environment:
      CERTIFICO_API_URL: http://api:3000/api
    networks:
      - production-api-network
networks:
  production-api-network:
    external: true

Then expose port 8080 as https://mcp.certifico.com.au via your TLS reverse proxy.

Security notes

  • Auth is a per-request bearer token; the server keeps no credential files, refresh tokens, sessions, or any cross-request state. A fresh MCP server instance is built per request around that request's token, so users cannot leak into each other.
  • Uploaded files are streamed straight to the Certifico API as a multipart batch; nothing is written to the service's disk.

Configuration

| Env var | Default | Description | |---|---|---| | CERTIFICO_API_URL | https://api.certifico.com.au/api | Base URL of the Certifico API. Defaults to production; override for the dev environment (https://dev.api.certifico.com.au/api) or a local stack. |

Credentials are stored at ~/.certifico/mark/credentials.json (mode 0600): { apiUrl, accessToken, refreshToken, email }. Tokens refresh automatically; logout deletes the file.

Privacy Policy

Full policy: certifico.com.au/privacy.

Student files are uploaded to Certifico only when a mark tool (mark_folder or mark_files) is called; nothing is uploaded before then. The refresh token that keeps you signed in is stored locally at ~/.certifico/mark/credentials.json and is never sent anywhere except the Certifico API. This MCP server collects no analytics and reports no telemetry.

Tools

| Tool | Purpose | |---|---| | login | Starts the device flow: opens the approval page in the default browser (disable with the "Open the sign-in page automatically" setting) and returns the verification URL, user code and a deviceCode. | | login_complete | Call immediately after login: waits up to ~45s for the browser approval, then saves tokens. If it reports "still pending", call it again with the same deviceCode - no need for the teacher to confirm anything. | | whoami | Shows the signed-in email and API URL. | | logout | Revokes the session and deletes local credentials. | | get_credits | Current credit balance (1 credit = one assessment group). | | buy_credits | Creates a checkout session; returns a checkoutUrl to pay. | | mark_folder | The main workflow: scans a folder for .pdf/.doc/.docx, auto-groups by "Student Name - UNITCODE - Part N.ext", pre-checks credits, uploads the batch, waits for marking (up to 30 min) and downloads result PDFs. wait: false returns the batchId immediately. | | get_batch_status | Per-assessment state/outcome of a batch. | | list_batches | Lists past batches. | | download_results | Downloads all completed PDFs of a batch to a folder. | | retry_assessment | Retries a FAILED assessment (charges 1 credit; fails if input files were purged after 24h). |

HTTP mode replaces the filesystem/login tools with:

| Tool (HTTP mode only) | Purpose | |---|---| | mark_files | Uploads files: [{ name, contentBase64 }] (max 200 files, 50 MB each), auto-groups by the naming convention, pre-checks credits and creates the batch. Returns the batchId immediately. | | get_download_links | Authenticated download URLs: /assessments/:id/download per completed assessment plus the batch ZIP. Fetching them requires the same bearer token. |

File naming convention

<Student Name> - <UNITCODE> - <Part N>.<pdf|doc|docx>: files sharing student + unit code form one group = one assessment = 1 credit. Names without a recognizable unit code (3 letters then 3+ letters/digits, e.g. BSBXCM501) fall back to a unitless group per student.

Limits (validated locally before upload, and enforced server-side): max 200 files, max 50 MB per file, non-recursive scan.

Example prompts

login

  • "Sign me in to Certifico"
  • "Log in to my Certifico account so I can start marking"
  • "Connect this to Certifico, start the sign-in flow"

login_complete (normally called by Claude on its own, straight after login)

  • "Complete my Certifico login now"
  • "Keep waiting, I'm approving it in the browser"

whoami

  • "Which Certifico account am I signed in as?"
  • "Show me who's logged in and which API URL is in use"
  • "Am I currently signed in to Certifico?"

logout

  • "Sign me out of Certifico"
  • "Log out and delete my local credentials"
  • "I'm done for today, log me out of Certifico"

get_credits

  • "How many credits do I have left?"
  • "Check my Certifico credit balance"
  • "Do I have enough credits to mark 10 assessments?"

buy_credits

  • "Buy 50 more credits"
  • "I'm running low, top up 20 credits"
  • "Create a checkout session for 100 credits"

mark_folder

  • "Mark the assessments in ~/Marking/BSB40120"
  • "Mark ~/Downloads/submissions and save results to ~/Marking/results"
  • "How much will marking ~/Marking/CHC33021 cost before you run it?"

get_batch_status

  • "What's the status of batch abc123?"
  • "Is batch abc123 finished marking yet?"
  • "Show me the per-student outcome for batch abc123"

list_batches

  • "Show me my past marking batches"
  • "List the batches I've run this month"
  • "What batches have I submitted so far?"

download_results

  • "Download the results for batch abc123 into ~/Marking/results"
  • "Get the finished PDFs from batch abc123 and save them to my Desktop"
  • "Save the completed marking PDFs for batch abc123 to ~/Marking/CHC33021/done"

retry_assessment

  • "Retry the failed assessment in batch abc123, assessment id xyz789"
  • "That assessment failed, please retry it: assessment xyz789 in batch abc123"
  • "Re-run assessment xyz789 since it failed the first time"

mark_files (HTTP mode only)

  • "Mark these three uploaded files as one batch"
  • "Here are base64-encoded submissions for Jane Doe, mark them"
  • "Upload and mark these assessment files for BSBXCM501"

get_download_links (HTTP mode only)

  • "Give me the download links for batch abc123"
  • "What are the authenticated URLs for the completed PDFs in batch abc123?"
  • "Get me the ZIP download link for batch abc123"

Development

Against the local stack (./scripts/dev-stack.sh in the monorepo root; API on plain HTTP :3000; prefer it over the TLS proxy so you never need to disable certificate checks):

npm install
npm test          # vitest
npm run typecheck # tsc --noEmit
npm run build     # tsup → dist/index.js (single minified file)

claude mcp add certifico-mark-dev --env CERTIFICO_API_URL=http://localhost:3000/api -- node "$(pwd)/dist/index.js"

Never set NODE_TLS_REJECT_UNAUTHORIZED=0 against production.

Publishing

Only the bundled, minified dist/ and this README are published (files in package.json); source code is not included in the npm tarball.