Prototype · Preview: every server in the official registry, synced every 30 minutes. Reviews and accounts come in a later step.
PopNx MCPMCP servers for people who use AI · explained in plain words

MCP Ts Template

by cyanheadsversion 3.0.9i★ –iRuns on your computer
Registry nameio.github.cyanheads/mcp-ts-template

Install

Overview

Description from the maker (original English)

TypeScript template for building MCP servers with declarative tooling, observability, and auth.

PopNx MCP’s three pillars

These three are never merged into one score: opinions, measurements and popularity are different things.

What you can do with it

We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.

Install

Pick the AI app you use, then copy the settings.

Before you install

  • Basic checks: 1 of 1 passed
  • Runs on your computer with your user’s permissions (files, network, apps).
  • You fill in yourself: MCP_LOG_LEVEL

You need

  • npmNode.js installed (for the npx command)

Which app do you use?

Pick your app above. We remember it, so next time the button says “Install in …”.

Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json

{
  "mcpServers": {
    "ts-template": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-ts-template",
        "run",
        "start:stdio"
      ],
      "env": {
        "MCP_LOG_LEVEL": "your-value"
      }
    }
  }
}

Run this in your terminal

claude mcp add ts-template --env MCP_LOG_LEVEL=your-value -- npx -y mcp-ts-template run start:stdio

Fill in the empty values before running it.

Open in Cursor

Or copy the settings yourself

Paste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json

{
  "mcpServers": {
    "ts-template": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-ts-template",
        "run",
        "start:stdio"
      ],
      "env": {
        "MCP_LOG_LEVEL": "your-value"
      }
    }
  }
}

Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.

Open in VS Code

Or copy the settings yourself

Paste into .vscode/mcp.json in your project

{
  "servers": {
    "ts-template": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "mcp-ts-template",
        "run",
        "start:stdio"
      ],
      "env": {
        "MCP_LOG_LEVEL": "your-value"
      }
    }
  }
}

Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.

This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.

Your choice stays on this device in a cookie; no account needed.

Values you fill in

  • MCP_LOG_LEVEL env
    Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').

These settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.

What it can do

Runs on your computer; the tool list appears in your AI app after you install it.

Basic checksi

We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 8, 2026

  • ✓ Pass

    Maker matches the repo

    The registry name was verified with the GitHub account cyanheads, which owns the repo

  • … Not checked yet

    Still maintained

    We have not read this repo from GitHub yet

  • … Not checked yet

    Has a licence

    We have not read this repo from GitHub yet

  • – Not applicable

    Endpoint responds

    This one runs on your computer; there is no internet endpoint

  • – Not applicable

    Sign-in with OAuth

    Runs on your computer and uses local settings instead

  • … Not checked yet

    No hidden instructions in tool descriptions

    Runs on your computer; we can only read tool lists from internet endpoints

Compared with others in Developer toolsi

  • More stars than 0% of the other 5548 servers in this category
  • Published to the registry more recently than 6% of the other 5548 servers in this category
  • Basic checks equal to or better than 100% of the other 5548 servers in this category

Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.

Common questions

Is MCP Ts Template safe?

It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.

What keys or codes does it need?

The registry does not list a required key, though some servers ask you to sign in on first use.

Does it run on my computer or in the cloud?

It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).

Is it still maintained?

The GitHub repo last changed –, and the latest version (3.0.9) reached the registry 8 months ago.

Which apps can use it?

Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.

What can I use instead?

In the same category: GitHub, Desktop Commander, Cloudflare MCP

Alternatives

Servers in the same category from other makers, sorted by stars.

Reading a card:↓ Downloads per weeki★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi

GitHub

GitHub’s official server lets AI read and manage code, issues and pull requests in your account. Use GitHub’s hosted version or run it locally with Docker.

by githubWidely used★ 34.2KUpdated 5 days ago

Computer or cloud

Desktop Commander

MCP server for terminal commands, file operations, and process management

by wonderwhy-erWidely used↓ 709.6K/wk★ 10.2KUpdated 17 days ago

Runs on your computer

Cloudflare MCP

Cloudflare MCP servers

by cloudflareWidely used★ 4.4KUpdated 14 months ago

Runs in the cloud✓ mcp.cloudflare.com

README from the maker

Open the README

Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.

@cyanheads/mcp-ts-core Agent-native TypeScript framework for building MCP servers. Runtime infrastructure for your server, and the agent skills to build, test, and ship it.

Quick start · Capabilities · API reference · Examples


Build AI tools for anything you can describe

Connect an API, a dataset, or a workflow to an AI agent through the Model Context Protocol (MCP). Your project holds the domain code; @cyanheads/mcp-ts-core handles the auth, storage, logging, and transports underneath it.

Agent-native. Every scaffold ships the framework reference and a set of Agent Skills: workflows for designing tools, writing tests, reviewing security, and cutting releases. You decide what the server does; your agent follows the skills to build it.

The framework stays a dependency. Infrastructure fixes arrive as package upgrades. Run the maintenance skill and your agent bumps core, syncs the latest skills, and adopts what changed.

Quick start

Servers run on Bun, Node.js 24+, or Cloudflare Workers.

bunx @cyanheads/mcp-ts-core init my-mcp-server

cd my-mcp-server bun install

The scaffold includes a source tree, build and test configuration, CLAUDE.md/AGENTS.md, Agent Skills, and plugin metadata for Claude Code and Codex. Open it in Claude Code, Codex, or another agent and describe what you want:

Build an MCP server for my team's inventory API. We need to find products, check stock across warehouses, investigate stock movements, and record adjustments and transfers. Let's get started.

Already have a TypeScript project? Run bun add @cyanheads/mcp-ts-core and register your definitions with createApp().

A tool is a schema and a function

This is a complete server that searches a three-item catalog. To try it, replace the scaffold's src/index.ts with it:

import { createApp, tool, z } from '@cyanheads/mcp-ts-core';

const catalog = ['Notebook', 'Mechanical pencil', 'Desk lamp'];

const search = tool('catalog_search', { description: 'Search catalog item names. An empty query lists all items.', annotations: { readOnlyHint: true }, input: z.object({ query: z.string().describe('Text to find in an item name'), }), output: z.object({ items: z.array(z.string()).describe('Matching item names'), }), async handler({ query }) { return { items: catalog.filter((name) => name.toLowerCase().includes(query.toLowerCase()), ), }; }, });

await createApp({ name: 'catalog-mcp-server', title: 'catalog-mcp-server', tools: [search] });

Build and run it over HTTP:

bun run rebuild

bun run start:http

Point your MCP client at http://127.0.0.1:3010/mcp (Streamable HTTP), or have the client launch it over stdio with bun /absolute/path/to/dist/index.js.

What comes with it

You need to…The framework provides
Give an assistant useful capabilitiesTyped builders for tools, resources, prompts, and interactive MCP Apps
Help an agent use those capabilities correctlyServer instructions, result enrichment, and declared errors with recovery guidance
Control access and keep stateJWT/OAuth, per-definition scopes, and tenant-scoped storage with swappable backends
Run locally or host a servicestdio and HTTP on Bun/Node.js; a separate entry point for Cloudflare Workers
Understand failures and catch mistakesStructured logs, optional OpenTelemetry, definition linting, contract tests, and fuzz testing

Optional integrations (DuckDB, Supabase, the OpenTelemetry SDK) are peer dependencies; install them when you need them.

Give agents useful results

Two declared contracts shape what an agent gets back. enrichment carries success-path context (totals, the parsed query, empty-result notices), populated with ctx.enrich(). errors lists each expected failure with its recovery guidance, and the handler throws one with the typed ctx.fail().

runSearch(query, limit) stands in for your search backend. It returns { items, total, parsed }, or null when the index is down:

import { createApp, tool, z } from '@cyanheads/mcp-ts-core';

import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';

const search = tool('search', { description: 'Search the catalog and return ranked matches.', annotations: { readOnlyHint: true }, input: z.object({ query: z.string().describe('Search terms'), limit: z.number().int().min(1).default(10).describe('Max results'), }), output: z.object({ items: z.array(z.string()).describe('Matching item names, best first'), }), enrichment: { effectiveQuery: z.string().describe('Query as the server parsed it'), totalCount: z.number().describe('Total matches before the limit'), notice: z.string().optional().describe('Guidance when nothing matched'), }, errors: [ { reason: 'index_unavailable', code: JsonRpcErrorCode.ServiceUnavailable, when: 'The upstream search index is unreachable.', retryable: true, recovery: 'Retry in a few seconds — the index may be briefly unavailable.', }, ], handler: async (input, ctx) => { const res = await runSearch(input.query, input.limit); if (!res) throw ctx.fail('index_unavailable'); ctx.enrich({ effectiveQuery: res.parsed, totalCount: res.total }); if (res.items.length === 0) { ctx.enrich({ notice: No matches for "${input.query}". Try broader terms. }); } return { items: res.items }; // enrichment never rides in the domain return }, });

await createApp({ tools: [search] });

Both contracts are advertised in tools/list, so clients see them before calling, and the definition linter checks the handler against them. A failure with a declared reason reaches the client carrying that entry's recovery hint, and every tool error carries the request ID its server log records share.

Same data across client surfaces

MCP hosts differ in which part of a tool result they hand the agent: structuredContent (JSON), content[] (text), or both. The framework fills both with the same data, so the agent sees the same result on any host.

format() renders the text side; without one, content[] gets JSON. The format-parity lint rule fails lint:mcp if any output field is missing from the rendered text. Enrichment needs no format() entry, because the framework adds it to both surfaces. This formatter renders the items as a markdown list:

format: (result) => [{

type: 'text', text: result.items.length > 0 ? result.items.map((name) => - ${name}).join('\n') : 'No matching items.', }],

Resources

Resources expose data at a URI. This one reads from your own getItem() service:

import { resource, z } from '@cyanheads/mcp-ts-core';

export const itemData = resource('items://{itemId}', { description: 'Retrieve item data by ID.', params: z.object({ itemId: z.string().describe('Item ID'), }), async handler(params) { return await getItem(params.itemId); }, });

Everything registers through createApp() in your entry point:

await createApp({

name: 'my-mcp-server', title: 'my-mcp-server', // display name in client UIs tools: allToolDefinitions, resources: allResourceDefinitions, prompts: allPromptDefinitions, instructions: 'Brief composition hints for the model.', // optional, sent on every initialize skills: 'skills', // optional, serves root skills/ over the SEP-2640 Skills extension });

On Cloudflare Workers, createWorkerHandler() takes the same definitions from a separate entry point.

Runtime and integration details

  • Auth and storage: Declare auth: ['scope'] on a definition and the scope is checked, under JWT or OAuth, before the handler runs. ctx.state is tenant-scoped storage over in-memory, filesystem, Supabase, or Cloudflare D1/KV/R2, chosen by config.
  • Client interaction: Return ctx.requestInput(...) to ask the user for input, the client's model for a sample, or the client for its roots. The handler runs again with the answers on ctx.inputs.
  • Protocol compatibility: HTTP serves 2026-07-28 clients (per-request _meta envelope) and session-based 2025-era clients. The SDK's compatibility layer handles input requests for the older ones.
  • Server presentation: instructions gives the model server-wide guidance once, at initialize, instead of in every tool description. Identity fields (title, websiteUrl, description, icons) populate the client's server info, the /.well-known/mcp.json server card, and the HTTP landing page. skills: 'skills' serves the Agent Skills the server publishes in root skills/ through the SEP-2640 Skills extension (skills/list, skills/get), checked at build time by lint:packaging.
  • Definition checks: lint:mcp checks names, schemas, scopes, annotations, format parity, and JSON Schema portability. It runs at build time, never at startup, so a new rule can't break a deployed server.
  • DataCanvas: An optional DuckDB workspace where agents run SQL across staged API results and export CSV, Parquet, or JSON. Agents share a workspace by passing its canvas token. Enable it with CANVAS_PROVIDER_TYPE=duckdb and @duckdb/node-api (Bun or Node.js only). brapi-mcp-server walks through loading API results into a dataframe and querying it.
  • Mirror: The /mirror module keeps a persistent local copy of a bulk upstream dataset in embedded SQLite with an optional FTS5 index, so tools query it locally instead of paging the live API on every call. You write the sync ingester and the schema; the framework handles storage, resumable initial loads, and incremental refreshes. Bun or Node.js only (better-sqlite3 is an optional peer on Node). faa-aircraft-registry-mcp-server serves the full FAA registry this way.

See the framework reference for configuration and handler patterns, and the observability guide for Pino logging and OpenTelemetry traces and metrics.

Server structure

my-mcp-server/

src/ index.ts # createApp() entry point worker.ts # createWorkerHandler() (optional) config/ server-config.ts # Server-specific env vars services/ [domain]/ # Domain services (init/accessor pattern) mcp-server/ tools/definitions/ # Tool definitions (.tool.ts) resources/definitions/ # Resource definitions (.resource.ts) prompts/definitions/ # Prompt definitions (.prompt.ts) package.json tsconfig.json # extends @cyanheads/mcp-ts-core/tsconfig.base.json CLAUDE.md / AGENTS.md # Server conventions; points to core's framework reference

Framework infrastructure lives in node_modules; your source t

Only the beginning is shown; read the rest in the repo

Ask PopNx