matimo-postgres 0.1.2__tar.gz → 0.2.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.
@@ -58,7 +58,6 @@ temp/
58
58
 
59
59
  # Personal scratch notes / working docs — not part of the shipped repo
60
60
  .local-notes/
61
- typescript/examples/mcp/matimo-tools/.matimo-approvals.json
62
61
  typescript/examples/mcp/matimo-tools/fetch-weather/definition.yaml
63
62
  typescript/examples/mcp/matimo-tools/npm_downloads/definition.yaml
64
63
  typescript/examples/mcp/matimo-tools/skills/ecosystem-health/SKILL.md
@@ -68,3 +67,6 @@ typescript/packages/cli/.matimo/certs/server.crt
68
67
  typescript/packages/cli/.matimo/certs/server.key
69
68
  typescript/examples/mcp/.matimo/certs/server.crt
70
69
  typescript/examples/mcp/.matimo/certs/server.key
70
+
71
+ # HITL approval manifests are per-machine state (HMAC-signed approvals); never commit one
72
+ **/.matimo-approvals.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ROAIQ TECHNOLOGIES PRIVATE LIMITED
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.5
2
+ Name: matimo-postgres
3
+ Version: 0.2.0
4
+ Summary: Matimo provider — PostgreSQL tools (query, insert, update, delete, execute SQL)
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: agents,ai,matimo,postgres,tools
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Requires-Python: >=3.11
13
+ Requires-Dist: asyncpg>=0.29
14
+ Requires-Dist: matimo-core<0.3.0,>=0.2.0
15
+ Description-Content-Type: text/markdown
16
+
17
+ # matimo-postgres
18
+
19
+ > PostgreSQL tools for [Matimo](https://matimo.dev) - execute SQL queries safely with policy-gated approval.
20
+
21
+ [![PyPI](https://img.shields.io/pypi/v/matimo-postgres)](https://pypi.org/project/matimo-postgres/)
22
+ [![Docs](https://img.shields.io/badge/docs-matimo.dev-blue)](https://docs.matimo.dev)
23
+
24
+ ---
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install matimo matimo-postgres
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Available Tools (1 Tool)
35
+
36
+ | Tool | Description |
37
+ |------|-------------|
38
+ | `postgres-execute-sql` | Execute a SQL query against a PostgreSQL database |
39
+
40
+ The tool does not set `requires_approval` itself - if you want destructive operations
41
+ (INSERT, UPDATE, DELETE, DROP) to require human approval, gate them yourself via a
42
+ [policy file](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE) or a custom
43
+ `PolicyEngine`.
44
+
45
+ ---
46
+
47
+ ## Quick Start
48
+
49
+ ```python
50
+ import asyncio
51
+ from matimo import Matimo
52
+ from matimo_postgres import get_tools_path
53
+
54
+ async def main():
55
+ matimo = await Matimo.init(get_tools_path())
56
+
57
+ # Run a SELECT query
58
+ result = await matimo.execute('postgres-execute-sql', {
59
+ 'sql': '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
+ A query whose `sql` contains a destructive keyword (`DELETE`, `DROP`, `UPDATE`, `INSERT`, `ALTER`, `CREATE`, ...) needs approval. Provide an `on_approval` callback; without one the query is refused:
69
+
70
+ ```python
71
+ from matimo import ApprovalRequest
72
+
73
+
74
+ async def ask_user(request: ApprovalRequest) -> bool:
75
+ print(f"\nSQL requires approval:\n{request.params.get('sql')}")
76
+ return input("Run this query? [y/n]: ").strip() == "y"
77
+
78
+
79
+ matimo = await Matimo.init(get_tools_path(), on_approval=ask_user)
80
+
81
+ # Prompts before executing
82
+ await matimo.execute('postgres-execute-sql', {
83
+ 'sql': 'DELETE FROM sessions WHERE expired_at < NOW()',
84
+ })
85
+ ```
86
+
87
+ The keyword match is a substring of the upper-cased query, so a `SELECT created_at ...` also asks (it contains `CREATE`).
88
+
89
+ ---
90
+
91
+ ## Authentication
92
+
93
+ ```bash
94
+ export MATIMO_POSTGRES_URL="postgresql://user:password@localhost:5432/mydb"
95
+ # or individual params
96
+ export MATIMO_POSTGRES_HOST="localhost"
97
+ export MATIMO_POSTGRES_PORT="5432"
98
+ export MATIMO_POSTGRES_DB="mydb"
99
+ export MATIMO_POSTGRES_USER="myuser"
100
+ export MATIMO_POSTGRES_PASSWORD="mypassword"
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Security Notes
106
+
107
+ - All SQL queries go through Matimo's **content validator** - SSRF and injection patterns are detected
108
+ - The tool itself does not require approval - use a policy file if you want writes gated
109
+ - Use a **read-only database user** for agent workloads when possible
110
+ - Consider a [policy file](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE) to restrict allowed SQL patterns
111
+
112
+ ---
113
+
114
+ ## Documentation
115
+
116
+ - [Approval System](https://docs.matimo.dev/api-reference/APPROVAL-SYSTEM)
117
+ - [Policy & Lifecycle](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE)
118
+ - [Python Examples](https://github.com/tallclub/matimo/tree/main/python/examples/langchain/postgres)
119
+
120
+ ---
121
+
122
+ ## Links
123
+
124
+ - **PyPI:** https://pypi.org/project/matimo-postgres/
125
+ - **GitHub:** https://github.com/tallclub/matimo
126
+
@@ -0,0 +1,110 @@
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://docs.matimo.dev)
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
+ | `postgres-execute-sql` | Execute a SQL query against a PostgreSQL database |
23
+
24
+ The tool does not set `requires_approval` itself - if you want destructive operations
25
+ (INSERT, UPDATE, DELETE, DROP) to require human approval, gate them yourself via a
26
+ [policy file](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE) or a custom
27
+ `PolicyEngine`.
28
+
29
+ ---
30
+
31
+ ## Quick Start
32
+
33
+ ```python
34
+ import asyncio
35
+ from matimo import Matimo
36
+ from matimo_postgres import get_tools_path
37
+
38
+ async def main():
39
+ matimo = await Matimo.init(get_tools_path())
40
+
41
+ # Run a SELECT query
42
+ result = await matimo.execute('postgres-execute-sql', {
43
+ 'sql': 'SELECT id, name FROM users LIMIT 10',
44
+ })
45
+ print(result)
46
+
47
+ asyncio.run(main())
48
+ ```
49
+
50
+ ### With Interactive Approval (Recommended for Writes)
51
+
52
+ A query whose `sql` contains a destructive keyword (`DELETE`, `DROP`, `UPDATE`, `INSERT`, `ALTER`, `CREATE`, ...) needs approval. Provide an `on_approval` callback; without one the query is refused:
53
+
54
+ ```python
55
+ from matimo import ApprovalRequest
56
+
57
+
58
+ async def ask_user(request: ApprovalRequest) -> bool:
59
+ print(f"\nSQL requires approval:\n{request.params.get('sql')}")
60
+ return input("Run this query? [y/n]: ").strip() == "y"
61
+
62
+
63
+ matimo = await Matimo.init(get_tools_path(), on_approval=ask_user)
64
+
65
+ # Prompts before executing
66
+ await matimo.execute('postgres-execute-sql', {
67
+ 'sql': 'DELETE FROM sessions WHERE expired_at < NOW()',
68
+ })
69
+ ```
70
+
71
+ The keyword match is a substring of the upper-cased query, so a `SELECT created_at ...` also asks (it contains `CREATE`).
72
+
73
+ ---
74
+
75
+ ## Authentication
76
+
77
+ ```bash
78
+ export MATIMO_POSTGRES_URL="postgresql://user:password@localhost:5432/mydb"
79
+ # or individual params
80
+ export MATIMO_POSTGRES_HOST="localhost"
81
+ export MATIMO_POSTGRES_PORT="5432"
82
+ export MATIMO_POSTGRES_DB="mydb"
83
+ export MATIMO_POSTGRES_USER="myuser"
84
+ export MATIMO_POSTGRES_PASSWORD="mypassword"
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Security Notes
90
+
91
+ - All SQL queries go through Matimo's **content validator** - SSRF and injection patterns are detected
92
+ - The tool itself does not require approval - use a policy file if you want writes gated
93
+ - Use a **read-only database user** for agent workloads when possible
94
+ - Consider a [policy file](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE) to restrict allowed SQL patterns
95
+
96
+ ---
97
+
98
+ ## Documentation
99
+
100
+ - [Approval System](https://docs.matimo.dev/api-reference/APPROVAL-SYSTEM)
101
+ - [Policy & Lifecycle](https://docs.matimo.dev/api-reference/POLICY_AND_LIFECYCLE)
102
+ - [Python Examples](https://github.com/tallclub/matimo/tree/main/python/examples/langchain/postgres)
103
+
104
+ ---
105
+
106
+ ## Links
107
+
108
+ - **PyPI:** https://pypi.org/project/matimo-postgres/
109
+ - **GitHub:** https://github.com/tallclub/matimo
110
+
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "matimo-postgres"
7
- version = "0.1.2"
7
+ version = "0.2.0"
8
8
  description = "Matimo provider — PostgreSQL tools (query, insert, update, delete, execute SQL)"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -17,7 +17,7 @@ classifiers = [
17
17
  "Programming Language :: Python :: 3.11",
18
18
  ]
19
19
  dependencies = [
20
- "matimo-core>=0.1.0,<0.2.0",
20
+ "matimo-core>=0.2.0,<0.3.0",
21
21
  "asyncpg>=0.29",
22
22
  ]
23
23
 
@@ -0,0 +1,293 @@
1
+ ---
2
+ name: postgres
3
+ description: "Complete guide to all PostgreSQL tools — parameterized queries, schema navigation, data retrieval, and safe database interaction patterns."
4
+ version: "1.0.0"
5
+ license: "MIT"
6
+ metadata:
7
+ category: "Database"
8
+ difficulty: "intermediate"
9
+ apply-to: "postgres-execute-sql"
10
+ tags: "postgres,sql,database,queries"
11
+ ---
12
+
13
+ # PostgreSQL
14
+
15
+ This skill teaches you how to **safely execute SQL queries** against a PostgreSQL database using Matimo tools, with emphasis on parameterized queries, schema awareness, and safe patterns.
16
+
17
+ ## Tools You Will Use
18
+
19
+ | Tool | Purpose |
20
+ |------|---------|
21
+ | `postgres-execute-sql` | Execute any SQL statement against a connected Postgres database |
22
+
23
+ ---
24
+
25
+ ## Executing a Query
26
+
27
+ Use `postgres-execute-sql` to run SQL statements. The tool supports parameterized queries for safety.
28
+
29
+ ### Parameters
30
+
31
+ | Parameter | Type | Description |
32
+ |-----------|------|-------------|
33
+ | `sql` | string | SQL statement to execute. Use `$1`, `$2`, etc. for parameterized values |
34
+ | `params` | array | Optional array of parameter values (matched by position to `$1`, `$2`, etc.) |
35
+ | `schema` | string | Optional schema name for table qualification |
36
+
37
+ ### Critical: Always Use Parameterized Queries
38
+
39
+ **NEVER** interpolate user-provided values directly into SQL strings. Always use `$1`, `$2` placeholders.
40
+
41
+ ```json
42
+ // ✅ SAFE — parameterized
43
+ {
44
+ "sql": "SELECT * FROM users WHERE email = $1",
45
+ "params": ["user@example.com"]
46
+ }
47
+
48
+ // ❌ DANGEROUS — SQL injection risk
49
+ {
50
+ "sql": "SELECT * FROM users WHERE email = 'user@example.com'"
51
+ }
52
+ ```
53
+
54
+ This prevents SQL injection attacks regardless of the input content.
55
+
56
+ ---
57
+
58
+ ## Read Operations
59
+
60
+ ### Select with Parameters
61
+
62
+ ```json
63
+ {
64
+ "sql": "SELECT id, name, email FROM users WHERE id = $1",
65
+ "params": [42]
66
+ }
67
+ ```
68
+
69
+ ### Select with Multiple Conditions
70
+
71
+ ```json
72
+ {
73
+ "sql": "SELECT * FROM orders WHERE status = $1 AND created_at > $2",
74
+ "params": ["pending", "2025-01-01"]
75
+ }
76
+ ```
77
+
78
+ ### Count Records
79
+
80
+ ```json
81
+ {
82
+ "sql": "SELECT count(*) as total FROM users WHERE active = $1",
83
+ "params": [true]
84
+ }
85
+ ```
86
+
87
+ ### Pagination Pattern
88
+
89
+ ```json
90
+ {
91
+ "sql": "SELECT id, name, email FROM users ORDER BY created_at DESC LIMIT $1 OFFSET $2",
92
+ "params": [20, 0]
93
+ }
94
+ ```
95
+
96
+ Increment the offset by the limit for each page: `0`, `20`, `40`, `60`...
97
+
98
+ ### Join Queries
99
+
100
+ ```json
101
+ {
102
+ "sql": "SELECT u.name, o.total, o.status FROM users u JOIN orders o ON u.id = o.user_id WHERE o.status = $1 ORDER BY o.created_at DESC LIMIT $2",
103
+ "params": ["completed", 10]
104
+ }
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Schema Discovery
110
+
111
+ ### List All Tables
112
+
113
+ ```json
114
+ {
115
+ "sql": "SELECT table_name FROM information_schema.tables WHERE table_schema = $1 ORDER BY table_name",
116
+ "params": ["public"]
117
+ }
118
+ ```
119
+
120
+ ### Describe a Table
121
+
122
+ ```json
123
+ {
124
+ "sql": "SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_name = $1 AND table_schema = $2 ORDER BY ordinal_position",
125
+ "params": ["users", "public"]
126
+ }
127
+ ```
128
+
129
+ ### List Indexes
130
+
131
+ ```json
132
+ {
133
+ "sql": "SELECT indexname, indexdef FROM pg_indexes WHERE tablename = $1",
134
+ "params": ["users"]
135
+ }
136
+ ```
137
+
138
+ ### Using Schema Parameter
139
+
140
+ When working with non-default schemas, use the `schema` parameter:
141
+
142
+ ```json
143
+ {
144
+ "sql": "SELECT * FROM customers LIMIT 10",
145
+ "schema": "sales"
146
+ }
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Write Operations
152
+
153
+ ### Insert a Row
154
+
155
+ ```json
156
+ {
157
+ "sql": "INSERT INTO users (name, email, role) VALUES ($1, $2, $3) RETURNING id",
158
+ "params": ["Alice Smith", "alice@example.com", "admin"]
159
+ }
160
+ ```
161
+
162
+ Use `RETURNING` to get the inserted row's ID without a second query.
163
+
164
+ ### Update Rows
165
+
166
+ ```json
167
+ {
168
+ "sql": "UPDATE users SET email = $1, updated_at = NOW() WHERE id = $2 RETURNING id, email",
169
+ "params": ["newemail@example.com", 42]
170
+ }
171
+ ```
172
+
173
+ ### Delete Rows
174
+
175
+ ```json
176
+ {
177
+ "sql": "DELETE FROM sessions WHERE expires_at < NOW() RETURNING id",
178
+ "params": []
179
+ }
180
+ ```
181
+
182
+ ### Upsert (Insert or Update)
183
+
184
+ ```json
185
+ {
186
+ "sql": "INSERT INTO settings (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value RETURNING key, value",
187
+ "params": ["theme", "dark"]
188
+ }
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Understanding the Response
194
+
195
+ Every query returns:
196
+
197
+ ```json
198
+ {
199
+ "rows": [
200
+ { "id": 1, "name": "Alice", "email": "alice@example.com" },
201
+ { "id": 2, "name": "Bob", "email": "bob@example.com" }
202
+ ],
203
+ "rowCount": 2
204
+ }
205
+ ```
206
+
207
+ - **`rows`**: Array of result objects (empty for non-SELECT statements)
208
+ - **`rowCount`**: Number of rows affected (for INSERT/UPDATE/DELETE) or returned (for SELECT)
209
+
210
+ ---
211
+
212
+ ## Common Workflows
213
+
214
+ ### Workflow: Data Exploration
215
+
216
+ 1. **List tables:** Query `information_schema.tables` to see what's available
217
+ 2. **Describe schema:** Query `information_schema.columns` for table structure
218
+ 3. **Sample data:** `SELECT * FROM {table} LIMIT 10` to understand content
219
+ 4. **Targeted queries:** Build specific queries based on discovered schema
220
+
221
+ ### Workflow: Reporting
222
+
223
+ 1. **Aggregate data:** Use `GROUP BY`, `COUNT`, `SUM`, `AVG`
224
+ 2. **Date ranges:** Filter with parameterized date values
225
+ 3. **Multiple queries:** Chain queries to build multi-dimensional reports
226
+
227
+ ```json
228
+ {
229
+ "sql": "SELECT status, count(*) as count, sum(total) as revenue FROM orders WHERE created_at >= $1 GROUP BY status ORDER BY count DESC",
230
+ "params": ["2025-01-01"]
231
+ }
232
+ ```
233
+
234
+ ### Workflow: Safe Bulk Operations
235
+
236
+ Always use transactions for multi-step writes:
237
+
238
+ ```json
239
+ {
240
+ "sql": "BEGIN; UPDATE accounts SET balance = balance - $1 WHERE id = $2; UPDATE accounts SET balance = balance + $1 WHERE id = $3; COMMIT;",
241
+ "params": [100.00, 1, 2]
242
+ }
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Best Practices
248
+
249
+ 1. **Always parameterize.** Every dynamic value should use `$1`, `$2`, etc. — no exceptions.
250
+ 2. **Use LIMIT.** Always add `LIMIT` to SELECT queries to prevent fetching millions of rows.
251
+ 3. **Use RETURNING.** On INSERT/UPDATE/DELETE, use `RETURNING` to avoid a second SELECT.
252
+ 4. **Check rowCount.** Verify the expected number of rows were affected before proceeding.
253
+ 5. **Use specific columns.** Avoid `SELECT *` in production — name the columns you need.
254
+ 6. **Schema-qualify tables.** Use the `schema` parameter or `schema.table` syntax for clarity.
255
+ 7. **Timeout awareness.** Queries timeout after 30 seconds — optimize or paginate large queries.
256
+
257
+ ---
258
+
259
+ ## Error Handling
260
+
261
+ | Error | Cause | Resolution |
262
+ |-------|-------|------------|
263
+ | `ECONNREFUSED` | Database not reachable | Check `MATIMO_POSTGRES_URL` or host/port env vars |
264
+ | `password authentication failed` | Bad credentials | Verify `MATIMO_POSTGRES_PASSWORD` env var |
265
+ | `relation "X" does not exist` | Table not found | Check table name and schema |
266
+ | `column "X" does not exist` | Wrong column name | Query `information_schema.columns` to verify |
267
+ | `syntax error at or near` | Invalid SQL | Check query syntax — use a SQL validator |
268
+ | `query timeout` | Query too slow | Add indexes, use LIMIT, or optimize the query |
269
+
270
+ ---
271
+
272
+ ## Authentication
273
+
274
+ PostgreSQL connection supports two modes:
275
+
276
+ ### Option 1: Connection String (Recommended)
277
+
278
+ Set `MATIMO_POSTGRES_URL`:
279
+ ```
280
+ postgresql://user:password@host:5432/dbname?sslmode=require
281
+ ```
282
+
283
+ ### Option 2: Separate Environment Variables
284
+
285
+ | Env Var | Description |
286
+ |---------|-------------|
287
+ | `MATIMO_POSTGRES_HOST` | Database hostname |
288
+ | `MATIMO_POSTGRES_PORT` | Port (default: 5432) |
289
+ | `MATIMO_POSTGRES_USER` | Username |
290
+ | `MATIMO_POSTGRES_PASSWORD` | Password |
291
+ | `MATIMO_POSTGRES_DB` | Database name |
292
+
293
+ **Never log or expose connection credentials.**
@@ -1,5 +1,6 @@
1
1
  name: postgres-execute-sql
2
2
  version: '1.0.0'
3
+ risk: high
3
4
  description: Execute arbitrary SQL against a Postgres database. Supports both connection string and explicit env var configuration.
4
5
 
5
6
  parameters:
@@ -1,122 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: matimo-postgres
3
- Version: 0.1.2
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
-
@@ -1,107 +0,0 @@
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
-