npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@matimo/composio

v0.1.5

Published

Governed access to Composio's tool catalog for Matimo — policy engine, risk classification, and HITL approval on top of Composio's 250+ integrations

Readme

@matimo/composio — Governed Access to Composio's Tool Catalog

@matimo/composio turns Composio's 250+ integrations from "agent has raw API access" into "agent has governed, auditable, human-approvable API access" — same breadth, with Matimo's policy engine, risk classification, and human-in-the-loop (HITL) approval layered on top.

Every tool in this package proxies a single Composio action via Composio's REST execute endpoint:

POST https://backend.composio.dev/api/v3/tools/execute/{TOOL_SLUG}

📦 Installation

npm install @matimo/composio
# or
pnpm add @matimo/composio

🧬 Tools Are Generated, Not Hand-Written

Unlike other Matimo provider packages, the tools/composio_*/ directory is generated by scripts/generate-tools.ts from Composio's live catalog API. Do not hand-edit tools/composio_<toolkit>_<action>/definition.yaml files — changes will be overwritten the next time the generator runs.

Running the Generator

# Requires COMPOSIO_API_KEY in the environment (used only at generation time,
# to call Composio's catalog API)
export COMPOSIO_API_KEY="your-composio-project-api-key"

pnpm generate:composio --toolkits=JIRA,LINEAR,ASANA
  • Idempotent and incremental: re-running with new toolkits only adds new files; existing tool definitions are left untouched.
  • Pass --force-refresh to regenerate every file for the named toolkits (e.g. after editing scripts/risk-overrides.json):
pnpm generate:composio --toolkits=JIRA --force-refresh

What Gets Generated

For each Composio action (e.g. JIRA_GET_ISSUE), the generator writes tools/composio_jira_get_issue/definition.yaml:

name: composio_jira_get_issue
description: Fetch a Jira issue by ID
version: '1.0.0'
risk: low
parameters:
  composio_user_id:
    type: string
    required: true
    description: The Composio entity/user ID for the calling tenant or user.
  composio_connected_account_id:
    type: string
    required: true
    description: >-
      The Composio connected account ID for the JIRA toolkit, scoped to the
      calling tenant. The "Connect JIRA" flow must be completed before this
      tool will succeed.
  issue_id_or_key:
    type: string
    required: true
    description: The ID or key of the Jira issue to retrieve.
execution:
  type: http
  method: POST
  url: https://backend.composio.dev/api/v3/tools/execute/JIRA_GET_ISSUE
  headers:
    x-api-key: '{COMPOSIO_API_KEY}'
    Content-Type: application/json
  body:
    user_id: '{composio_user_id}'
    connected_account_id: '{composio_connected_account_id}'
    arguments:
      _matimo_tool: composio_jira_get_issue
      issue_id_or_key: '{issue_id_or_key}'
  timeout: 30000
authentication:
  type: api_key
  location: header
  name: x-api-key
tags: [composio, jira]

arguments._matimo_tool is a literal marker baked in at generation time (not a {param} placeholder) — see Why _matimo_tool Is in Every arguments Block below.

Why _matimo_tool Is in Every arguments Block

Composio's /tools/execute/{slug} endpoint requires the arguments key to be present in the request body, even when empty ({}) — omitting it entirely returns HTTP 400 "Only one of 'text' or 'arguments' must be provided". Matimo's HTTP executor, however, drops empty nested objects from the request body after templating. For any action where the caller supplies none of the optional parameters (or the action has no input parameters at all), arguments would template down to {} and then be stripped entirely — triggering that 400 on every such call.

The generator works around this by always including a literal _matimo_tool: <tool name> entry in arguments. Because it's a plain string baked in at generation time (not a {param} placeholder), it always survives templating, keeping arguments non-empty. Composio tolerates the extra field and ignores it; it also serves as a debugging breadcrumb in Composio's logs identifying which Matimo tool made the call.

🔑 Runtime Configuration

Every generated tool requires three values, all supplied by the application embedding Matimo (e.g. via its existing credential-injection layer — the same mechanism that provides SLACK_BOT_TOKEN for @matimo/slack):

| Value | Type | How it's resolved | |-------|------|--------------------| | COMPOSIO_API_KEY | Environment variable | Auto-injected as the x-api-key header by Matimo's auth-parameter resolution (any execution-config placeholder containing key resolves from process.env) | | composio_user_id | Tool parameter, required | The Composio entity/user ID for the calling tenant/user | | composio_connected_account_id | Tool parameter, required | The connected account ID for the specific toolkit, scoped to the calling tenant — requires the "Connect <toolkit>" flow to have been completed |

How composio_user_id / composio_connected_account_id are obtained, stored, or surfaced via a "Connect via Composio" UI is out of scope for this package — see definition.yaml for details.

🚦 Risk Classification

Every generated tool sets an explicit risk: low | medium | high field. The generator derives this from the Composio action's slug:

| Pattern in action slug | Risk | Examples | |-------------------------|------|----------| | GET, LIST, FETCH, SEARCH, READ, FIND | low | JIRA_GET_ISSUE, LINEAR_LIST_ISSUES | | CREATE, SEND, UPDATE, EDIT, ADD, POST, UPLOAD, INVITE | medium | LINEAR_CREATE_ISSUE, GMAIL_SEND_EMAIL | | DELETE, REMOVE, ARCHIVE, REVOKE, CANCEL | high | JIRA_DELETE_ISSUE, LINEAR_ARCHIVE_ISSUE | | Matches none of the above | medium (default) | An unnecessary approval prompt beats a silent destructive write |

Destructive patterns are checked first, so an ambiguous name that also looks destructive (e.g. ARCHIVE_AND_GET_ISSUE) is still flagged high.

Overriding the Heuristic

If the generator misclassifies a specific action, add an entry to scripts/risk-overrides.json keyed by the Composio tool slug:

{
  "JIRA_DELETE_ISSUE_LINK": "high"
}

Then re-run the generator with --force-refresh for the affected toolkit(s) to apply the override.

Acting on risk: — This Is the Embedding Application's Job

classifyRisk(tool) always returns each generated tool's explicit risk: field, but DefaultPolicyEngine.canExecute() does not itself gate execute() calls on risk: — it only checks deprecation/draft status and requires_approval + role. So with the default policy engine, a risk: medium or risk: high composio tool executes immediately.

To get pending_approval quarantine for medium/high-risk composio tools (e.g. composio_jira_create_issue, composio_jira_delete_issue), the embedding application must do one of:

  • Implement a custom PolicyEngine whose canExecute() checks classifyRisk(tool) against its quarantineRiskLevels and returns { allowed: 'pending_approval', riskLevel, reason, toolName }MatimoInstance.execute() will then invoke the configured onHITL callback before proceeding.
  • Register composio tools under untrustedPaths with requires_approval: true and call reloadTools() with { environment: 'prod' }DefaultPolicyEngine.canCreate() returns pending_approval for medium/high-risk tools when enableHITL: true and the risk level is in quarantineRiskLevels.

See skills/composio/SKILL.md for how agents should handle a pending_approval result if the host wires this up.

🚀 Quick Start

import { MatimoInstance } from 'matimo';

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

// Low-risk: executes immediately
const result = await matimo.execute('composio_jira_get_issue', {
  composio_user_id: 'user_123',
  composio_connected_account_id: 'ca_abc123',
  issue_id_or_key: 'PROJ-123',
});

// Medium-risk: executes immediately under DefaultPolicyEngine — see
// "Acting on risk:" above for how to make this return `pending_approval`
const created = await matimo.execute('composio_linear_create_linear_issue', {
  composio_user_id: 'user_123',
  composio_connected_account_id: 'ca_def456',
  title: 'Investigate flaky test',
  team_id: 'team_abc789',
});

🧪 Testing Strategy (Exception to Standard Matimo Rules)

Most Matimo provider packages require 100% unit coverage, 4 TypeScript examples, and 3 Python examples per tool. That rule does not apply here: the initial toolkit set generates 200–1000+ tool definition files across 15–20 toolkits, and per-tool hand-written tests/examples for every generated file would be unmaintainable busywork that breaks on every catalog change.

Instead:

  1. test/unit/generator.test.ts covers the generator itself — pnpm jest packages/composio — with mocked Composio API responses. It asserts:
    • Risk classification for representative action-name patterns (one case per heuristic bucket: GET-like → low, CREATE-like → medium, DELETE-like → high, ambiguous → medium default, and destructive patterns winning over ambiguous matches)
    • Risk override resolution (scripts/risk-overrides.json wins over the heuristic)
    • Parameter mapping from Composio's JSON Schema input_parameters to Matimo's parameters block
    • Generated tool definitions are schema-valid via validateToolDefinition
    • Pagination via next_cursor when fetching a toolkit's catalog
    • Idempotent file writes (created / skipped / forceRefresh)
  2. pnpm validate-tools passing on all generated YAML is the acceptance gate for generated files. No per-tool hand-written tests or examples (TypeScript or Python) are required or expected for tools/composio_*/.
  3. There is no executor.test.ts — every generated tool is type: http, so there is no shared executor to test.

🤝 Contributing

See CONTRIBUTING.md for guidelines on contributing to Matimo.


Part of the Matimo ecosystem — Write YAML once, use everywhere.