portaljs-connect-ckan

portaljs-connect-ckan is a skill for Claude Code from datopian/portaljs. It costs 74 tokens per session (1,522 once invoked), scanned A, original, MIT.

A connector that makes a PortalJS website read its catalogue and dataset pages from CKAN, an open-source system for publishing and managing datasets, through its web API.

In plain words
What is it for?
Use it after creating a PortalJS portal when the catalogue and dataset pages should display data from an existing CKAN installation.
Why use it?
It replaces example data stored in local files with data from a live CKAN server. The generated code fetches the data when the site is built and can still be deployed as a static website.

Skill for Claude Code

Written for Claude Code: allowed-tools in frontmatter. Also seen: reads .claude/ paths; mentions Claude Code.

Part of the portaljs plugin — 14 skills, 25 commands shipped together

Good fit Use it after creating a PortalJS portal when the catalogue and dataset pages should display data from an existing CKAN installation.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/datopian/portaljs/portaljs-connect-ckan
About the project

PortalJS is a framework for building data portals that present searchable datasets through a home page, catalog, and dataset showcase. It is for teams that want to choose a data backend, scaffold a Next.js portal, load CSV or JSON data, connect services such as CKAN, and deploy the result. The catalogue entries are agent commands, skills, instructions, and a plugin that guide portal creation and data loading.

datopian/portaljs · 2,350 stars · on GitHub · portaljs.com

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add datopian/portaljs --skill portaljs-connect-ckan
Clone the repo
git clone --depth 1 https://github.com/datopian/portaljs

Made for: Claude Code.

Or install portaljs, the plugin that ships this one along with the rest of its 14 skills, 25 commands.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for portaljs-connect-ckan

README.md
[![agentmods](https://agentmods.dev/badge/skills/datopian/portaljs/portaljs-connect-ckan/github.svg)](https://agentmods.dev/skills/datopian/portaljs/portaljs-connect-ckan)
Your own site
<a href="https://agentmods.dev/skills/datopian/portaljs/portaljs-connect-ckan"><img src="https://agentmods.dev/badge/skills/datopian/portaljs/portaljs-connect-ckan/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for portaljs-connect-ckan

Your own site · 80×15
<a href="https://agentmods.dev/skills/datopian/portaljs/portaljs-connect-ckan"><img src="https://agentmods.dev/badge/skills/datopian/portaljs/portaljs-connect-ckan.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 74 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 1,522 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. Third-party audits
  • NVIDIA SkillSpector warn 7 Sept 2026
SkillSpector: 2 findings, up to medium

These are SkillSpector’s own severities. On a checked sample its high-severity flags on skills were ~96% false positives — a documented command, a public API, a “never do X” rule — so we show them as a caution to read, not a verdict. Why →

  • medium MCP Rug Pull · line 61
    npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
    Fix: Pin the version: npx @scope/[email protected]
  • medium MCP Rug Pull · line 70
    npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
    Fix: Pin the version: npx @scope/[email protected]
How audits are shown
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00074 $0.01522
Opus 5 $0.00037 $0.00761
Sonnet 5 $0.00015 $0.00304
Haiku 4.5 $0.00007 $0.00152

Measured 11d ago against content hash af7dc40dfcec, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-11, from the pricing page.

Security

Grade A, and why

portaljs-connect-ckan scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 11d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/portaljs-connect-ckan/SKILL.md · 111 lines

How it starts

The opening of the file, as written. The whole thing — 111 lines — stays where its author put it; the contents beside it link to each section on GitHub.

PortalJS — Connect CKAN

Overview

Connect an existing portaljs-catalog portal to a live CKAN backend for the "decoupled / any backend" path. The portal stops reading the static datasets.json manifest (and files in /public/data/) and instead feeds its two data surfaces — the /search catalog and the /@namespace/slug showcases — straight from a CKAN instance's REST API (package_search / package_show) through a generated fetch client. Output is plain, editable Next.js code with no runtime dependency — never @portaljs/ckan, whose bundle wires React UI components to React 18 internals and crashes at import under the template's React 19. Pages fetch CKAN server-side in getStaticProps/getStaticPaths, so the catalog is pre-rendered at build time and the site can still be statically deployed. Run this right after portaljs-new-portal to swap a freshly scaffolded portal's sample data over to CKAN.

Prerequisites

  • A scaffolded PortalJS portal (see portaljs-new-portal) with package.json, pages/, datasets.json, pages/search.tsx, and pages/[owner]/[slug].tsx present.
  • A CKAN base URL that is publicly reachable, e.g. https://demo.dev.datopian.com.
  • Node 18+ and npm available in the portal directory (no new packages are installed).

Instructions

The canonical, full step-by-step workflow is .claude/commands/portaljs-connect-ckan.md — the single source of truth. Read and follow it when executing. Summary:

  1. Gather input from $ARGUMENTS — CKAN base URL (required), org filter (optional), group filter (optional), portal directory (default .). If the URL is missing, interview the user; never dead-end with a missing-input error.
  2. Validate the target directory is a portaljs-catalog portal; if not, suggest portaljs-new-portal instead of failing silently.
  3. Verify the CKAN backend is reachable via package_search?rows=1, and validate each org filter via organization_show; on failure, explain and re-prompt rather than dead-ending.
  4. Generate lib/ckan.ts — a self-contained server-side fetch client wrapping package_search and package_show, with DMS, ORG_FILTER, GROUP_FILTER, and MAX_DATASETS as editable constants.
  5. Rewire pages/search.tsx to list datasets from package_search, linking each to /@namespace/slug via datasetHref; leave pages/index.tsx untouched.
  6. Overwrite pages/[owner]/[slug].tsx to pre-render one page per dataset via getStaticPaths and fetch details with package_show, previewing tabular resources through the existing Table component.
  7. Verify the build with npx next build; fix any error before reporting success.
  8. Report what changed: client, catalog, showcase, filters, and static page count.

Read the full file on GitHub · 111 lines

Files

What ships with it

1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 11d ago First seen · 111 lines · 74 tokens per session scan A af7dc40dfcec

Subscribe to this mod's changes

portaljs-connect-ckan is a skill published in the GitHub repository datopian/portaljs (2,350 stars, last pushed 3d ago), licensed MIT. It adds 74 tokens to every session and 1,522 once invoked, about $0.0004 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other skills, from other repositories

nextjs-app-router

Full end-to-end tRPC setup for Next.js App Router. Covers route handler with fetchRequestHandler (GET + POST exports), TRPCProvider with QueryClientProvider, createTRPCOptionsProxy for RSC prefetching, HydrateClient/HydrationBoundary for hydration, useSuspenseQuery for Suspense, and server-side callers.

trpc/trpc · 74 tokens

nextjs-pages-router

Set up tRPC in Next.js Pages Router with createNextApiHandler, createTRPCNext, withTRPC HOC, SSR via ssr option and ssrPrepass, SSG via createServerSideHelpers with getStaticProps, and server-side helpers for getServerSideProps prefetching.

trpc/trpc · 67 tokens

openapi

Generate OpenAPI 3.1 spec from a tRPC router with @trpc/openapi CLI or programmatic API. Generate typed REST client with @hey-api/openapi-ts and configureTRPCHeyApiClient(). Configure transformers (superjson, EJSON) for generated clients. Alpha status.

trpc/trpc · 64 tokens

server-setup

Initialize tRPC with initTRPC.create(), define routers with t.router(), create procedures with .query()/.mutation()/.subscription(), configure context with createContext(), export AppRouter type, merge routers with t.mergeRouters(), lazy-load routers with lazy().

trpc/trpc · 56 tokens

subscriptions

Set up real-time event streams with async generator subscriptions using .subscription(async function() { yield }). SSE via httpSubscriptionLink is recommended over WebSocket. Use tracked(id, data) from @trpc/server for reconnection recovery with lastEventId. WebSocket via wsLink and createWSClient from @trpc/client…

trpc/trpc · 118 tokens

client-setup

Create a vanilla tRPC client with createTRPCClient (), configure link chain with httpBatchLink/httpLink, dynamic headers for auth, transformer on links (not client constructor). Infer types with inferRouterInputs and inferRouterOutputs. AbortController signal support. TRPCClientError typing.

trpc/trpc · 63 tokens