RR

routecraftjs/routecraft

Developer tools
34 stars 0 forks Quality 55 Trend 55

Define TypeScript capabilities that send emails, manage calendars, and automate work. Expose them to the Routecraft agent, Claude, ChatGPT, Cursor, or any AI agent via MCP.

Overview

Tools for agents. Or the agent harness itself. Routecraft is a TypeScript framework for AI automation. A capability is a route: a typed pipeline from a source, through operations, to a destination. The same route is an MCP tool for Claude or Cursor, a tool for an agent you run yourself, an HTTP endpoint, or a scheduled job, depending only on its source. Agents are routes too, with the same guardrails around a model call as around any other step. Nothing is reachable until you write a route for it. craft-harness is a complete agent built out of Routecraft capabilities: chat, a sandboxed shell, web fetch and search, a workspace, memory, a scheduler, human approvals, and the editor capabilities. Every one of them is an ordinary route in capabilities/ you can read on one screen and change. The instance is walled, the settings file carries the credential, and the transcript is a file --session names.

README

About

Routecraft is a TypeScript framework for AI automation. A capability is a route: a typed pipeline from a source, through operations, to a destination. The same route is an MCP tool for Claude or Cursor, a tool for an agent you run yourself, an HTTP endpoint, or a scheduled job, depending only on its source. Agents are routes too, with the same guardrails around a model call as around any other step. Nothing is reachable until you write a route for it.

Five minutes: an agent you own

craft-harness is a complete agent built out of Routecraft capabilities: chat, a sandboxed shell, web fetch and search, a workspace, memory, a scheduler, human approvals, and the editor capabilities. Every one of them is an ordinary route in capabilities/ you can read on one screen and change.

bunx create-routecraft my-agent --example https://github.com/routecraftjs/craft-harness
cd my-agent
bun run setup            # generates the project's own secrets into .env and .routecraft/
# add LLM_API_KEY to .env
bun run dev

From another terminal:

bun run exec chat --session=demo --message="what can you do?"

The instance is walled, the settings file carries the credential, and the transcript is a file --session names. The same conversation is reachable over MCP at http://localhost:8081/mcp and from your editor over the Agent Client Protocol.

What a capability looks like

import { craft, mail } from '@routecraft/routecraft'
import { mcp } from '@routecraft/ai'
import { z } from 'zod'

const SendTeamEmail = z.object({
  to: z
    .string()
    .email()
    .refine((email) => email.endsWith('@company.com'), 'Can only send to @company.com addresses'),
  subject: z.string(),
  message: z.string(),
})

// The route id is the tool name; description and input schema live on the
// route, so every call is validated before any of your code runs.
export default craft()
  .id('send-team-email')
  .description('Send an email to a team member')
  .input({ body: SendTeamEmail })
  .from(mcp())
  .transform(({ to, subject, message }) => ({ to, subject, text: message }))
  .to(mail()) // the account comes from craft.config.ts

The source decides the door. .from(mcp()) makes it an MCP tool. .from(direct()) makes it a capability any local agent can call and craft exec can run. .from(http()) makes it an endpoint. .from(cron()) makes it a job. The steps in between do not change.

An agent is a route too

import { craft, direct } from '@routecraft/routecraft'
import { agent, tools } from '@routecraft/ai'
import { z } from 'zod'

export default craft()
  .id('assistant')
  .description('Answer a question with the tools this project defines')
  .input({ body: z.object({ question: z.string() }) })
  .from(direct())
  .to(
    agent({
      model: 'anthropic:claude-opus-4-7',
      system: 'Be useful. Say what you did.',
      user: (ex) => ex.body.question,
      tools: tools(['Direct(send-team-email)']),
    }),
  )

Tools are an allowlist of capabilities, never a blacklist. An agent can also be a markdown file under agents/ with frontmatter for its model and tools, which craft start discovers with everything else in the project. Because the agent is a step in a route, .authorize(), .throttle(), .retry(), .timeout() and .circuitBreaker() apply to the model call exactly as to any other step.

What you get

  • Work that survives a restart. .defer() defers an exchange in a store, and .resume() revives it by token, hours or days later, from any transport. Durable agents defer mid-conversation the same way.
  • Agents with sessions and background tools. A conversation is a record a person owns; a tool can hand a long job to a route and come back when it finishes. Agent adapter.
  • Talk to your agents from your editor. craft acp and the acp config key serve the Agent Client Protocol. Talk from your editor.
  • MCP both ways. Expose routes as tools with mcp() and the mcp plugin; call other servers’ tools as MCP(server:tool) in an agent’s tool list. Expose as MCP, call an MCP.
  • Isolated host execution. shell() runs commands in an isolation tier, including a throwaway Docker container per command, with egress denied by default.
  • A management API and a CLI to drive it. The ops plugin serves health, readiness, a route listing and dispatch behind scope-gated tiers; craft exec and craft ops are its clients. CLI reference.
  • Secure by design. JWT, JWKS and API-key validators, .authorize() at route entry, principals that follow an exchange through every hop. Securing capabilities.

Add Routecraft to an existing project

bunx create-routecraft my-app

Expose a capability to Claude Desktop by adding it to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "my-tools": {
      "command": "bunx",
      "args": ["@routecraft/cli", "run", "./capabilities/send-team-email.ts"]
    }
  }
}

Now talk to Claude: “Send an email to [email protected] thanking him for yesterday’s meeting”. Claude discovers the tool and calls it with validated input.

The craft CLI runs on Bun (>=1.1.0). Node users embed @routecraft/routecraft programmatically; see the Programmatic Invocation guide.

📚 Get Started | Project structure | Examples | API Reference

Monorepo Structure

  • packages/routecraft – Core library (builder, DSL, context, adapters, consumers, the ops plugin)
  • packages/ai – AI integrations: LLM providers, agents, embeddings, MCP server / client, ACP
  • packages/clicraft CLI to run capabilities and start contexts (Bun >= 1.1.0)
  • packages/create-routecraft – Project scaffolder (bunx create-routecraft)
  • packages/eslint-plugin-routecraft – ESLint rules for capability authoring
  • packages/prettier-plugin-routecraft – Prettier plugin for compact DSL formatting
  • packages/os – System-native adapters: isolated subprocess execution via shell(), browser automation via agentBrowser()
  • packages/testing – Test utilities (testContext, spy logger, mockAdapter, fixtures)
  • skills/ – Agent Skills for authoring Routecraft (Claude Code, Cursor, Codex, Windsurf, Cline, Continue, Copilot, …; bunx skills add routecraftjs/routecraft). See skills/README.md
  • apps/routecraft.dev – Documentation site (docs, examples, guides)
  • examples/ – Runnable example capabilities

Examples

Browse runnable examples in examples/src/: hello-world.ts, mcp-greet.ts, agent.ts, find-product.ts, mail-noreply-notify.ts, programmatic-invocation.ts, split.ts. Each demonstrates a different feature combination.

Try one:

bun install
bun run build
bunx craft run ./examples/dist/mcp-greet.js

For end-to-end walkthroughs, see the docs site.

Contributing

Contributions are welcome! Please read our contribution guide at https://routecraft.dev/docs/community/contribution-guide for guidelines on how to propose changes, add adapters, and write capabilities.

License

Licensed under the Apache 2.0 License.

View this README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide

Configuration

{ "mcpServers": { "my-tools": { "command": "bunx", "args": ["@routecraft/cli", "run", "./capabilities/send-team-email.ts"] } } }