@rayul/kordis-mcp
v0.1.0
Published
Kordis MCP server — exposes the Kordis registry (search / read / info) to any MCP client (Claude Desktop, Codex, Cursor, ChatGPT). stdio + Streamable HTTP transports; anonymous read-only over the public Kordis API.
Maintainers
Readme
@rayul/kordis-mcp
The Kordis MCP server — exposes the public Kordis registry to any MCP client (Claude Desktop, Claude Code, Codex, Cursor, …). Anonymous, read-only, no account needed.
Three tools over the registry:
| Tool | Purpose |
| -------- | ----------------------------------------------------------------------------- |
| search | Find packages (skills, project rules, custom agents) by free-text query |
| info | Inspect one package — metadata, dependencies, recent activity |
| read | JIT-fetch a skill body into the agent's context for one-shot use (no install) |
When a package is install-only (e.g. an MCP server or Claude hook), read
returns a Velko handoff instead of a body, so the user can install it
locally.
Use it
The server runs over stdio by default — point your client's MCP config at
npx @rayul/kordis-mcp and it launches on demand.
Claude Desktop — claude_desktop_config.json:
{
"mcpServers": {
"kordis": {
"command": "npx",
"args": ["-y", "@rayul/kordis-mcp"]
}
}
}Claude Code — one command:
claude mcp add kordis -- npx -y @rayul/kordis-mcpCodex — ~/.codex/config.toml:
[mcp_servers.kordis]
command = "npx"
args = ["-y", "@rayul/kordis-mcp"]Cursor — ~/.cursor/mcp.json (or project .cursor/mcp.json):
{
"mcpServers": {
"kordis": {
"command": "npx",
"args": ["-y", "@rayul/kordis-mcp"]
}
}
}Any other MCP client works the same way: run npx -y @rayul/kordis-mcp and
speak MCP over stdio.
Configuration
| Env var | Default | Effect |
| ---------------------- | -------------------------- | ----------------------------------------------------------------------------- |
| KORDIS_API_URL | https://api.kordis.store | Registry API base URL (point at a dev core-api to test) |
| KORDIS_MCP_HTTP_PORT | (unset) | If set, serve HTTP transport on 127.0.0.1:<port> instead of stdio |
| LOG_LEVEL | info | pino log level (logs go to stderr — stdout is the stdio protocol channel) |
| NODE_ENV | — | production disables pretty logging |
Transports
- stdio (default) — for local clients launched as a subprocess (the configs above). stdout carries JSON-RPC; all logs go to stderr.
- Streamable HTTP — set
KORDIS_MCP_HTTP_PORT. ServesPOST /mcp(stateless JSON-RPC) andGET /health, bound to127.0.0.1only. Intended to sit behind a reverse proxy / tunnel for a hosted endpoint.
KORDIS_MCP_HTTP_PORT=8787 npx @rayul/kordis-mcp
# POST http://127.0.0.1:8787/mcp · GET http://127.0.0.1:8787/healthA hosted endpoint at mcp.kordis.store is planned for shell-less clients
(e.g. ChatGPT) that connect over HTTP rather than spawning a subprocess.
Trust gate
This server sends X-Kordis-Surface: chatgpt-app, so the registry applies its
strict consumer trust gate — stricter than the kordis CLI by design,
because the model invokes these tools autonomously (the human is several layers
removed from the trust decision). See apps/core-api/src/services/package-service.ts
(SURFACE_TIER_ALLOWLIST, SURFACE_ALLOW_PENDING_OPT_IN).
| Check | kordis CLI | Kordis MCP |
| ----------------------------------------- | ------------ | ----------------------------- |
| review_status = passed | required | required |
| pending_review via --allow-pending | allowed | refused |
| Tier C (Claude hook, Cursor mdc-rule) | allowed | refused (install-only anyway) |
| Tier D (plugin) | allowed | refused |
Velko handoff
When read targets an install-only package (mcp-server, hook, …), the result
is a Velko handoff with two CTAs:
- Install Velko →
https://velko.app/download?from=kordis&pkg=<full_slug>(works whether or not Velko is installed). - I already have Velko →
velko://install?kordis=<full_slug>(deep link the Velko desktop app handles to pull + register the package).
Develop
# stdio against prod (default API base)
pnpm -F @rayul/kordis-mcp dev
# stdio against a local core-api
KORDIS_API_URL=http://127.0.0.1:3000 pnpm -F @rayul/kordis-mcp dev
pnpm -F @rayul/kordis-mcp typecheck
pnpm -F @rayul/kordis-mcp test
pnpm -F @rayul/kordis-mcp build # tsup → self-contained dist/ (workspace deps inlined)Layout
src/
├── index.ts Entry — selects stdio (default) or HTTP transport
├── server.ts createServer(api) — registers the 3 tools
├── http.ts Streamable HTTP transport (KORDIS_MCP_HTTP_PORT)
├── lib/
│ ├── api.ts KordisClient with the surface header
│ ├── deeplink.ts Velko URL builder
│ └── logger.ts pino → stderr
├── tools/
│ ├── search.ts · read.ts · info.ts
└── cards/ Inline-HTML result cards (OpenAI Apps SDK)
├── _styles.ts
├── SearchResultsCard.ts · PackageDetailCard.ts
└── ReadResultCard.ts · VelkoHandoffCard.ts
manifest.json OpenAI Apps SDK manifest (hosted ChatGPT path)The cards/* HTML and the openai/outputTemplate tool metadata are read only by
the OpenAI Apps SDK; other MCP clients ignore them and render the text content.
