# Tool Development Context - docs/tools/

## Purpose

This directory contains comprehensive documentation for all MCP tools. When developing new tools or understanding existing ones, reference these documents for complete context.

## Key Documents

### Core Tool Documentation

1. **[TOOLS_SUMMARY.md](./TOOLS_SUMMARY.md)** - Overview of all 73 tools organized by domain
   - Admin tools (10): users, groups, platforms, roles, settings
   - Content tools (21): spaces, entries, assets, types, categories
   - Channels tools (21): sites, pages, widgets, templates, navigation
   - Customers tools (15): realms, users, forms, submissions

2. **[RELEASE_TOOLS.md](./RELEASE_TOOLS.md)** - Publishing workflow
   - Two-step release process
   - Get publishable elements → Create release
   - Critical for publishing widgets, pages, templates, menus

3. **[WIDGET_TOOLS.md](./WIDGET_TOOLS.md)** - Widget management
   - Widget definitions (creation, update, variables)
   - Publishing widgets (must be published before use)
   - Widget UUIDs are OIDs (40-char hex), not RFC 4122 UUIDs

4. **[PAGE_WIDGET_TOOLS.md](./PAGE_WIDGET_TOOLS.md)** - Widget positioning on pages
   - Adding widgets to WIDGET PAGES only (not content/origination pages)
   - `sync` parameter (render-blocking vs non-blocking)
   - Column validation based on `grid_type`

5. **[PAGE_PARAMETERS_EXPLAINED.md](./PAGE_PARAMETERS_EXPLAINED.md)** - Critical parameters
   - `has_router` dual purpose:
     - Widget pages: Client-side JS routing (SPAs)
     - Content pages: Server-side slug routing
   - `sync` parameter: Widget loading mode
   - Performance implications and best practices

## Architecture Context

### Rendering System

**Must understand before creating template/page/widget tools**:
- Read [../MODYO_SNIPPETS_ARCHITECTURE.md](../MODYO_SNIPPETS_ARCHITECTURE.md) first
- Layouts wrap entire page with `{{ html5 }}` and `{{ content_for_layout }}`
- `content_for_layout` invokes grid snippet based on `page.grid_type`
- Grid snippets organize widgets using `page_grid` object
- Widget snippets handle sync/async rendering

**Key Files**:
- [../MODYO_SNIPPETS_ARCHITECTURE.md](../MODYO_SNIPPETS_ARCHITECTURE.md) - Complete rendering system
- [../MODYO_SITE_ARCHITECTURE.md](../MODYO_SITE_ARCHITECTURE.md) - Site structure
- [../MODYO_PAGE_TYPES.md](../MODYO_PAGE_TYPES.md) - Three page types

### Page Types - Critical for Tool Development

**Three distinct page types** (NEVER mix them up):

| Type | Widgets | Content | Forms | Use Case |
|------|---------|---------|-------|----------|
| **Widget Pages** | ✅ Custom widgets | ❌ | ❌ | SPAs, dashboards |
| **Content Pages** | ❌ | ✅ Liquid + Content API | ❌ | Blogs, catalogs |
| **Origination Pages** | ❌ | ❌ | ✅ Forms | Applications |

**Tool Implications**:
- `page-add-widgets` ONLY works with Widget Pages
- Content pages use `content_type_id` and Liquid templates
- Origination pages use forms and submission workflows

### Widget Types

**Two widget types** (affects deployment):

| Type | `read_only` | Editable | Deployment | Format |
|------|------------|----------|------------|--------|
| **Normal** | `false` | ✅ Yes | Modyo UI | HTML/CSS/JS |
| **CLI** | `true` | ❌ No | CLI push | Bundle or Zip |

**CLI Widget Formats**:
- **Bundle** (`zip: false`): Single HTML/CSS/JS bundle
- **Zip** (`zip: true`): Full build directory with code splitting

### Publishing Workflow

**Two-step process** (required for all publishable resources):

```typescript
// Step 1: Get what can be published
release-get-elements-to-publish({ platformSlug, siteId })

// Step 2: Create release with selected elements
release-create({
  platformSlug,
  siteId,
  data: {
    widgetDefinition: [{ id: 123, selected: true }],
    page: [{ id: 456, selected: true }],
    template: [{ id: 789, selected: true }]
  }
})
```

**What needs publishing**:
- Widget definitions (before adding to pages)
- Pages (before going live)
- Templates (snippets, layouts, CSS, JS)
- Menus (navigation structures)

## Tool Development Patterns

### Using Class-Based Tools (Recommended)

**Extend `ToolBase`** for cleaner code:

```typescript
import { ToolBase, orgValidation } from "@modyo/mcp-shared";
import { z } from "zod/v3";

class MyTool extends ToolBase {
  protected config = {
    name: "my-tool",
    description: "Tool description",
    annotations: {
      readOnlyHint: false,
      idempotentHint: false,
      destructiveHint: true,
    },
  };

  protected getParamsSchema() {
    return z.object({
      platformSlug: orgValidation,
      siteId: z.number().min(1),
      // ... other params
    });
  }

  async execute(params: z.infer<ReturnType<MyTool["getParamsSchema"]>>) {
    // getRepository is async - fetches platform config from mcp-platforms service
    const repo = await this.getRepository(MyRepository, params.platformSlug);

    const result = await repo.doSomething(params);

    return this.success(result);
  }
}

export const MyToolInstance: Tool = new MyTool();
```

See [../../src/tools/CLASS_BASED_TOOLS.md](../../src/tools/CLASS_BASED_TOOLS.md) for details.

### Common Validation Patterns

**Platform slug** (always required):
```typescript
import { orgValidation } from "@modyo/mcp-shared";

platformSlug: orgValidation
```

**Slug format** (for names/identifiers):
```typescript
import { slugRegex } from "@modyo/mcp-shared/helpers";

uid: z.string().regex(slugRegex, "Must be valid slug")
```

**Widget UUIDs** (OIDs, not standard UUIDs):
```typescript
// ❌ WRONG
widget_uuid: z.string().uuid()

// ✅ CORRECT
widget_uuid: z.string() // OIDs are 40-char hex strings
```

### Repository Pattern

**Always use the async repository helper** in ToolBase:

```typescript
// In any tool extending ToolBase
const repo = await this.getRepository(MyRepository, platformSlug);
const result = await repo.myMethod(params);
```

**Note**: Repository access is now async because platform configs are fetched from the mcp-platforms service. Always use `await` when calling `this.getRepository()`.

## Common Mistakes to Avoid

### ❌ Widget Tool Mistakes

1. **Trying to add widgets to content/origination pages**
   ```typescript
   // ❌ Will fail - content pages don't accept widgets
   page-add-widgets({ pageId: contentPageId, widgets: [...] })
   ```

2. **Using unpublished widget definitions**
   ```typescript
   // ❌ Widget not published yet
   page-add-widgets({ widgets: [{ definition_uuid: "unpublished..." }] })

   // ✅ Publish first
   release-create({ data: { widgetDefinition: [{ id: 123, selected: true }] } })
   ```

3. **Wrong column for grid type**
   ```typescript
   // ❌ full_grid only has column 0
   page-add-widgets({ widgets: [{ column: 1 }] })

   // ✅ Use column 0
   page-add-widgets({ widgets: [{ column: 0 }] })
   ```

### ❌ Page Tool Mistakes

1. **Missing content_type_id for content pages**
   ```typescript
   // ❌ Content pages require content_type_id
   page-create({ page_type: "content", path: "/blog" })

   // ✅ Include content_type_id
   page-create({ page_type: "content", content_type_id: 5756 })
   ```

2. **Forgetting has_router for content show pages**
   ```typescript
   // ❌ Entry pages need has_router for slug routing
   page-create({ page_type: "entry", has_router: false })

   // ✅ Enable router for slugs
   page-create({ page_type: "entry", has_router: true })
   ```

### ❌ UUID Validation Mistakes

1. **Using .uuid() for widget UUIDs**
   ```typescript
   // ❌ Widget UUIDs are OIDs (40-char hex)
   definition_uuid: z.string().uuid()

   // ✅ OIDs are strings, not RFC 4122 UUIDs
   definition_uuid: z.string()
   ```

### ❌ Publishing Mistakes

1. **Skipping the release step**
   ```typescript
   // ❌ Widget not published
   widget-definitions-create({ name: "My Widget" })
   page-add-widgets({ widgets: [{ definition_uuid: "..." }] })

   // ✅ Publish before using
   widget-definitions-create({ name: "My Widget" })
   release-create({ data: { widgetDefinition: [...] } })
   page-add-widgets({ widgets: [{ definition_uuid: "..." }] })
   ```

## Liquid Drops Reference

**Available in templates/snippets/widgets** (from [../MODYO_SNIPPETS_ARCHITECTURE.md](../MODYO_SNIPPETS_ARCHITECTURE.md)):

| Object | Properties | Context |
|--------|-----------|---------|
| `account` | url, host, google_key | All |
| `site` | name, description, language, logo, url | All |
| `page` | content, name, url, title, description, grid | Pages/Layouts |
| `page_grid` | column_0/1/2, main_widgets, sidebar | Grid snippets |
| `widget` | wid, version, sync, css, html, js, name | Widget snippets |
| `entry` | space, category, type, tags, fields | Content pages |
| `category` | id, slug, name, url, children | Content pages |
| `asset` | data_file_name, description, url | All |

**Special variables**:
- `{{ csp_nonce }}` - CSP nonce for inline scripts/styles
- `{{ content_for_layout }}` - Invokes grid snippet in layouts
- `{{ html5.open_tag }}` / `{{ html5.close_tag }}` - HTML5 document tags

## Testing Tools

### Using MCP Inspector

```bash
npm run inspect
```

**Access**: http://localhost:5173

**Test workflow**:
1. Select tool from list
2. Fill in parameters
3. Click "Run Tool"
4. Inspect JSON response

### Testing with Claude Code

**Configure** in `claude_desktop_config.json`:
```json
{
  "mcpServers": {
    "modyo-mcp": {
      "command": "npx",
      "args": ["tsx", "/path/to/modyo-mcp/src/index.ts"]
    }
  }
}
```

**Test in conversation**:
```
Claude: "List all spaces in fed-team"
Claude: "Create a widget named 'Test Widget'"
Claude: "Add widget to page 12345"
```

## Quick Reference Checklist

**Before creating a page tool**:
- [ ] Understand 3 page types (Widget, Content, Origination)
- [ ] Know when to use `has_router` (dual purpose)
- [ ] Understand `content_type_id` requirement for content pages

**Before creating a widget tool**:
- [ ] Understand widget types (Normal vs CLI)
- [ ] Know publishing is required before use
- [ ] Understand `sync` parameter implications
- [ ] Validate columns match `grid_type`

**Before creating a template tool**:
- [ ] Read MODYO_SNIPPETS_ARCHITECTURE.md
- [ ] Understand layouts vs snippets
- [ ] Know system snippets have `deletable: false`
- [ ] Understand snippet groups and purposes

**Before creating a release tool**:
- [ ] Understand two-step workflow
- [ ] Know what resources need publishing
- [ ] Understand async nature of releases

## Related Documentation

- [../CONTEXT_FOR_NEW_TOOLS.md](../CONTEXT_FOR_NEW_TOOLS.md) - Master tool development reference
- [../MODYO_SNIPPETS_ARCHITECTURE.md](../MODYO_SNIPPETS_ARCHITECTURE.md) - Rendering system
- [../MODYO_SITE_ARCHITECTURE.md](../MODYO_SITE_ARCHITECTURE.md) - Site structure
- [../MODYO_PAGE_TYPES.md](../MODYO_PAGE_TYPES.md) - Page types
- [../../src/tools/CLASS_BASED_TOOLS.md](../../src/tools/CLASS_BASED_TOOLS.md) - ToolBase pattern
- [../../src/tools/ERROR_HANDLING.md](../../src/tools/ERROR_HANDLING.md) - Error strategies

---

**Document Version**: 2.0.0
**Last Updated**: 2025-12-26
**Purpose**: Provide context for tool development and usage
