The function registry for AI agents.

Publish TypeScript functions as versioned tools. Agents discover and run them through one MCP connection.

Think npm for functions your agents can actually run.

Your agent runs what you published

Connect Codex or any MCP client. It searches, then executes. You write the Stripe and email code - Functhis publishes and runs it.

You asked to find Acme’s unpaid invoices and send Anna a payment reminder.

Acme invoices

Running

Find Acme's unpaid invoices and send Anna a payment reminder.

Find Acme's unpaid invoices and send Anna a payment reminder.


Write it. Deploy it. Let anyone run it.

A useful function shouldn’t need an entire service around it.

Without Functhis

You wanted to send a reminder. Now you own a service.

send-reminder.ts

The part you actually wanted to write.

Your logic

Then all the files around it.

Expose it

Routes, schemas & agent adapters

  • routes/reminders.ts
  • schemas/reminder.ts
  • mcp/server.ts

app.post('/reminders', validate(schema), handler);

Secure it

Authentication, permissions & limits

  • auth/verify-token.ts
  • middleware/rate-limit.ts
  • secrets.ts

await authorize(token, { scope: 'billing:write' });

Deploy it

Runtime, infrastructure & CI

  • Dockerfile
  • infra/main.tf
  • .github/workflows/deploy.yml

terraform plan && terraform apply

Keep it running

Logs, health checks & alerts

  • observability/logger.ts
  • routes/health.ts
  • monitoring/alerts.yml

alert: reminder_error_rate > threshold

And someone still has to manage credentials, patch dependencies, and debug failed deploys.

With Functhis

Keep the function. We handle the infrastructure around it.

functions/billing/send-reminder.ts

/** * Send a payment reminder from this project’s mail provider. * * @param input.contact - Person to email. * @param input.invoiceIds - Open invoices to include. */export default async function sendReminder(input: {  customer: string;  contact: string;  invoiceIds: string[]; }) {  await mail.send({    to: input.contact,    subject: `Payment reminder for ${input.customer}`,    invoiceIds: input.invoiceIds,  });  return { sent: true };}
functhis publish

@acme/billing/send-reminder

One function. More ways to run it.

  • From an agent

    Discover and run over MCP

  • Over HTTP

    Coming soon

    Call a public function URL

  • On a schedule

    Coming soon

    Run automatically with cron

  • From a webhook

    Coming soon

    React to events in your tools

Batteries included

  • Managed runtime
  • Input validation
  • Access control
  • Execution limits

One command publishes it

Run npx functhis publish from the project. Functhis versions the functions and prints MCP ids. Inspect them in console. Agents call search and execute.

~/projects/openenvx-tools
❯

One file is one function

Functhis catalogs every published function at functhis.now. Write a default export with a typed input and JSDoc. The file name is the slug. That shape is the product, not a style guide.

Catalog path

Published functions live in the catalog at @handle/package/function - not in a Git host Functhis runs for you.

One file, one function

One TypeScript file is one callable. The file name is the slug. Named exports are ignored.

Named input

The default export takes a single object named input. Put JSDoc on that export - that is the description agents search.

JSDoc is the contract

The JSDoc on the default export is the contract. Functhis does not invent a description for you.


Questions before you deploy

Straight answers about what Functhis is, what it replaces, and where it fits.


Get started