Service Creator
Service Creator Skill
This skill guides you on how to create background services that monitor data and proactively notify users.
Reference documents directory: {{SKILL_DIR}}/reference/
When you need detailed information on a specific topic below, use read_file to load the corresponding reference document. Do NOT read all references upfront — only load what you need for the current step.
| Reference File | When to Read |
|---|---|
reference/architecture.md |
Before designing a new service's filtering logic |
reference/dry-run.md |
When implementing dry run mode or verifying dry run output |
reference/modification.md |
When modifying an existing service |
reference/guidelines.md |
For best practices and example conversations |
reference/templates-minimal.md |
When writing service code (recommended starting point) |
reference/templates-stock-monitor.md |
When building a data-monitoring service with local filtering |
reference/templates-python-monitor.md |
When building a Python monitoring service |
reference/templates-reminder.md |
When building a reminder/time-based service |
When to Use
Create a service when the user asks you to:
- Monitor something continuously (stocks, websites, APIs, files, etc.)
- Get notified when certain conditions are met
- Run periodic checks or tasks
- Watch for changes or events
Examples of user requests:
- "Help me monitor XX stock, notify me if it drops more than 5%"
- "Watch this API endpoint and tell me when it returns data"
- "Check my server status every 5 minutes"
- "Monitor this folder for new files"
Architecture Overview
Services use a two-layer filtering pattern: Local Rules Filter → Invoke API (LLM Evaluation).
Read reference/architecture.md for full details when designing filter logic.
Service Creation Workflow
Step 0: Runtime Availability Check (Automatic)
When you call service_create, the system automatically checks if the required runtime (Node.js or Python) is available. If not available, the tool returns an error.
When runtime is missing:
- Ask the user if they want you to install it
- If yes, try to install using methods that DON'T require sudo:
- macOS: Use Homebrew (
brew install node/brew install python3) - no sudo needed - If no Homebrew: Install Homebrew first, or use nvm/pyenv
- Linux/Windows: Explain to user that installation requires manual steps (sudo password or admin rights)
- macOS: Use Homebrew (
- After installation succeeds, retry
service_create
Note: You cannot use sudo or su commands as they require password interaction. Only use installation methods that work without elevated privileges.
Step 1: Create Service Metadata
Use the service_create tool with:
name: Human-readable namedescription: What the service doestype: Choose based on whether the task has a definite end:"longRunning": Never exits, runs indefinitely (e.g., "monitor stock price every 30s", "wake me up every day at 8am", "send weekly report every Monday")"scheduled": Completes and exits after task is done (e.g., "remind me at 4:30pm today", "remind me to drink water 3 times", "notify me tomorrow morning")
runtime:"node"or"python"entryFile: Entry file name (e.g.,"index.js"or"main.py")schedule: For scheduled services, interval like"*/5"(every 5 minutes)userRequest: The user's original request (verbatim)expectation: What should trigger a notification
Step 2: Write Service Code
After creating the service, write the code to the returned servicePath.
Before writing code: Read reference/templates-minimal.md for the recommended pattern. For more complex scenarios, read the appropriate full template.
Pre-built invoke helper: The service_create tool automatically generates an invoke helper file in the service directory:
- Node.js:
invoke.js— useconst { invoke, dryRunResult, DRY_RUN, SERVICE_ID } = require('./invoke'); - Python:
invoke.py— usefrom invoke import invoke, dry_run_result, DRY_RUN, SERVICE_ID
Invoke API uses named parameters (NOT positional args):
- Node.js:
await invoke({ context: CONTEXT, summary: '...', details: '...', metadata: {} }) - Python:
invoke(context=CONTEXT, summary='...', details='...', metadata={})
This eliminates the need to copy-paste the invoke boilerplate. Just import and use it.
CRITICAL: Service Code Requirements
- Service lifecycle depends on type:
longRunning: Never exit - keep running indefinitely withsetIntervalscheduled: Exit withprocess.exit(0)after task completion (e.g., reminder sent, N executions done)
- Use the pre-built invoke helper - Import from
./invokeinstead of writing your own HTTP client - Implement local filtering first - Use algorithms/rules to filter data before calling API
- Set appropriate thresholds - Use slightly lower thresholds than user specified to catch edge cases
- Only call invoke when conditions are potentially met - Save LLM tokens for important decisions
- Include context - Pass the user's original request and expectations to LLM
- Validate external API responses - Always check HTTP status code AND response structure before accessing nested properties. External APIs may return rate limit errors, unexpected JSON, or HTML error pages.
- Handle errors gracefully - Wrap all API calls in try-catch and log meaningful error messages. Don't let the service crash due to temporary API failures.
- Respect rate limits - Free APIs often have rate limits (e.g., 10-30 requests/minute). Don't poll too frequently.
- Implement dry run mode - The service MUST support dry run mode. Read
reference/dry-run.mdfor the specification and patterns. - Only use built-in modules - Only use Node.js or Python standard library modules (http, https, fs, os, json, urllib, etc.). Do NOT use third-party packages (no axios, requests, cheerio, etc.) to avoid dependency issues.
IMPORTANT: Use setInterval() (Node.js) or loops (Python) to keep the service running. For scheduled type, call process.exit(0) when the task is complete.
Step 3: Verify with Dry Run (MANDATORY)
After writing the service code, you MUST run service_dry_run to verify it works. Read reference/dry-run.md for full verification criteria, iteration rules, and failure handling.
Step 4: Start the Service
Only after a successful dry run, use service_start with the serviceId to start the service.
Modifying Existing Services
When modifying a service, read reference/modification.md first — it describes the critical synchronization rules between code, CONTEXT, and service.json.
Available Tools
service_create- Create a new serviceservice_dry_run- Run a service in dry-run mode to verify it works (MANDATORY before starting)service_list- List all services and their statusservice_start- Start a service (only after successful dry run)service_stop- Stop a serviceservice_delete- Delete a serviceservice_get_info- Get detailed service information