Products Marketplace Blog About Contact Sign in Download
How to Build and Publish a LacPointer Skill Photo by Edwin Petrus on Unsplash

How to Build and Publish a LacPointer Skill

LacPointer's Skills Marketplace isn't just for installing things — you can ship your own skill in an afternoon. Here's exactly how to do it, from manifest to submission.

Why I Started Building My Own Skills

The built-in skills in LacPointer cover a solid range — Weather, GitHub, Crypto Tracker, Hacker News, and a handful of others. But I kept hitting the same wall: I'd open LacPointer with Option+Space, ask something specific to my daily workflow, and the AI would do its best but come up short because it had no access to the right tool.

I wanted to query our internal staging environment's health endpoint. I wanted to pull the latest row from a Notion database on command. Stuff that's genuinely useful but too specific to be a default skill.

Turns out the Skills Marketplace has a submission system that's actually designed for this. You write a zip bundle, submit it, and if it passes review it becomes installable by anyone. Or you can keep it for yourself. Either way, the process is the same.

Here's how it works, start to finish.

Model walks runway with audience watching
Photo by Ken's Vision on Unsplash
What a Skill Actually Is

A LacPointer skill is a zip file with a manifest.json at the root. That manifest tells LacPointer everything it needs to know: what domains the skill talks to, what tools it exposes, and how authentication works.

The AI reads your tool descriptions in plain English and decides when to call each tool automatically. You're not writing UI or wiring up button clicks — you're just describing capabilities, and the AI handles the rest.

When a user installs your skill and asks something that matches one of your tools, the AI calls it and weaves the result into its response. No extra steps for the user.

The manifest.json Structure

Every skill needs these fields in manifest.json:

  • slug — unique identifier, lowercase, hyphens only (e.g. my-status-checker)
  • name — human-readable display name
  • version — semver string like 1.0.0
  • author — your name or handle
  • description — what the skill does
  • domains — array of allowed hostnames the skill is allowed to fetch from
  • tools — array of tool definitions (more on this below)
  • auth_type — one of none, secret, or oauth

Here's a minimal manifest for a skill that checks whether a URL is up:

{
  "slug": "uptime-check",
  "name": "Uptime Checker",
  "version": "1.0.0",
  "author": "yourname",
  "description": "Checks if a given URL returns a 200 status code.",
  "domains": ["*"],
  "auth_type": "none",
  "tools": [
    {
      "name": "check_uptime",
      "description": "Sends a GET request to a URL and returns whether it is up or down based on the HTTP status code.",
      "parameters": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "The full URL to check, including https://"
          }
        },
        "required": ["url"]
      }
    }
  ]
}

The description field on each tool is the most important thing you'll write. The AI reads it verbatim to decide whether to call the tool. Be specific and use plain English. "Checks if a URL is up" will get called correctly. "Does the thing" will not.

Close up of a vintage yellow truck headlight
Photo by Jimmy Blackwell on Unsplash
Writing the Tool Logic

Each tool in your manifest maps to a function in your skill's code. The file structure looks like this:

uptime-check/
  manifest.json
  index.js
  package.json

Your index.js exports a handler for each tool name. For the uptime checker:

exports.check_uptime = async ({ url }) => {
  try {
    const res = await fetch(url, { method: "GET", signal: AbortSignal.timeout(5000) });
    return { up: res.ok, status: res.status };
  } catch (e) {
    return { up: false, error: e.message };
  }
};

That's genuinely it for a simple skill. The runtime calls your export, passes in the parameters the AI extracted from the user's message, and returns the result back to the AI to include in its answer.

If your skill needs an API key, set "auth_type": "secret" in the manifest. The user will be prompted to enter it once on install, and it'll be encrypted with AES-256 before storage. Your handler receives it as context.secrets.API_KEY.

The Approval Tiers (Don't Skip This Part)

LacPointer's review system uses three tiers based on what your skill does:

  • Green: talks to a single domain, no special permissions. This gets auto-approved. Ships fast.
  • Yellow: multiple domains, or needs schedule/panel permissions. Goes to manual review.
  • Red: requests filesystem access. Auto-rejected. Full stop.

Every submission also goes through ClamAV antivirus, static analysis that blocks things like eval, dynamic imports, child_process, and fs writes — plus an npm audit. This isn't bureaucracy for its own sake. It's what makes it safe for anyone to install skills from the marketplace without worrying about what they're running.

If you want a fast approval, keep your skill single-domain and avoid any dynamic code. I got a skill approved in under an hour that way.

A blue concept car is on display.
Photo by Rob Wingate on Unsplash
Bundling and Submitting

When you're ready:

  1. Zip your entire skill folder — manifest.json must be at the root of the zip, not inside a subfolder.
  2. Keep it under 5MB.
  3. Submit via the developer portal or POST directly to /api/skills/submit.

The developer docs have the full API spec if you want to automate submissions as part of a CI step, which is actually a nice pattern if you're iterating quickly.

Testing Before You Submit

You can install a skill locally before submitting it publicly. Just upload the zip through your LacPointer settings and it'll appear in your installed skills list immediately. From there, open LacPointer with Option+Space and try triggering the tool naturally in conversation.

This is the fastest feedback loop — you don't need to submit to the marketplace just to test. I usually spend 20 minutes here tweaking the tool descriptions until the AI calls the right tool at the right time without me having to think about it.

white and red ceramic vase
Photo by Nataliya Smirnova on Unsplash
A Few Things Worth Knowing

The tool description field is load-bearing. Spend time on it. If the AI isn't calling your tool when it should, the description is almost always why. Try making it more specific about the kind of input it expects and what it returns.

Skills with "auth_type": "none" are the easiest to get approved and the easiest to install. If you can design your skill to not need a key — maybe it wraps a public API — do that.

If you're building something useful for other developers, the marketplace is worth publishing to. The currently approved skills are useful but lean general purpose. There's a real gap for developer-specific tools: deployment status checks, PR summaries, error log parsing, that kind of thing.

The full skill developer docs are at lacai.io/docs/skills. Start there, then use the developer portal to manage submissions. And if you build something good, it'll show up for everyone browsing the marketplace once it clears review.

Quick Start Checklist

  • Create a folder with manifest.json, index.js, and package.json
  • Fill in slug, name, version, author, description, domains, tools, and auth_type
  • Write a clear, specific description for every tool — the AI depends on it
  • Keep it single-domain for a fast auto-approval (Green tier)
  • Zip it up, install locally first, test with Option+Space
  • Submit via the developer portal when it's working right

We use cookies to keep you signed in and to serve ads via Google AdSense. By continuing to use this site you agree to our Privacy Policy.