← Back to Skills

connection-schema-design

majiayu000
Updated Today
1 views
58
9
58
View on GitHub
Designdesign

About

This skill provides design rules for creating connection profile and state schemas in Claude Code. It mandates extending core profiles instead of creating custom ones and requires connection states to include base properties like expiresIn. Use it when implementing connection schemas to ensure compliance with the platform's standards.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/majiayu000/claude-skill-registry
Git CloneAlternative
git clone https://github.com/majiayu000/claude-skill-registry.git ~/.claude/skills/connection-schema-design

Copy and paste this command in Claude Code to install this skill

Documentation

Connection Profile & State Design Rules

Rules for designing connectionProfile.yml and connectionState.yml schemas

🚨 CRITICAL RULES

Rule 1: Always Extend Core Profiles

NEVER create custom profiles from scratch - ALWAYS extend core profiles

# ❌ WRONG - Custom profile
type: object
properties:
  apiKey:
    type: string

# βœ… CORRECT - Extend core profile
$ref: './node_modules/@zerobias-org/types-core/schema/tokenProfile.yml'

Rule 2: connectionState MUST Extend baseConnectionState

🚨 MANDATORY: connectionState.yml MUST extend baseConnectionState.yml for expiresIn

# βœ… CORRECT - Extends base with expiresIn
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/baseConnectionState.yml'
  - type: object
    properties:
      accessToken:
        type: string

# ❌ WRONG - Missing baseConnectionState
type: object
properties:
  accessToken:
    type: string
  # Missing expiresIn!

WHY: Server uses expiresIn to schedule automatic token refresh cronjobs

Rule 3: expiresIn Must Be in Seconds

# βœ… CORRECT
expiresIn:
  type: integer
  description: Token expiry time in SECONDS from now

# ❌ WRONG
expiresAt:
  type: string  # Don't use expiresAt, convert to expiresIn

Calculation: expiresIn = Math.floor((expiresAt - now) / 1000)

Core Profile Selection

Available Core Profiles

ProfileWhen to UseContains
tokenProfile.ymlAPI Key, Bearer Token, PATtoken
oauthClientProfile.ymlOAuth2 Client CredentialsclientId, clientSecret
oauthTokenProfile.ymlOAuth2 with RefreshclientId, clientSecret
basicConnection.ymlUsername/Password, Email/Passwordusername, password

Path: ./node_modules/@zerobias-org/types-core/schema/{profileName}.yml

Selection Decision Tree

@credential-manager provides authMethodType:

IF authMethodType == "bearer-token" OR "api-key"
  β†’ EXTEND tokenProfile.yml

IF authMethodType == "oauth2-client-credentials"
  β†’ EXTEND oauthClientProfile.yml

IF authMethodType == "oauth2-authorization-code"
  β†’ EXTEND oauthTokenProfile.yml

IF authMethodType == "basic-auth"
  β†’ EXTEND basicConnection.yml

Available Core States

StateWhen to UseContains
tokenConnectionState.ymlSimple token authaccessToken + expiresIn
oauthTokenState.ymlOAuth with refreshaccessToken + refreshToken + expiresIn

State Selection

IF requiresRefresh == false
  β†’ EXTEND tokenConnectionState.yml

IF requiresRefresh == true
  β†’ EXTEND oauthTokenState.yml

Common Patterns

Pattern 1: Simple API Token

# connectionProfile.yml
$ref: './node_modules/@zerobias-org/types-core/schema/tokenProfile.yml'

# connectionState.yml
$ref: './node_modules/@zerobias-org/types-core/schema/tokenConnectionState.yml'

Pattern 2: OAuth Client Credentials

# connectionProfile.yml
$ref: './node_modules/@zerobias-org/types-core/schema/oauthClientProfile.yml'

# connectionState.yml (no refresh)
$ref: './node_modules/@zerobias-org/types-core/schema/tokenConnectionState.yml'

Pattern 3: OAuth with Refresh Token

# connectionProfile.yml
$ref: './node_modules/@zerobias-org/types-core/schema/oauthTokenProfile.yml'

# connectionState.yml
$ref: './node_modules/@zerobias-org/types-core/schema/oauthTokenState.yml'

Pattern 4: Custom Fields (Extend Core)

# connectionProfile.yml - Add organizationId
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/tokenProfile.yml'
  - type: object
    required: [organizationId]
    properties:
      organizationId:
        type: string
        description: Organization identifier for API access

# connectionState.yml - Add extra state
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/tokenConnectionState.yml'
  - type: object
    properties:
      organizationName:
        type: string
        description: Cached organization name

Connection Profile Scope

What Belongs in connectionProfile

ONLY connection parameters - minimal set needed to CONNECT

# βœ… GOOD - Connection parameters
- token / apiKey / clientId / clientSecret
- baseUrl (if API has multiple environments)
- organizationId (if required to authenticate)

# ❌ BAD - Operation parameters
- limit (pagination parameter)
- projectId (operation scope, not connection scope)
- fields (query parameter)

Rule: If you can connect WITHOUT it, it's an operation parameter (not profile)

Check for Additional Optional Parameters

Always review API docs for environment-specific optional parameters:

# Example: Service has optional region parameter
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/tokenProfile.yml'
  - type: object
    properties:
      region:
        type: string
        description: Optional region for multi-region deployments
        enum: [us-east-1, eu-west-1, ap-southeast-1]
    # region is optional, but include it if API docs mention it

Don't omit parameters that some environments might need!

🚨 CRITICAL: Check Parent Schema First

Before adding ANY property, check what the parent schema provides:

# Check what tokenProfile.yml provides
cat node_modules/@zerobias-org/types-core/schema/tokenProfile.yml

# Check what basicConnection.yml provides
cat node_modules/@zerobias-org/types-core/schema/basicConnection.yml

# Check what baseConnectionState.yml provides
cat node_modules/@zerobias-org/types-core/schema/baseConnectionState.yml

Avoid Semantic Duplication

# ❌ WRONG - basicConnection already has uri
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/basicConnection.yml'
  - type: object
    properties:
      url:    # Duplicate! basicConnection has uri
        type: string

# βœ… CORRECT - Use parent's uri, or extend if truly different
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/basicConnection.yml'
  # uri is already provided by basicConnection

Semantic duplicates to avoid:

  • url / uri / baseUrl
  • token / accessToken
  • username / user / userName
  • password / pass / pwd

🚨 CRITICAL: ALWAYS Check Product Documentation

Before finalizing connectionProfile, check product docs for ALL auth parameters:

# Example: Missing mfaCode from product docs
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/basicConnection.yml'
  - type: object
    properties:
      mfaCode:    # Found in product docs!
        type: string
        description: Multi-factor authentication code (optional)

Don't assume - verify:

  1. Read product documentation authentication section
  2. Look for optional parameters (region, environment, mfaCode, etc.)
  3. Include ALL mentioned parameters (even if optional)
  4. Don't omit parameters some environments might need

🚨 CRITICAL: Connection Scope MUST NOT Limit Operations

NEVER add organization/project/workspace IDs to connection:

# ❌ WRONG - Limits connection to single organization
connectionState:
  allOf:
    - $ref: './node_modules/@zerobias-org/types-core/schema/baseConnectionState.yml'
    - type: object
      properties:
        accessToken:
          type: string
        organizationId:    # NO! Limits scope
          type: string

# βœ… CORRECT - Connection works across all organizations
connectionState:
  allOf:
    - $ref: './node_modules/@zerobias-org/types-core/schema/baseConnectionState.yml'
    - type: object
      properties:
        accessToken:
          type: string
  # organizationId is operation parameter, NOT connection parameter

WHY: Connection should be reusable across all scopes. Use operation parameters for scope.

Scope identifiers belong in operation parameters, NOT connection:

  • ❌ organizationId in connection
  • ❌ workspaceId in connection
  • ❌ projectId in connection
  • ❌ teamId in connection
  • βœ… These are operation parameters (use in API paths)

🚨 CRITICAL: Only Add Used Fields (for connectionState)

For connectionState - don't add fields "just in case" - only add what's actually USED:

# ❌ WRONG - identityId not used anywhere
connectionState:
  properties:
    accessToken: string
    identityId: string    # Where is this used? Nowhere!

# βœ… CORRECT - Only fields that are actually used
connectionState:
  properties:
    accessToken: string
  # If connect() doesn't return identityId, don't add it

Ask:

  1. Does connect() method return this field?
  2. Do operations use this field?
  3. Is it needed for refresh/reconnect? If NO to all β†’ don't add it

For connectionProfile - include environment-optional fields:

# βœ… CORRECT - Include optional fields that some environments need
allOf:
  - $ref: './node_modules/@zerobias-org/types-core/schema/tokenProfile.yml'
  - type: object
    properties:
      region:
        type: string
        description: Optional region (needed in some deployments)
      mfaCode:
        type: string
        description: Multi-factor authentication code (optional)
    # These aren't required, but include them if product docs mention them

connectionProfile vs connectionState:

  • connectionProfile: Include optional fields that might be needed in some environments (region, mfaCode, etc.)
  • connectionState: Only fields actually used by connect() or operations

Validation Checklist

Before finalizing connection schemas:

  • Checked parent schema - no semantic duplicates (url/uri, token/accessToken)
  • Checked product docs thoroughly - all auth parameters included (mfaCode, region, etc.)
  • connectionProfile extends a core profile (NOT custom)
  • connectionState extends baseConnectionState (includes expiresIn)
  • expiresIn is in seconds (integer), not expiresAt timestamp
  • If refresh capability: state extends oauthTokenState
  • If simple token: state extends tokenConnectionState
  • Custom fields use allOf to extend core
  • All required fields marked as required
  • Checked API docs for optional connection parameters (region, environment, etc.)
  • Profile contains ONLY connection parameters (not operation parameters)
  • NO scope limitation - no organizationId/projectId/workspaceId in connection
  • Only used fields - every state field is actually used by connect() or operations
  • Minimal set needed to connect (don't add operation scope parameters)

Common Mistakes

❌ Creating Custom Profile

# DON'T DO THIS
type: object
properties:
  apiKey: string
  baseUrl: string

Fix: Extend tokenProfile.yml

❌ Missing baseConnectionState

# DON'T DO THIS
type: object
properties:
  accessToken: string

Fix: Extend baseConnectionState or tokenConnectionState

❌ Using expiresAt Instead of expiresIn

# DON'T DO THIS
expiresAt:
  type: string
  format: date-time

Fix: Convert to expiresIn (seconds) in connect() method

❌ No expiresIn for Refresh Tokens

# DON'T DO THIS
properties:
  accessToken: string
  refreshToken: string
  # Missing expiresIn!

Fix: MUST extend baseConnectionState for expiresIn

Remember

  1. Always extend core profiles - Never create custom from scratch
  2. Always extend baseConnectionState - Server needs expiresIn for cronjobs
  3. expiresIn in seconds - Not timestamps, not milliseconds
  4. Use allOf for extensions - Add custom fields via composition
  5. Receive data from @credential-manager - Don't guess auth method

Connection schemas are YAML schemas - design them like api.yml schemas!

GitHub Repository

majiayu000/claude-skill-registry
Path: skills/connection-schema-design

Related Skills

content-collections

Meta

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

View skill

creating-opencode-plugins

Meta

This skill provides the structure and API specifications for creating OpenCode plugins that hook into 25+ event types like commands, files, and LSP operations. It offers implementation patterns for JavaScript/TypeScript modules that intercept and extend the AI assistant's lifecycle. Use it when you need to build event-driven plugins for monitoring, custom handling, or extending OpenCode's capabilities.

View skill

langchain

Meta

LangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.

View skill

Algorithmic Art Generation

Meta

This skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.

View skill