Documentation Index
Fetch the complete documentation index at: https://spec.conveniencepro.cc/llms.txt
Use this file to discover all available pages before exploring further.
Getting Started
This guide walks you through setting up a CTP tool development environment.
Prerequisites
- Node.js 18+ or 20+
- npm, pnpm, or yarn
- TypeScript 5.0+
Project Setup
1. Create a New Project
mkdir my-ctp-tools
cd my-ctp-tools
npm init -y
2. Install Dependencies
npm install @conveniencepro/ctp-core @conveniencepro/ctp-runtime
npm install -D typescript @types/node
Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"]
}
4. Project Structure
my-ctp-tools/
├── src/
│ ├── tools/
│ │ ├── my-tool.ts
│ │ └── another-tool.ts
│ ├── registry.ts
│ └── index.ts
├── package.json
└── tsconfig.json
Create src/tools/text-reverser.ts:
import type { ToolDefinition, ToolFunction } from '@conveniencepro/ctp-core';
// Define the result type
interface TextReverserResult {
reversed: string;
originalLength: number;
isPalindrome: boolean;
}
// Tool definition
export const textReverserDefinition: ToolDefinition = {
id: 'text-reverser',
name: 'Text Reverser',
description: 'Reverse any text string and check if it is a palindrome.',
category: 'editors',
tags: ['text', 'reverse', 'palindrome', 'string'],
method: 'POST',
parameters: [
{
name: 'text',
type: 'textarea',
label: 'Input Text',
description: 'Text to reverse',
required: true,
placeholder: 'Enter text to reverse...',
},
{
name: 'ignoreSpaces',
type: 'boolean',
label: 'Ignore Spaces',
description: 'Ignore spaces when checking for palindrome',
required: false,
defaultValue: false,
},
],
outputDescription: 'Reversed text with palindrome detection',
example: {
input: { text: 'hello', ignoreSpaces: false },
output: { reversed: 'olleh', originalLength: 5, isPalindrome: false },
},
executionMode: 'client',
};
// Tool implementation
export const textReverserFn: ToolFunction<TextReverserResult> = (params) => {
const text = params.text as string;
const ignoreSpaces = params.ignoreSpaces === true;
if (!text) {
return {
success: false,
error: 'Text is required',
errorCode: 'MISSING_REQUIRED',
};
}
const reversed = text.split('').reverse().join('');
// Check palindrome
const normalizedOriginal = ignoreSpaces
? text.toLowerCase().replace(/\s/g, '')
: text.toLowerCase();
const normalizedReversed = ignoreSpaces
? reversed.toLowerCase().replace(/\s/g, '')
: reversed.toLowerCase();
return {
success: true,
data: {
reversed,
originalLength: text.length,
isPalindrome: normalizedOriginal === normalizedReversed,
},
};
};
export default {
definition: textReverserDefinition,
fn: textReverserFn,
};
Create src/registry.ts:
import { ToolRegistry } from '@conveniencepro/ctp-runtime';
import textReverser from './tools/text-reverser';
// Create registry
export const registry = new ToolRegistry();
// Register tools
registry.register(textReverser.definition, textReverser.fn);
// Export for use
export default registry;
Create src/index.ts:
import { createRuntime } from '@conveniencepro/ctp-runtime';
import registry from './registry';
// Create runtime
const runtime = createRuntime(registry);
// Test execution
async function main() {
const result = await runtime.execute('text-reverser', {
text: 'race car',
ignoreSpaces: true,
});
console.log('Result:', JSON.stringify(result, null, 2));
}
main();
Run with:
Expected output:
{
"success": true,
"data": {
"reversed": "rac ecar",
"originalLength": 8,
"isPalindrome": true
}
}
Next Steps
Creating Tools
Learn tool creation patterns
Validation
Input and output validation
Discovery Docs
Generate OpenAPI and MCP manifests
View Examples
Reference implementations