matimo-postgres 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,63 @@
1
+ # Dependencies
2
+ **/node_modules/
3
+ package-lock.json
4
+ yarn.lock
5
+
6
+ # Build output
7
+ **/dist/
8
+ *.tsbuildinfo
9
+
10
+ # Python compiled / build
11
+ **/__pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+ *.egg-info/
15
+ *.egg
16
+ **/build/
17
+ **/.eggs/
18
+ **/.venv/
19
+ **/.mypy_cache/
20
+ **/.ruff_cache/
21
+ **/.pytest_cache/
22
+
23
+ # Test coverage
24
+ **/coverage/
25
+ **/.nyc_output/
26
+
27
+ # IDE
28
+ .vscode/
29
+ .idea/
30
+ *.swp
31
+ *.swo
32
+ *~
33
+ .DS_Store
34
+
35
+ # Environment
36
+ .env
37
+ .env.local
38
+ .env.*.local
39
+
40
+ # Logs
41
+ *.log
42
+ npm-debug.log*
43
+ yarn-debug.log*
44
+ yarn-error.log*
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Temporary files
51
+ tmp/
52
+ temp/
53
+ *.tmp
54
+ typescript/examples/mcp/matimo-tools/.matimo-approvals.json
55
+ typescript/examples/mcp/matimo-tools/fetch-weather/definition.yaml
56
+ typescript/examples/mcp/matimo-tools/npm_downloads/definition.yaml
57
+ typescript/examples/mcp/matimo-tools/skills/ecosystem-health/SKILL.md
58
+ typescript/examples/mcp/matimo-tools/skills/matimo-health-check/SKILL.md
59
+ typescript/examples/mcp/matimo-tools/skills/moltbook-identity/SKILL.md
60
+ typescript/packages/cli/.matimo/certs/server.crt
61
+ typescript/packages/cli/.matimo/certs/server.key
62
+ typescript/examples/mcp/.matimo/certs/server.crt
63
+ typescript/examples/mcp/.matimo/certs/server.key
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: matimo-postgres
3
+ Version: 0.1.0
4
+ Summary: Matimo provider — PostgreSQL tools (query, insert, update, delete, execute SQL)
5
+ License: MIT
6
+ Keywords: agents,ai,matimo,postgres,tools
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: asyncpg>=0.29
13
+ Requires-Dist: matimo-core<0.2.0,>=0.1.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # matimo-postgres
17
+
18
+ > PostgreSQL tools for [Matimo](https://matimo.dev) — execute SQL queries safely with policy-gated approval.
19
+
20
+ [![PyPI](https://img.shields.io/pypi/v/matimo-postgres)](https://pypi.org/project/matimo-postgres/)
21
+ [![Docs](https://img.shields.io/badge/docs-matimo.dev-blue)](https://matimo.dev/docs)
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install matimo matimo-postgres
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Available Tools (1 Tool)
34
+
35
+ | Tool | Description |
36
+ |------|-------------|
37
+ | `execute-sql` | Execute a SQL query against a PostgreSQL database |
38
+
39
+ The `execute-sql` tool is marked `requires_approval: true` — destructive operations (INSERT, UPDATE, DELETE, DROP) trigger HITL approval by default.
40
+
41
+ ---
42
+
43
+ ## Quick Start
44
+
45
+ ```python
46
+ import asyncio
47
+ from matimo import Matimo, InitOptions
48
+ from matimo_postgres import get_tools_path
49
+
50
+ async def main():
51
+ # Auto-approve for read-only usage (CI/CD)
52
+ matimo = await Matimo.init(
53
+ get_tools_path(),
54
+ InitOptions(on_hitl=lambda req: {'approved': True, 'reason': 'auto'}),
55
+ )
56
+
57
+ # Run a SELECT query
58
+ result = await matimo.execute('execute-sql', {
59
+ 'query': 'SELECT id, name FROM users LIMIT 10',
60
+ })
61
+ print(result)
62
+
63
+ asyncio.run(main())
64
+ ```
65
+
66
+ ### With Interactive Approval (Recommended for Writes)
67
+
68
+ ```python
69
+ async def ask_user(request) -> dict:
70
+ print(f"\nSQL requires approval:\n{request.params.get('query')}")
71
+ answer = input("Run this query? [y/n]: ").strip()
72
+ return {'approved': answer == 'y', 'reason': 'user reviewed'}
73
+
74
+ matimo = await Matimo.init(
75
+ get_tools_path(),
76
+ InitOptions(on_hitl=ask_user),
77
+ )
78
+
79
+ # This will prompt before executing
80
+ await matimo.execute('execute-sql', {
81
+ 'query': 'DELETE FROM sessions WHERE expired_at < NOW()',
82
+ })
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Authentication
88
+
89
+ ```bash
90
+ export DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
91
+ # or individual params
92
+ export POSTGRES_HOST="localhost"
93
+ export POSTGRES_PORT="5432"
94
+ export POSTGRES_DB="mydb"
95
+ export POSTGRES_USER="myuser"
96
+ export POSTGRES_PASSWORD="mypassword"
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Security Notes
102
+
103
+ - All SQL queries go through Matimo's **content validator** — SSRF and injection patterns are detected
104
+ - The tool has `requires_approval: true` — writes trigger approval by default
105
+ - Use a **read-only database user** for agent workloads when possible
106
+ - Consider a [policy file](https://matimo.dev/docs/api-reference/POLICY_AND_LIFECYCLE) to restrict allowed SQL patterns
107
+
108
+ ---
109
+
110
+ ## Documentation
111
+
112
+ - [Approval System](https://matimo.dev/docs/api-reference/APPROVAL-SYSTEM)
113
+ - [Policy & Lifecycle](https://matimo.dev/docs/api-reference/POLICY_AND_LIFECYCLE)
114
+ - [Python Examples](https://github.com/tallclub/matimo/tree/main/python/examples/langchain/postgres)
115
+
116
+ ---
117
+
118
+ ## Links
119
+
120
+ - **PyPI:** https://pypi.org/project/matimo-postgres/
121
+ - **GitHub:** https://github.com/tallclub/matimo
122
+
@@ -0,0 +1,107 @@
1
+ # matimo-postgres
2
+
3
+ > PostgreSQL tools for [Matimo](https://matimo.dev) — execute SQL queries safely with policy-gated approval.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/matimo-postgres)](https://pypi.org/project/matimo-postgres/)
6
+ [![Docs](https://img.shields.io/badge/docs-matimo.dev-blue)](https://matimo.dev/docs)
7
+
8
+ ---
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install matimo matimo-postgres
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Available Tools (1 Tool)
19
+
20
+ | Tool | Description |
21
+ |------|-------------|
22
+ | `execute-sql` | Execute a SQL query against a PostgreSQL database |
23
+
24
+ The `execute-sql` tool is marked `requires_approval: true` — destructive operations (INSERT, UPDATE, DELETE, DROP) trigger HITL approval by default.
25
+
26
+ ---
27
+
28
+ ## Quick Start
29
+
30
+ ```python
31
+ import asyncio
32
+ from matimo import Matimo, InitOptions
33
+ from matimo_postgres import get_tools_path
34
+
35
+ async def main():
36
+ # Auto-approve for read-only usage (CI/CD)
37
+ matimo = await Matimo.init(
38
+ get_tools_path(),
39
+ InitOptions(on_hitl=lambda req: {'approved': True, 'reason': 'auto'}),
40
+ )
41
+
42
+ # Run a SELECT query
43
+ result = await matimo.execute('execute-sql', {
44
+ 'query': 'SELECT id, name FROM users LIMIT 10',
45
+ })
46
+ print(result)
47
+
48
+ asyncio.run(main())
49
+ ```
50
+
51
+ ### With Interactive Approval (Recommended for Writes)
52
+
53
+ ```python
54
+ async def ask_user(request) -> dict:
55
+ print(f"\nSQL requires approval:\n{request.params.get('query')}")
56
+ answer = input("Run this query? [y/n]: ").strip()
57
+ return {'approved': answer == 'y', 'reason': 'user reviewed'}
58
+
59
+ matimo = await Matimo.init(
60
+ get_tools_path(),
61
+ InitOptions(on_hitl=ask_user),
62
+ )
63
+
64
+ # This will prompt before executing
65
+ await matimo.execute('execute-sql', {
66
+ 'query': 'DELETE FROM sessions WHERE expired_at < NOW()',
67
+ })
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Authentication
73
+
74
+ ```bash
75
+ export DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
76
+ # or individual params
77
+ export POSTGRES_HOST="localhost"
78
+ export POSTGRES_PORT="5432"
79
+ export POSTGRES_DB="mydb"
80
+ export POSTGRES_USER="myuser"
81
+ export POSTGRES_PASSWORD="mypassword"
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Security Notes
87
+
88
+ - All SQL queries go through Matimo's **content validator** — SSRF and injection patterns are detected
89
+ - The tool has `requires_approval: true` — writes trigger approval by default
90
+ - Use a **read-only database user** for agent workloads when possible
91
+ - Consider a [policy file](https://matimo.dev/docs/api-reference/POLICY_AND_LIFECYCLE) to restrict allowed SQL patterns
92
+
93
+ ---
94
+
95
+ ## Documentation
96
+
97
+ - [Approval System](https://matimo.dev/docs/api-reference/APPROVAL-SYSTEM)
98
+ - [Policy & Lifecycle](https://matimo.dev/docs/api-reference/POLICY_AND_LIFECYCLE)
99
+ - [Python Examples](https://github.com/tallclub/matimo/tree/main/python/examples/langchain/postgres)
100
+
101
+ ---
102
+
103
+ ## Links
104
+
105
+ - **PyPI:** https://pypi.org/project/matimo-postgres/
106
+ - **GitHub:** https://github.com/tallclub/matimo
107
+
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "matimo-postgres"
7
+ version = "0.1.0"
8
+ description = "Matimo provider — PostgreSQL tools (query, insert, update, delete, execute SQL)"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.11"
12
+ keywords = ["ai", "tools", "agents", "matimo", "postgres"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3.11",
18
+ ]
19
+ dependencies = [
20
+ "matimo-core>=0.1.0,<0.2.0",
21
+ "asyncpg>=0.29",
22
+ ]
23
+
24
+ [project.entry-points."matimo.providers"]
25
+ postgres = "matimo_postgres:get_tools_path"
26
+
27
+ [tool.hatch.build.targets.wheel]
28
+ packages = ["src/matimo_postgres"]
@@ -0,0 +1,17 @@
1
+ """Matimo postgres provider — exposes the path to YAML tool definitions."""
2
+ from __future__ import annotations
3
+
4
+ import importlib.resources
5
+ from pathlib import Path
6
+
7
+
8
+ def get_tools_path() -> str:
9
+ """Return the absolute path to the bundled postgres tool definitions."""
10
+ try:
11
+ ref = importlib.resources.files("matimo_postgres") / "tools"
12
+ return str(ref)
13
+ except Exception:
14
+ return str(Path(__file__).parent / "tools")
15
+
16
+
17
+ __all__ = ["get_tools_path"]
@@ -0,0 +1,59 @@
1
+ name: postgres-execute-sql
2
+ version: '1.0.0'
3
+ description: Execute arbitrary SQL against a Postgres database. Supports both connection string and explicit env var configuration.
4
+
5
+ parameters:
6
+ sql:
7
+ type: string
8
+ description: "SQL statement to execute. Use parameterized queries for safety (e.g. $1, $2)."
9
+ required: true
10
+ params:
11
+ type: array
12
+ description: "Optional array of parameters to pass to the query."
13
+ required: false
14
+ schema:
15
+ type: string
16
+ description: "Optional schema name to search for tables or qualify queries."
17
+ required: false
18
+
19
+ execution:
20
+ type: function
21
+ # The function file path is resolved relative to this definition.yaml
22
+ code: ./execute-sql.py
23
+ timeout: 30000
24
+
25
+ authentication:
26
+ type: custom
27
+ notes: |
28
+ The tool supports two authentication modes (choose either):
29
+ 1. Connection string - set `MATIMO_POSTGRES_URL` to a full Postgres connection string (recommended).
30
+ 2. Separate env vars - set `MATIMO_POSTGRES_HOST`, `MATIMO_POSTGRES_PORT`, `MATIMO_POSTGRES_USER`, `MATIMO_POSTGRES_PASSWORD`, `MATIMO_POSTGRES_DB`.
31
+ # Consumers should treat secrets as env variables. This custom auth type
32
+ # documents expected environment variables but does not enforce a single
33
+ # auth scheme - the executor reads either `MATIMO_POSTGRES_URL` or the
34
+ # individual env vars at runtime.
35
+
36
+ error_handling:
37
+ retry: 1
38
+ backoff_type: exponential
39
+ initial_delay_ms: 500
40
+
41
+ output_schema:
42
+ type: object
43
+ properties:
44
+ rows:
45
+ type: array
46
+ items:
47
+ type: object
48
+ rowCount:
49
+ type: number
50
+
51
+ examples:
52
+ - name: Simple select
53
+ params:
54
+ sql: "SELECT id, name FROM users WHERE id = $1"
55
+ params: [1]
56
+
57
+ - name: Parameterless query
58
+ params:
59
+ sql: "SELECT count(*) as cnt FROM users"
@@ -0,0 +1,93 @@
1
+ """
2
+ execute-sql — Execute arbitrary SQL against a PostgreSQL database.
3
+ Mirrors: typescript/packages/postgres/tools/execute-sql/execute-sql.ts
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import os
8
+ from typing import Any
9
+ from urllib.parse import quote_plus
10
+
11
+ from matimo.errors import ErrorCode, MatimoError
12
+
13
+
14
+ async def run(params: dict[str, Any]) -> dict[str, Any]:
15
+ sql: str = params.get("sql", "").strip()
16
+ query_params: list | None = params.get("params")
17
+ schema: str | None = params.get("schema")
18
+
19
+ if not sql:
20
+ raise MatimoError(
21
+ "Missing SQL statement",
22
+ ErrorCode.EXECUTION_FAILED,
23
+ {"tool_name": "postgres-execute-sql"},
24
+ )
25
+
26
+ # Build connection string from MATIMO_POSTGRES_URL or separate env vars
27
+ connection_string = os.environ.get("MATIMO_POSTGRES_URL")
28
+
29
+ if not connection_string:
30
+ host = os.environ.get("MATIMO_POSTGRES_HOST")
31
+ port = os.environ.get("MATIMO_POSTGRES_PORT", "5432")
32
+ user = os.environ.get("MATIMO_POSTGRES_USER")
33
+ password = os.environ.get("MATIMO_POSTGRES_PASSWORD")
34
+ database = os.environ.get("MATIMO_POSTGRES_DB")
35
+
36
+ if host and user and password and database:
37
+ connection_string = (
38
+ f"postgresql://{quote_plus(user)}:{quote_plus(password)}@{host}:{port}/{database}"
39
+ )
40
+
41
+ if not connection_string:
42
+ raise MatimoError(
43
+ "Postgres connection information not provided. "
44
+ "Set MATIMO_POSTGRES_URL or MATIMO_POSTGRES_HOST/PORT/USER/PASSWORD/DB",
45
+ ErrorCode.EXECUTION_FAILED,
46
+ {"tool_name": "postgres-execute-sql"},
47
+ )
48
+
49
+ try:
50
+ import asyncpg # type: ignore[import]
51
+ except ImportError:
52
+ raise MatimoError(
53
+ "asyncpg is required for the postgres tool. Install it with: pip install asyncpg",
54
+ ErrorCode.EXECUTION_FAILED,
55
+ {"tool_name": "postgres-execute-sql"},
56
+ ) from None
57
+
58
+ conn = None
59
+ try:
60
+ conn = await asyncpg.connect(connection_string)
61
+
62
+ # Set search_path if schema is specified
63
+ if schema:
64
+ await conn.execute(f"SET search_path TO {schema}")
65
+
66
+ rows = await conn.fetch(sql, *(query_params or []))
67
+ return {
68
+ "rows": [dict(row) for row in rows],
69
+ "row_count": len(rows),
70
+ }
71
+
72
+ except MatimoError:
73
+ raise
74
+ except Exception as exc:
75
+ msg = str(exc)
76
+ details: dict[str, Any] = {"original_message": msg}
77
+
78
+ if "Connection refused" in msg or "ECONNREFUSED" in msg:
79
+ details["hint"] = "Connection refused — is Postgres running at the configured host/port?"
80
+ elif "role" in msg and "does not exist" in msg:
81
+ details["hint"] = "Database user does not exist — check MATIMO_POSTGRES_USER env var"
82
+ elif "database" in msg and "does not exist" in msg:
83
+ details["hint"] = "Database does not exist — check MATIMO_POSTGRES_DB env var"
84
+
85
+ raise MatimoError(
86
+ f"Postgres query failed: {msg}",
87
+ ErrorCode.EXECUTION_FAILED,
88
+ {"tool_name": "postgres-execute-sql", "details": details},
89
+ ) from exc
90
+
91
+ finally:
92
+ if conn:
93
+ await conn.close()