NCI
Guides · Working with NCI

Work with your installed types, not the web

NCI is not a fixed FAQ. After you index node_modules, you can ask open-ended questions about whatever versions you actually have: Better Auth setup, Motion animation options, Effect layers, your own workspace packages. The limit is what is indexed, not a curated topic list.

This page is written for you in the editor, not only for the agent loop diagram in Agent integration. The same MCP tools power both; the difference is how you phrase the task and which skills you attach so answers stay tied to declaration evidence.

One habit: index once, then ask in place

  1. Install and index the project (or monorepo) you are working in.
  2. Wire MCP in Cursor, Claude, Codex, or another host so the chat can call nci_query / nci_sql.
  3. Attach the answer-quality skill when the question is about API shape, generics, or “how does this package expect me to wire it?”

You do not need a special NCI phrasing grammar. Plain questions work. What matters is that the agent fetches signatures before it narrates.

Reference a skill the way your host expects

Most agent IDEs can load a skill bundle and expose it as a slash command or @-mention. Cursor discovers skills under .cursor/skills/ (and compatible paths); the folder name becomes the command.

nci

Then combine the skill with a normal question, for example:

  • /nci-answer-quality How does Better Auth set up auth?
  • /nci-answer-quality How do I use view transitions in Motion?
  • Using nci-answer-quality, what options does zod 4 expect on z.object?

The skill does not replace MCP. It tells the agent to call NCI for proof, then answer in a fixed evidence-first shape. Host-specific paths and invocation details live in NCI skills.

Why types help humans and agents

Declaration files are the contract the compiler sees. They list what is public, which options exist, and how generics flow. When an agent reads those signatures through NCI instead of training data:

  • It reasons about your version, not a blog post from last year.
  • It sees overload rows and merged exports you would miss in a quick doc search.
  • It can reject plausible-sounding APIs that are not on the export surface.

You still think in product terms (“set up auth”, “use view transitions”). NCI maps that to symbols: exact names when you know them, FTS phrases when you do not.

The answer-quality protocol (short)

When nci-answer-quality is in scope, insist on this order:

StepWhat you are doing
1. Decision symbols

Name the exports or types that decide correctness (betterAuth, BetterAuthOptions, a combinator, a client factory).

2. Signature proof

Pull declarations with MCP nci_query (evidence preferred) pinned to package + package_version.

3. Derived conclusion

Explain only what follows from those signatures (generics, return type, required fields).

4. Wrong alternative

State one tempting mistake and why the types rule it out (wrong import path, reversed generic, option that does not exist).

5. Usage snippet

Show a call site that matches the evidence.

6. Confidence

Say what was signature-backed vs assumed (runtime config, framework wiring).

Tool-level detail (active-package first, when to use find vs evidence, SQL joins) stays in the Agent primer.

Example: Better Auth setup (MCP evidence)

Question: How does Better Auth set up auth?

Decision symbols: betterAuth, BetterAuthOptions.

Relevant signatures (from nci_query evidence on better-auth@1.6.5):

declare const betterAuth: <Options extends BetterAuthOptions>( options: Options & {} ) => Auth<Options>;

Two public rows share that signature: dist/auth/minimal.d.mts (minimal / without Kysely) and dist/auth/full.d.mts (full mode with Kysely). JSDoc on the full entry points at better-auth/minimal when you want adapter-only database config.

BetterAuthOptions is the large options object: baseURL, basePath (default /api/auth), secret, database, emailAndPassword, plugins, session/account hooks, and more. Setup is “call betterAuth with a typed options object; get Auth<Options> back.”

Wrong alternative: Importing a non-existent createAuth() factory or passing a bare connection string where the type expects database to be a pool, dialect, or adapter object. The initializer name is betterAuth, and database is structured in BetterAuthOptions, not a single string field.

Correct usage snippet:

import { betterAuth } from "better-auth"; // or: import { betterAuth } from "better-auth/minimal"; export const auth = betterAuth({ baseURL: process.env.BETTER_AUTH_URL, database: /* pool | adapter per BetterAuthOptions */, emailAndPassword: { enabled: true }, });

Confidence: Signature-backed for entrypoint name, return type, and options surface. Route mounting, middleware, and env var names are convention + docs beyond the snippet.

Example: vague product ask (Motion view transitions)

Question: How do I use view transitions in the Motion package?

This is the kind of question people ask in plain language. NCI still has to map it to real exports. Pin motion@12.38.0 and run nci_query evidence with phrase view transition. If you also try an exact symbol first, most people start with ViewTransition; then phrase hits reveal the Motion names you can verify next, such as animateView and ViewTransitionOptions.

What a name-only lookup shows

On motion@12.38.0, exact lookup for ViewTransition returns nothing. That is easy to misread as “Motion doesn’t support view transitions.” It usually means that export name is not on "motion" at this version, not that the feature is missing altogether.

Phrase search is what answers the question. The same evidence call with view transition surfaces names you would not have typed cold, including ViewTransitionOptions, animateView, and related ViewTransitionTarget members. Multi-word product language maps to camelCase symbols in the index; that is why you lead with the phrase, then pull signatures for what it returns.

What the types actually offer

The API that shows up for this question is declared in motion-dom and indexed under motion. The symbols that matter: animateView, ViewTransitionOptions, ViewTransitionBuilder.

Relevant signatures (from nci_query evidence on motion@12.38.0):

declare function animateView( update: () => void | Promise<void>, defaultOptions?: ViewTransitionOptions ): ViewTransitionBuilder; type ViewTransitionOptions = AnimationOptions & { interrupt?: "wait" | "immediate"; };

You pass a callback that performs the DOM update, optional default transition settings, then chain on the builder: .get(subject), then .enter, .exit, .layout, and related helpers for the pieces you want to animate.

Wrong alternative: Stopping after an empty ViewTransition search, or importing ViewTransition from "motion" because the browser has document.startViewTransition. On this index, the Motion entry point is animateView (found via the phrase, not from the wording of the question). React’s ViewTransition and Motion+’s AnimateView are separate packages you might see in docs, not exports to assume from "motion".

Correct usage snippet:

import { animateView } from "motion"; animateView( () => { showNextPanel(); }, { type: "spring", stiffness: 400, damping: 40, interrupt: "immediate", } ) .get(".panel") .enter({ opacity: [0, 1] }, { type: "tween", duration: 0.35 }) .then(() => {});

Confidence: Signature-backed for what exists and what does not on motion@12.38.0. Wiring the update callback to the browser transition and choosing your app’s import path are outside the declaration snippet.

Prompt patterns that work well

You wantTry
Exact API you rememberSkill + package name + symbol: “/nci-answer-quality What is betterAuth’s return type in better-auth 1.6?”
Exploratory wiringSkill + task: “How should I configure session cookies per the types?”
Compare overloads“Fetch overloads for symbol id … and explain when to use each.”
Monorepo local packageIndex workspace scope, then ask about @my-org/shared the same way as npm.

Pin versions when you have multiple (better-auth 1.4.6 and 1.6.5 in one database). Use active_package (or explicit package_version) so evidence matches the install you are editing.

What NCI will not do

  • Run tsc or prove runtime behavior.
  • Replace reading framework guides for deployment and security checklists.
  • Answer about packages you never indexed.

Stay inside declarations and treat strong claims as requiring a cited signature.