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 bothkebab-case(e.g.,slack-send-message) andsnake_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_casefollowing{provider}_{action}(e.g.,notion_create_page).
Build your own Python tool (5 min):
Most tools are a single YAML file that describes an HTTP call — no code. This one calls the public JSONPlaceholder test API.
1. Create tools/get_user/definition.yaml:
name: get_user
description: Look up a user by id on the JSONPlaceholder test API
version: '1.0.0'
parameters:
id:
type: number
required: true
description: User id (1-10)
execution:
type: http
method: GET
url: 'https://jsonplaceholder.typicode.com/users/{id}'
output_schema:
type: object
properties:
name:
type: string
email:
type: string
2. Create main.py:
import asyncio
from matimo import Matimo
async def main():
matimo = await Matimo.init('./tools', log_level='warn')
print(f"📦 Loaded {len(matimo.list_tools())} tools")
user = await matimo.execute('get_user', {'id': 1})
print('✅', user['name'], '-', user['email'])
asyncio.run(main())
3. Run it:
python main.py
# 📦 Loaded 1 tools
# ✅ Leanne Graham - Sincere@april.biz
A Python HTTP tool returns the parsed response body.
Python next steps:
- SDK Patterns (Python) — factory, decorator, LangChain
- LangChain Integration
- Examples →
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 bothkebab-caseandsnake_casetool names. Legacy tools (Gmail, GitHub, older Slack) usekebab-case(e.g.,slack-send-message), while newer tools usesnake_case(e.g.,bruno_run_request,matimo_create_tool).
Recommended: Usesnake_casefor 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 your first 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.).
✅ 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('get_user', { id: 1 })) as {
data: { name: string; email: string };
};
console.log('✅', result.data.name, '-', result.data.email);
}
main().catch(console.error);
3. Create Your First Tool (1 min)
Create tools/get_user/definition.yaml — an HTTP tool, Matimo’s default kind, which needs no code:
name: get_user
description: Look up a user by id on the JSONPlaceholder test API
version: '1.0.0'
parameters:
id:
type: number
required: true
description: User id (1-10)
execution:
type: http
method: GET
url: 'https://jsonplaceholder.typicode.com/users/{id}'
output_schema:
type: object
properties:
name:
type: string
email:
type: string
4. Run It (< 1 min)
# Compile TypeScript
npx tsc demo.ts
# Run the script
node demo.js
# Output:
# 📦 Loaded 1 tools
# ✅ Leanne Graham - Sincere@april.biz
A TypeScript HTTP tool returns { success, data, statusCode, headers }, with the response body in data.
What Just Happened?
- MatimoInstance.init(‘./tools’) — Loaded every
definition.yamlunder./tools - matimo.listTools() — Listed discovered tools
- matimo.execute(‘get_user’, { id: 1 }) — The policy engine classified the call (a GET is low risk, so it runs without asking), Matimo filled
{id}into the URL, made the request and returned the result
Tools that ask first
In 0.2.0 some calls wait for a person: tools whose YAML says requires_approval: true, HTTP DELETE tools, and type: command tools (unless they say requires_approval: false). Give the instance a reviewer, or those calls are refused:
const matimo = await MatimoInstance.init({
toolPaths: ['./tools'],
onApproval: async (request) => confirmWithUser(request.toolName, request.params),
});
See Approval System.
Next Steps
Choose Your Pattern
- Factory Pattern (you just used this) — Best for simple scripts and backends
- Decorator Pattern — Best for class-based code
- LangChain — Best for AI agents with automatic tool selection
See SDK Usage Patterns for details.
Add More Tools
Create more YAML files in tools/:
tools/
├── get_user/
│ └── 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({
toolPaths: [
'./tools', // Your custom tools
'./node_modules/@matimo/slack/tools', // Pre-built tools
'./node_modules/@matimo/gmail/tools',
],
});
Further Reading
- API Reference — Full SDK methods and types
- Tool Specification — Write production tools
- SDK Usage Patterns — Factory, Decorator, LangChain patterns
- Architecture Overview — How Matimo works internally
- Framework Integrations — LangChain integration examples
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('get_user');
if (tool) {
console.log('Parameters:', tool.parameters);
}
Search Tools
const results = matimo.searchTools('user');
console.log(
'Found:',
results.map((t) => t.name)
);
Execute with Error Handling
try {
const result = await matimo.execute('get_user', { id: 1 });
console.log('Success:', result);
} catch (error) {
if (error.code === 'TOOL_NOT_FOUND') {
console.error('Tool not found:', error.message);
} else if (error.code === 'INVALID_PARAMETER') {
console.error('Invalid parameters:', error.details);
} else if (error.code === 'POLICY_DENIED') {
console.error('Refused by policy or by a reviewer:', error.message);
} 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({
toolPaths: ['./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