Agent skill

add-provider

Add a new storage or service provider to the core package. Use when implementing a new backend for StorageService (e.g., a new database) or a new service provider (e.g., a new LLM backend).

Stars 131
Forks 24

Install this agent skill to your Project

npx add-skill https://github.com/cyanheads/mcp-ts-core/tree/main/skills/add-provider

Metadata

Additional technical details for this skill

type
reference
author
cyanheads
version
1.0
audience
internal

SKILL.md

Context

Providers implement interfaces defined in core. They are selected at runtime via config (e.g., STORAGE_PROVIDER_TYPE). Tier 3 providers lazy-load their dependencies to keep the core bundle small.

Provider interfaces

Domain Interface file
Storage src/storage/core/IStorageProvider.ts
LLM src/services/llm/core/ILlmProvider.ts
Speech src/services/speech/core/ISpeechProvider.ts

Read the relevant interface fully before implementing — each has distinct required members. ISpeechProvider in particular requires readonly name, readonly supportsTTS, readonly supportsSTT, and healthCheck() in addition to the capability methods; these flags drive routing in SpeechService.

File conventions

Provider file location and naming differ by domain:

  • Storage — nested subdirectory, PascalCase file: src/storage/providers/{{provider-name}}/{{provider-name}}Provider.ts (e.g., src/storage/providers/inMemory/inMemoryProvider.ts)

  • LLM / Speech — flat directory, kebab-case with .provider.ts suffix: src/services/llm/providers/{{provider-name}}.provider.ts src/services/speech/providers/{{provider-name}}.provider.ts (e.g., src/services/llm/providers/openrouter.provider.ts, src/services/speech/providers/elevenlabs.provider.ts)

Steps

  1. Identify the provider interface — read the interface file for the target domain (see table above).

  2. Create the provider file following the file convention for its domain (see above).

  3. Implement the interface — all methods must be implemented.

  4. Lazy-load dependencies if Tier 3:

    typescript
    let _client: SomeClient | undefined;
    async function getClient(): Promise<SomeClient> {
      if (!_client) {
        const { SomeClient } = await import('some-package');
        _client = new SomeClient(/* config */);
      }
      return _client;
    }
    
  5. Register the provider — the registration point differs by domain:

    • Storage — add a case to the switch in src/storage/core/storageFactory.ts inside createStorageProvider(). Import the new provider class at the top of that file.

    • Speech — two changes required:

      1. Add the new provider string literal to the provider union in SpeechProviderConfig (src/services/speech/types.ts, field provider).
      2. Add a case to the switch in createSpeechProvider() (src/services/speech/core/SpeechService.ts). Import the new provider class at the top of that file.
    • LLM — currently only one provider exists (OpenRouterProvider); it is instantiated directly in src/core/app.ts rather than through a factory switch. Add a factory function or extend app.ts as needed, then update ILlmProvider consumers accordingly.

  6. Update the Worker-compatible provider list if the new storage provider runs in Cloudflare Workers. The list is an inline array in storageFactory.ts at the isServerless() guard:

    typescript
    // src/storage/core/storageFactory.ts ~line 112
    !['in-memory', 'cloudflare-r2', 'cloudflare-kv', 'cloudflare-d1'].includes(providerType)
    

    Add the new provider string to this array. Non-storage providers have no equivalent gate.

  7. Add the dependency as an optional peer dependency in package.json if Tier 3.

  8. Run bun run devcheck to verify.

Checklist

  • Provider file created with JSDoc @fileoverview + @module header
  • Interface fully implemented (including name, supportsTTS/supportsSTT for speech)
  • Tier 3 dependencies lazy-loaded (not top-level imports)
  • Registered in the correct factory for the domain (see Step 5)
  • Speech: provider literal added to SpeechProviderConfig union in types.ts
  • Storage: Worker-compatible array in storageFactory.ts updated if applicable
  • Optional peer dependency added to package.json if Tier 3
  • bun run devcheck passes
  • Integration tested with the target backend

Expand your agent's capabilities with these related and highly-rated skills.

cyanheads/mcp-ts-core

add-resource

Scaffold a new MCP resource definition. Use when the user asks to add a resource, expose data via URI, or create a readable endpoint.

131 24
Explore
cyanheads/mcp-ts-core

field-test

Exercise tools, resources, and prompts with real-world inputs to verify behavior end-to-end. Use after adding or modifying definitions, or when the user asks to test, try out, or verify their MCP surface. Calls each definition with realistic and adversarial inputs and produces a report of issues, pain points, and recommendations.

131 24
Explore
cyanheads/mcp-ts-core

release

Verify release readiness and publish. The git wrapup protocol handles version bumps, changelog, README, commits, and tagging during the coding session. This skill verifies nothing was missed, runs final checks, and presents the irreversible publish commands.

131 24
Explore
cyanheads/mcp-ts-core

add-export

Add a new subpath export to the @cyanheads/mcp-ts-core package. Use when creating a new public API surface that consumers import from a dedicated subpath (e.g., @cyanheads/mcp-ts-core/newutil).

131 24
Explore
cyanheads/mcp-ts-core

api-errors

McpError constructor, JsonRpcErrorCode reference, and error handling patterns for `@cyanheads/mcp-ts-core`. Use when looking up error codes, understanding where errors should be thrown vs. caught, or using ErrorHandler.tryCatch in services.

131 24
Explore
cyanheads/mcp-ts-core

api-utils

API reference for all utilities exported from `@cyanheads/mcp-ts-core/utils`. Use when looking up utility method signatures, options, peer dependencies, or usage patterns.

131 24
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results