Skip to content

Packages ​

Any API can ship as a Halo tool. These are in the registry at halolang.com/registry:

bash
halo search                 # list them
halo add stripe             # then: tool Pay : Stripe()
halo add world-time --trust # it runs its own code, so it needs --trust
halo tools                  # every provider you can use, and its methods

github-mcp

1.0.0 · GitHubMCP()
mcp

GitHub through its official MCP server: repositories, issues, pull requests, code search, and more

methods listed by its server at run time
network: none declared
reads env: GITHUB_PERSONAL_ACCESS_TOKEN
starts: docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
runs its own code: YES (needs --trust)

jira

1.0.0 · Jira()
http

Jira Cloud issues: search with JQL, read, create, comment, and transition

searchget_issuecreate_issueadd_commentlist_transitionstransition
network: *.atlassian.net
reads env: JIRA_EMAIL, JIRA_API_TOKEN
runs its own code: no

notion

1.0.0 · Notion()
http

Notion pages and databases: search, read, query, create, and append

searchget_pageget_blocksquery_databasecreate_pageappend_blocks
network: api.notion.com
reads env: NOTION_API_KEY
runs its own code: no

sentry

1.0.0 · Sentry()
http

Sentry error tracking: list, read, and resolve issues

list_issuesget_issuelatest_eventupdate_issue
network: sentry.io
reads env: SENTRY_AUTH_TOKEN
runs its own code: no

stripe

1.0.0 · Stripe()
http

Stripe payments: customers, charges, refunds, and balance

list_customersget_customercreate_customerlist_chargescreate_refundget_balance
network: api.stripe.com
reads env: STRIPE_API_KEY
runs its own code: no

world-time

1.0.0 · WorldTime()
module

Time zones without an API: the time anywhere, and converting a time between zones

nowconvert
network: none declared
reads env: nothing
runs its own code: YES (needs --trust)

cloudflare

1.0.0 · Cloudflare(), CloudflareZone()
http

Cloudflare: Workers, KV, D1, R2, Pages and Queues in an account; DNS records, settings and cache purges in a zone

list_workersget_worker_settingslist_worker_deploymentslist_kv_namespaceslist_kv_keysget_kv_valuedelete_kv_valuelist_d1_databasesquery_d1list_r2_bucketslist_pages_projectslist_pages_deploymentslist_queues
list_dns_recordscreate_dns_recordupdate_dns_recorddelete_dns_recordget_settingpurge_cache
network: api.cloudflare.com
reads env: CLOUDFLARE_API_TOKEN
runs its own code: no

Method colors are their effects: read write external. Policies and halo plan use them.

How packages work ​

A package is a halo-tool.json declaring providers of one of three kinds:

KindWhat runsNeeds --trust
httpNothing from the package: Halo makes the requests, only under the declared base URLno
mcpAn MCP server: a command it starts, or a URLfor a command
moduleThe package's TypeScriptyes

Every package is a single checksummed file. halo add pins its version and SHA-256 in halo.lock, and every load checks the installed files against it. Trust is recorded on your machine (.halo/trust.json, per checksum), never read from the lockfile, so a pull request can't grant it.

Publish your own ​

bash
halo pack ./my-api                                         # → my-api-1.0.0.halotool
halo publish my-api-1.0.0.halotool --registry ./index.json # add it to a registry index

A registry is a static index.json plus the package files: host it anywhere. Users point at it with --registry, HALO_REGISTRY, or "registry" in halo.json. Writing a package →

curl -fsSL https://halolang.com/install.sh | sh