View on GitHub

Matimo - AI Tools Ecosystem

Define tools once in YAML, use them everywhere

Download this project as a .zip file Download this project as a tar.gz file

Quick Start — 5 Minutes

Get Matimo up and running in 5 minutes. Available in TypeScript and Python.


Python SDK

Path D: Python Quick Start

Install:

pip install matimo
# or with uv
uv add matimo

Use pre-built tools immediately:

pip install matimo matimo-slack matimo-github
import asyncio
from matimo import Matimo

async def main():
    # Load all installed provider packages automatically
    matimo = await Matimo.init(auto_discover=True)

    # Execute a Slack tool
    result = await matimo.execute('slack_send_channel_message', {
        'channel': '#general',
        'text': 'Hello from Matimo!',
    })
    print('Message sent!', result)

asyncio.run(main())

ℹ️ Tool Naming
You’ll notice Matimo tools use both kebab-case (e.g., slack-send-message) and snake_case (e.g., slack_send_channel_message).
Both work identically — legacy tools use kebab-case, newer tools use snake_case.
Recommended for new tools: snake_case following {provider}_{action} (e.g., notion_create_page).

Build your own Python tool (5 min):

1. Create tools/calculator/definition.yaml:

name: calculator
description: Perform basic math operations
version: '1.0.0'

parameters:
  operation:
    type: string
    enum: [add, subtract, multiply, divide]
    required: true
  a:
    type: number
    required: true
  b:
    type: number
    required: true

execution:
  type: command
  command: python
  args:
    - -c
    - |
      import sys, json, operator
      op, a, b = sys.argv[1], float(sys.argv[2]), float(sys.argv[3])
      ops = {'add': a+b, 'subtract': a-b, 'multiply': a*b, 'divide': a/b}
      print(json.dumps({'result': ops[op]}))
    - '{operation}'
    - '{a}'
    - '{b}'

output_schema:
  type: object
  properties:
    result:
      type: number
  required: [result]

2. Create main.py:

import asyncio
from matimo import Matimo

async def main():
    matimo = await Matimo.init('./tools')
    tools = matimo.list_tools()
    print(f"📦 Loaded {len(tools)} tools")

    result = await matimo.execute('calculator', {
        'operation': 'add',
        'a': 10,
        'b': 5,
    })
    print('✅ Result:', result)  # {'result': 15.0}

asyncio.run(main())

3. Run it:

python main.py
# or
uv run python main.py

Python next steps:


TypeScript SDK

Choose Your Path

Not sure where to start? Pick one:

🚀 Path A: Use Pre-Built Tools (Fastest — 2 mins)

You want to execute existing tools (Slack, Gmail, GitHub, etc.) without building your own.

Install:

npm install matimo @matimo/slack @matimo/gmail

Use immediately:

import { MatimoInstance } from 'matimo';

const matimo = await MatimoInstance.init({ autoDiscover: true });

// Execute a Slack tool
const result = await matimo.execute('slack-send-message', {
  channel: '#general',
  text: 'Hello from Matimo!',
});

console.log('Message sent!', result);

ℹ️ Tool Naming
Matimo supports both kebab-case and snake_case tool names. Legacy tools (Gmail, GitHub, older Slack) use kebab-case (e.g., slack-send-message), while newer tools use snake_case (e.g., bruno_run_request, matimo_create_tool).
Recommended: Use snake_case for new tools following {provider}_{action}.

✅ Great for: Using existing integrations in your app 📖 See All Available Tools →


🛠️ Path B: Build Your Own Tool (Educational — 5 mins)

You want to understand how to create and execute custom tools.

Continue below to create a calculator tool →

✅ Great for: Learning how Matimo works 📖 Build Your First Tool →


🤖 Path C: Integrate with LangChain (Advanced — 10 mins)

You want to use Matimo tools with an AI agent (LangChain, CrewAI, etc.).

See LangChain Integration →

✅ Great for: Building intelligent agents 📖 Examples →


1. Installation (1 min)

npm install matimo
# or with pnpm
pnpm add matimo

2. Create Your First Script (3 min)

Create a file demo.ts:

import { MatimoInstance } from 'matimo';

async function main() {
  // Initialize Matimo with your tools
  const matimo = await MatimoInstance.init('./tools');

  // List available tools
  const tools = matimo.listTools();
  console.log(`📦 Loaded ${tools.length} tools`);

  // Execute a tool
  const result = await matimo.execute('calculator', {
    operation: 'add',
    a: 10,
    b: 5,
  });

  console.log('✅ Result:', result);
}

main().catch(console.error);

3. Create Your First Tool (1 min)

Create tools/calculator/definition.yaml:

name: calculator
description: Perform basic math operations
version: '1.0.0'

parameters:
  operation:
    type: string
    enum: [add, subtract, multiply, divide]
    required: true
    description: Mathematical operation to perform
  a:
    type: number
    required: true
    description: First operand
  b:
    type: number
    required: true
    description: Second operand

execution:
  type: command
  command: node
  args:
    - -e
    - |
      const op = process.argv[1];
      const a = parseFloat(process.argv[2]);
      const b = parseFloat(process.argv[3]);
      const ops = { add: a + b, subtract: a - b, multiply: a * b, divide: a / b };
      console.log(JSON.stringify({ result: ops[op] }));
    - '{operation}'
    - '{a}'
    - '{b}'

output_schema:
  type: object
  properties:
    result:
      type: number
      description: Result of the operation
  required: [result]

error_handling:
  retry: 2
  backoff_type: exponential
  initial_delay_ms: 100

4. Run It (< 1 min)

# Compile TypeScript
npx tsc demo.ts

# Run the script
node demo.js

# Output:
# 📦 Loaded 1 tools
# ✅ Result: { result: 15 }

What Just Happened?

  1. MatimoInstance.init(‘./tools’) — Loaded all YAML files from ./tools/**/*.yaml
  2. matimo.listTools() — Listed discovered tools
  3. matimo.execute(‘calculator’, {…}) — Executed the tool with parameters
  4. Matimo validated parameters, spawned process, validated output, returned result

Next Steps

Choose Your Pattern

See SDK Usage Patterns for details.

Add More Tools

Create more YAML files in tools/:

tools/
├── calculator/
│   └── definition.yaml      # Done ✅
├── my-api/
│   └── definition.yaml      # Create more
└── slack/
    └── definition.yaml

Each tool is just a YAML file — no code needed!

Use Provider Tools

Install pre-built tools from npm:

pnpm add @matimo/slack @matimo/gmail

Then load them alongside your custom tools:

const matimo = await MatimoInstance.init([
  './tools',                    # Your custom tools
  './node_modules/@matimo/slack/tools',  # Pre-built tools
  './node_modules/@matimo/gmail/tools'
]);

Further Reading


Common Tasks

List All Loaded Tools

const tools = matimo.listTools();
tools.forEach((tool) => {
  console.log(`${tool.name} - ${tool.description}`);
});

Get Tool by Name

const tool = matimo.getTool('calculator');
if (tool) {
  console.log('Parameters:', tool.parameters);
}

Search Tools

const results = matimo.searchTools('calculate');
console.log(
  'Found:',
  results.map((t) => t.name)
);

Execute with Error Handling

try {
  const result = await matimo.execute('calculator', {
    operation: 'divide',
    a: 10,
    b: 0,
  });
  console.log('Success:', result);
} catch (error) {
  if (error.code === 'TOOL_NOT_FOUND') {
    console.error('Tool not found:', error.message);
  } else if (error.code === 'INVALID_PARAMETERS') {
    console.error('Invalid parameters:', error.details);
  } else if (error.code === 'EXECUTION_FAILED') {
    console.error('Execution failed:', error.details);
  }
}

Example: Using Slack

After installing @matimo/slack:

import { MatimoInstance } from 'matimo';

const matimo = await MatimoInstance.init(['./tools', './node_modules/@matimo/slack/tools']);

// Execute a Slack tool
const result = await matimo.execute('slack-send-message', {
  channel: '#general',
  text: 'Hello from Matimo!',
});

console.log(result);

Troubleshooting

Tools not loading?

# Check that YAML files exist
ls tools/*/definition.yaml

# Validate YAML syntax
pnpm validate-tools

Execution failing?

// Enable detailed error messages
try {
  const result = await matimo.execute('tool-name', params);
} catch (error) {
  console.error('Full error:', JSON.stringify(error, null, 2));
}

Type errors?

# Check TypeScript compilation
npx tsc --noEmit

Support