Skip to main content

Project Structure

HelixID is developed across six public repositories in the helixid organization.

helixid/
├── helixid/ The self-hosted server you run (@helixid/api)
├── helix-core/ The API implementation it runs (@helixid/core)
├── helix-console/ Operator web UI
├── helix-sdk-js/ JS/TS SDK, CLI, MCP, LangChain, widget
├── helix-sdk-py/ Python SDK
└── helix-wiki/ This documentation site

The org at a glance​

RepositoryPackageWhat it is
helixid@helixid/apiThe server you deploy. A thin, runnable shell that composes the API implementation
helix-core@helixid/coreThe API implementation. Routes, services, repositories, storage, cache, audit, Hedera
helix-console—React operator UI — agents, enrollment, verifier services, audit trail
helix-sdk-js7 npm packagesEverything a JS/TS agent or verifier installs
helix-sdk-pyhelixid-sdk-pyThe Python counterpart, for AI/ML stacks
helix-wiki—This documentation site

A running server is the one thing everything else needs. The console and both SDKs reach it over its HTTP API; nothing reaches into anything else's internals.

How helixid and helix-core fit together​

This pair is the part worth understanding first, because the names do not tell you which is which.

helixid (@helixid/api) ← the thing you run
│
│ depends on, as a published npm package:
│ "@helixid/core": "^2.0.1"
▼
helix-core (@helixid/core) ← where the API actually lives

helixid is deliberately thin — its src/ holds a server entrypoint and environment loading, and little else. It is the packaging: the runnable, self-hostable server, plus its Prisma schema, tests, and Docker setup.

helix-core is the substance. Everything that makes a decision lives here:

helix-core/src/
├── routes/ HTTP surface — the endpoints in the API reference
├── services/ business logic — issuance, verification, delegation, revocation
├── repositories/ persistence, behind an interface
├── storage/ storage adapters
├── cache/ DID and status-list caching
├── audit/ the audit log contract
├── middleware/ request-level concerns
├── hedera/ optional did:hedera support
└── core/ shared primitives
Why the split exists

Keeping the API implementation in its own package means the layer that makes trust decisions is a single real dependency rather than a copy that drifts. helixid composes it into a server you can run; the logic itself has one home.

Don't install @helixid/core in an application

It is a server-side dependency, published on npm but meant to be consumed by the server, not something an agent or verifier installs. If you are building an agent, a verifier, or an integration, you want @helixid/sdk-js or the Python SDK. See The core layer.

helixid — the server you run​

helixid/
├── src/ server entrypoint and env loading
├── examples/ every runnable demo and verifier script
│ ├── e2e-consent-demo/ user consent across two SPs (JS)
│ ├── e2e-consent-demo-py/ the same demo, Python agent
│ ├── e2e-travel-concierge/ LLM agent + protected MCP tool (JS)
│ ├── e2e-travel-concierge-py/ the same demo, Python agent
│ ├── framework-middleware/ live LangChain and MCP adapters
│ └── *.ts standalone verifier scripts
├── prisma/ schema and migrations
├── docs/ architecture decisions and proposals
├── e2e/ end-to-end tests
├── scripts/ setup and helper scripts
├── docker-compose.local.yml
└── Dockerfile

It is a pnpm workspace: the root is @helixid/api, and examples/* are workspace packages, which is how the pnpm example:* scripts resolve. See Examples.

Dependencies

DependencyRequired?Notes
@helixid/coreYesPublished npm package from helix-sdk-js/helix-core's release, not a git dependency
@helixid/sdk-js, @helixid/did-hederaDev-onlyPublished npm packages from helix-sdk-js, used for this repo's own examples/e2e tests — not needed to run the server itself
DatabaseYes — one of twoPostgres, or SQLite as a fast local path that self-initializes its schema with no migration step
RedisNoOnly when a Redis cache adapter is configured explicitly
@helixid/did-hederaResolved at runtimehelix-core loads it dynamically even in did:key mode

Setup is in Installation & Modes; every variable is in Environment & Configuration.

helix-sdk-js​

A pnpm workspace managed with Turborepo. Every npm package lives here.

helix-sdk-js/
├── helix-sdk-js/ core SDK (@helixid/sdk-js)
├── cli/ the `helix` command-line tool
├── mcp-server/ standalone MCP server for operator workflows
├── mcp-middleware/ VP verification/attachment for other MCP servers
├── langchain/ LangChain / LangGraph integration
├── widget/ browser consent widget
├── did-hedera/ optional Hedera DID method
└── fixtures/ golden vectors, shared with helix-sdk-py
PackageWhat it is
@helixid/sdk-jsHelixClient, verifyVP, AgentWallet, VPBuilder, delegate
@helixid/cliOperator CLI (helix)
@helixid/mcp-serverOperator workflows exposed as MCP tools
@helixid/mcp-middlewareVP verification for your own MCP server
@helixid/langchainLangChain / LangGraph middleware
@helixid/widgetSP-side consent widget
@helixid/did-hederaOptional Hedera DID resolver

See each package's npm page for its current version.

Each package carries its own README, test suite, and a files allowlist controlling what publishes.

Dependencies: none to build and verify presentations locally. The Hedera path needs @helixid/did-hedera and operator credentials — it spends real money, so install it only where Hedera support is actually needed.

mcp-server vs mcp-middleware​

Easy to confuse, different jobs:

  • @helixid/mcp-server is a standalone server. It exposes the same platform-operator workflows as the CLI — DID, wallet, status-list and VC lifecycle — as MCP tools instead of shell commands.
  • @helixid/mcp-middleware is a library for your own MCP server or client. It verifies inbound presentations and attaches outbound ones. This is what MCP Integration documents.

The CLI is the single canonical implementation of operator workflows and is deliberately not duplicated per language — which is why helix-sdk-py ships no CLI.

helix-sdk-py​

The Python counterpart, for AI/ML stacks. Distribution name helixid-sdk-py.

helix-sdk-py/
├── src/
│ ├── helix_sdk/ core SDK
│ ├── helix_langchain/ LangChain integration
│ ├── helix_crewai/ CrewAI integration
│ └── helix_mcp_middleware/ MCP auth middleware
├── examples/ demo scripts — these need a running server
├── tests/
└── fixtures/ golden vectors, shared with helix-sdk-js

Dependencies: none for the package itself beyond its own extras. The example scripts need a running server.

The shared fixtures/ directory is what keeps the two SDKs honest: both verify against the same golden vectors, so a presentation signed in Python must verify through the same path as one signed in TypeScript. Divergent crypto behaviour between them would be a security bug, not a compatibility inconvenience.

helix-console​

The operator view — agents, enrollment, verifier services, and the audit trail, without hitting the API by hand.

helix-console/
├── src/
│ ├── pages/, components/, hooks/ feature UI
│ ├── auth/, theme/ login gate, dark/light mode
│ ├── api/ the one seam wrapping HelixClient
│ └── runtimeConfig.ts container-runtime configuration
├── docker/ nginx config + runtime env injection
├── tests/ mirrors src/
├── public/, brand-src/
├── vite.config.ts
└── Dockerfile

Dependencies: a running server, and nothing else.

All API access goes through a single api/ module wrapping HelixClient. The console holds no credential logic of its own — it is a view over the server's state.

Working across the repositories​

Clone what you need as siblings:

mkdir helixid && cd helixid
git clone https://github.com/helixid/helixid.git
git clone https://github.com/helixid/helix-core.git
git clone https://github.com/helixid/helix-console.git
git clone https://github.com/helixid/helix-sdk-js.git
git clone https://github.com/helixid/helix-sdk-py.git

Start in dependency order:

  1. helixid — the server. The SQLite path is the quickest way up.
  2. helix-console, if you need the UI. Its admin key must match the server's.
  3. helix-sdk-js / helix-sdk-py, pointed at the same API base URL and admin key.

You only need helix-core cloned if you are changing the API implementation itself — running the server pulls it automatically.

Toolchain versions are pinned per repository — .nvmrc for the Node repos, and a pinned interpreter for helix-sdk-py. Use them rather than whatever is on your path; these are cryptographic codebases and version drift is not worth debugging.

Which repository does my change belong in?​

Each repository tracks its own issues and pull requests — file against the one you are changing.

You are changingRepository
Routes, services, issuance, verification, revocation, storagehelix-core
Server packaging, deployment, Prisma schema, Dockerhelixid
The wallet, VP building, local verification, delegationhelix-sdk-js
The CLI, or either MCP packagehelix-sdk-js
Anything Python — SDK, LangChain, CrewAI, MCP middlewarehelix-sdk-py
The operator UIhelix-console
These docshelix-wiki

If you are unsure whether a bug is in the server shell or the API implementation, file it against helix-core — that is where the logic lives.

One rule holds across all of them: the SDK owns the cryptography. Adapters, middleware, and examples must never hand-roll VP canonicalization, base58/base64url encoding, Ed25519 signing, or verification semantics. Two code paths meant to agree that don't is a security bug. See Coding Standards.