Tools & Connectors
Knowledge Bases & No-Code
Notion, Confluence, and Airtable toolsets.
#Knowledge bases & no-code
Wiki connectors (Notion, Confluence) and the Airtable no-code database
share enough of a workflow shape — read pages / records, write
pages / records, attach metadata — that they're grouped together here.
Every connector follows the agent-ready toolset pattern (compact
summaries by default, opt-in raw IDs, tolerant write inputs).
#NotionToolSet
NotionToolSet wraps the Notion API.
It uses an integration secret or OAuth bearer token plus aNotion-Version header.
from maivn_tools import NotionToolSet, register_connector connector = NotionToolSet(token=secrets["NOTION_TOKEN"])register_connector(agent, connector)#Tools
| Tool | Permission | Description |
|---|---|---|
get_self() |
READ | Return the bot user the token belongs to. |
get_user(user_id) / list_users() |
READ | User lookup. |
search(query, filter_type, sort_direction, page_size, include_metadata, include_ids, ...) |
READ | Search across pages and databases. |
get_page(page_id) / get_page_property(page_id, property_id, ...) |
READ | Fetch one page or one property. |
create_page(parent, properties, children, icon, cover) |
WRITE | Create a page under a database or page parent. |
update_page(page_id, properties, archived, icon, cover) |
WRITE | Patch page properties or state. |
archive_page(page_id) |
DELETE (destructive) | Soft-delete a page. |
get_database(database_id) |
READ | Database metadata. |
query_database(database_id, filter, sorts, page_size, include_metadata, include_ids, ...) |
READ | Query database rows. |
create_database(parent, title, properties, ...) |
WRITE | Create a database. |
update_database(database_id, title, description, properties) |
WRITE | Update title / schema. |
get_block(block_id) / list_block_children(block_id, ...) |
READ | Fetch blocks. |
append_block_children(block_id, children, after) |
WRITE | Append child blocks. |
update_block(block_id, fields) |
WRITE | Update one block. |
delete_block(block_id) |
DELETE (destructive) | Archive a block. |
list_comments(block_id, ...) |
READ | Comments on a page/block. |
create_comment(parent, discussion_id, rich_text) |
WRITE | Add a comment. |
#Agent-ready behavior
searchandquery_databasereturn compact summaries by default.
Each summary carries a stable ref —page_ref(page_1, ...) for
page objects,result_reffor non-page hits — plus theobject
type (page/database),title,url,last_edited_time,archived, andparent_type(when present).- Default
page_sizeis 25 on bothsearchandquery_database
(max 100).list_usersandlist_block_childrenretain their
Notion-native 100 default. - Notion
idGUIDs are hidden by default. Passinclude_ids=True
to addpage_idto each summary — needed before callingget_page,update_page,archive_page, orget_page_property. - Pass
include_metadata=Falseonsearchorquery_databaseto
receive the raw Notion response, includinghas_moreandnext_cursorpagination cursors. get_page,get_page_property,update_page, andarchive_page
accept either a raw Notion ID string, a summary dict fromsearch
orquery_database, or a list of such dicts. The connector
resolves the ID frompage_idorid.
#Destructive tools
archive_page and delete_block carry destructive=True. Both move
content to Notion's trash. Confirm with the user, or filter them out
with exclude_tags=["destructive"].
#Example: summary-mode search
agent.add_toolset(NotionToolSet(token=secrets["NOTION_TOKEN"])) response = connector.search("runbook", filter_type="page", page_size=10)# response == {# "results": [# {"page_ref": "page_1", "object": "page",# "title": "On-call runbook", "url": "https://www.notion.so/...",# "last_edited_time": "...", "archived": False,# "parent_type": "database_id"},# ...# ],# "has_more": False, "next_cursor": None,# }To act on a result, request raw IDs:
hits = connector.search( "Q3 plan", filter_type="page", include_ids=True)["results"]connector.update_page(hits[0], archived=True)#ConfluenceToolSet
ConfluenceToolSet wraps Atlassian Confluence Cloud REST API v1.
from maivn_tools import ConfluenceToolSet connector = ConfluenceToolSet( base_url="https://acme.atlassian.net", email="ops@acme.com", api_token=secrets["CONFLUENCE_API_TOKEN"],)#Tools
| Tool | Permission | Description |
|---|---|---|
get_current_user() / get_user(account_id) |
READ | Identity lookups. |
list_spaces(space_key, type, ...) / get_space(space_key) |
READ | Spaces. |
create_space(key, name, ...) / delete_space(space_key) |
WRITE / DELETE (destructive) | Manage spaces. |
list_content(type, space_key, title, limit, include_metadata, include_ids, ...) |
READ | List pages, blog posts, comments, or attachments. |
get_content(content_id, expand, version) |
READ | Fetch one item. |
create_page(space_key, title, body, parent_id, representation) |
WRITE | Create a page. |
update_page(content_id, title, body, version, representation) |
WRITE | Update a page. |
delete_content(content_id) |
DELETE (destructive) | Trash content. |
list_children(content_id, type, ...) |
READ | List child content. |
list_versions(content_id, ...) |
READ | Version history. |
list_labels(content_id, ...) / add_label(content_id, label, prefix) / remove_label(content_id, label) |
READ / WRITE / DELETE (destructive) | Labels. |
list_comments(content_id, location, depth, ...) / create_comment(container_id, body, representation) |
READ / WRITE | Comments. |
search(cql, limit, include_metadata, include_ids, ...) / search_content(cql, limit, include_metadata, include_ids, ...) |
READ | CQL search. |
list_attachments(content_id, media_type, filename, ...) |
READ | List attachments. |
#Agent-ready behavior
list_content,search, andsearch_contentreturn compact
summaries by default. Each summary carries a stablepage_ref
(page_1,page_2, ...) plustitle,type,status,space_key,version, and theurl(webui link). Search results
additionally include theexcerptandresultGlobalContainer
fields when present.- Default
limitis 25 onlist_content,search, andsearch_content.list_spacesdefaults to 25 (max 250). - Confluence numeric content IDs are hidden by default. Pass
include_ids=Trueto addcontent_idto each summary — needed
before callingget_content,update_page,delete_content,list_children,list_versions,list_labels,add_label,remove_label,list_comments, orlist_attachments. - Pass
include_metadata=Falseonlist_content,search, orsearch_contentto receive the raw Confluence response, includingstart,limit,size,totalSize, and_linkscursors. - All of the per-content tools above accept either a raw numeric ID
string, a summary dict fromlist_content/search/search_content/get_content, or a list of such dicts. The
connector resolves the ID fromcontent_id,page_id, orid. - Space tools use the human-readable
key(e.g.ENG) — this is the
canonical handle and is safe to surface in final answers.
#Destructive tools
delete_space, delete_content, and remove_label carrydestructive=True. delete_space schedules a long-running deletion
of the space and all its content; delete_content trashes a page
(call again to purge). Confirm with the user, or filter them out
with exclude_tags=["destructive"].
#Example: summary-mode search
agent.add_toolset( ConfluenceToolSet(base_url="https://acme.atlassian.net", email="ops@acme.com", api_token=secrets["CONFLUENCE_API_TOKEN"])) response = connector.search( "space = ENG AND text ~ 'runbook' ORDER BY lastmodified DESC", limit=10,)# response == {# "results": [# {"page_ref": "page_1", "title": "On-call runbook",# "type": "page", "status": "current", "space_key": "ENG",# "version": 12, "url": "/spaces/ENG/pages/...",# "excerpt": "...", "resultGlobalContainer": "Engineering"},# ...# ],# "start": 0, "limit": 10, "size": 4, "totalSize": 4,# }To follow up with an update, request raw IDs:
hits = connector.search( "title = 'On-call runbook'", include_ids=True)["results"]page = connector.get_content(hits[0], expand="body.storage,version")connector.update_page( hits[0], title=page["title"], body=page["body"]["storage"]["value"] + "<p>Updated.</p>", version=page["version"]["number"] + 1,)#AirtableToolSet
AirtableToolSet wraps the Airtable Web + Meta APIs.
It accepts a personal access token (pat...) or an OAuth bearer.
from maivn_tools import AirtableToolSet connector = AirtableToolSet(access_token=secrets["AIRTABLE_PAT"])#Tools
| Tool | Permission | Description |
|---|---|---|
list_bases(offset) |
READ | List bases the token can access. |
get_base_schema(base_id, include) |
READ | Tables + fields for a base. |
create_table(base_id, name, fields, description) |
WRITE | Add a table to a base. |
create_field(base_id, table_id, name, field_type, options, description) |
WRITE | Add a field to a table. |
list_records(base_id, table_id_or_name, view, fields, filter_by_formula, sort, max_records, page_size, offset, cell_format, include_metadata, include_ids, ...) |
READ | List records with full filter / sort / pagination support. |
get_record(base_id, table_id_or_name, record_id) |
READ | Fetch one record. |
create_records(base_id, table_id_or_name, records, typecast, return_fields_by_field_id) |
WRITE | Create up to 10 records per call. |
update_records(base_id, table_id_or_name, records, typecast, replace, perform_upsert) |
WRITE | PATCH (partial) or PUT (replace); supports upsert via perform_upsert.fieldsToMergeOn. |
delete_records(base_id, table_id_or_name, record_ids) |
DELETE (destructive) | Delete up to 10 records per call. |
list_comments(base_id, table_id_or_name, record_id, page_size, offset) |
READ | Record comments. |
create_comment(base_id, table_id_or_name, record_id, text) |
WRITE | Post a comment. |
delete_comment(base_id, table_id_or_name, record_id, comment_id) |
DELETE (destructive) | Delete a comment. |
list_webhooks(base_id) |
READ | Webhooks on a base. |
create_webhook(base_id, notification_url, specification) |
WRITE | Create a webhook (MAC secret returned once). |
delete_webhook(base_id, webhook_id) |
DELETE (destructive) | Delete a webhook. |
list_webhook_payloads(base_id, webhook_id, cursor, limit) |
READ | Pull pending webhook payloads. |
get_current_user() |
READ | /v0/meta/whoami. |
#Agent-ready behavior
list_recordsreturns compact summaries by default. Each summary
carries a stablerecord_ref(record_1,record_2, ...), the
original Airtablefieldsdict for the row, and thecreated_time.- Default
page_sizeis 25 onlist_records.list_commentsand
webhook helpers retain their Airtable-native 100 default. - Raw Airtable record IDs (
rec...) are hidden by default. Passinclude_ids=Trueto addrecord_idto each summary — needed
before callingupdate_records,delete_records,list_comments,create_comment, ordelete_comment. - Pass
include_metadata=Falseto receive the raw Airtable payload
(records with rawidplusoffsetpagination cursor). delete_recordsaccepts a list whose items can be raw Airtable IDs
("rec..."), full record dicts fromlist_records
(include_ids=True) orget_record, or a mixed list. The
connector resolves each entry fromrecord_idorid.
#Destructive tools
delete_records, delete_comment, and delete_webhook carrydestructive=True. delete_records cannot be undone; the others
remove the underlying resource. Confirm with the user, or filter them
out with exclude_tags=["destructive"].
#Example: summary-mode list
agent.add_toolset(AirtableToolSet(access_token=secrets["AIRTABLE_PAT"])) response = connector.list_records( base_id="appXXXXXXXXXXXXXX", table_id_or_name="Customers", filter_by_formula="{Status} = 'Active'", page_size=10,)# response == {# "records": [# {"record_ref": "record_1",# "fields": {"Name": "ACME", "Status": "Active", "MRR": 4500},# "created_time": "..."},# ...# ],# "offset": "...", # only when more results exist# }To delete matching rows, request raw IDs and pipe them straight
through:
hits = connector.list_records( base_id="appXXXXXXXXXXXXXX", table_id_or_name="Customers", filter_by_formula="{Status} = 'Cancelled'", include_ids=True,)["records"]connector.delete_records( base_id="appXXXXXXXXXXXXXX", table_id_or_name="Customers", record_ids=hits[:10], # dicts accepted; the connector resolves IDs)Airtable enforces a max of 10 records per write call; the connector
raises ValueError before the API does. table_id_or_name accepts
either the stable tbl... ID or the human-readable table name (the
connector URL-encodes either form).
See Permissions and dry-run for the permission model
shared by all toolsets.