Skip to main content
Glama

Server Details

Draft, find, update and sign contracts in fynk, the European contract management platform. Your AI assistant can search and summarize your documents, create contracts from templates or PDFs, fill in parties, signatories and dynamic fields, build templates, manage tags, teams and metadata, and send documents out for e-signature (SES, AES, QES). It acts with your own fynk permissions via OAuth. Requires an Essential, Business or Pro plan (14-day free trial) with MCP enabled by an account admin.

Ownership verified
Status
Healthy
Uptime
100.0% over the last 24 hours
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
ChatGPT
–
Claude
fynk

TDQS

A4/5.0

Scored across 68 tools

Disambiguation4/5

Most tools target a distinct resource and action pair: documents vs templates vs account-level entities, and list/get/search/create/update/delete are clearly separated. A few pairs still require care (e.g. list-documents vs get-document-info, list-account-users vs list-account-team-members), but the descriptions draw clear boundaries.

Naming Consistency5/5

Nearly all tools use kebab-case verb-first naming with consistent suffixes for documents, templates, and account resources. Minor plural/singular variation, such as update-document-dynamic-fields vs update-template-dynamic-field, does not undermine the overall pattern.

Tool Count1/5

At 68 tools, the surface is far beyond the typical 3-15 range and is extremely heavy even for a broad contract-management domain. The set covers many workflows, but the sheer number of tools makes it overextended and hard to navigate as a coherent whole.

Completeness4/5

Core document lifecycle and template authoring are well covered, including CRUD for account resources and document parties, signatories, metadata, and dynamic fields. Some gaps remain around template archiving/deletion and basic template metadata updates, while playbooks, automations, and imports are only list/search-oriented.

Publisher details

Operator
fynk · Publisher source
Vendor relationship
First-party
Restrictions
Requires a fynk Essential, Business or Pro plan (or 14-day free trial) with MCP enabled by an account owner or admin under Account Settings → MCP; no regional limits or custom OAuth app needed, as clients register automatically via OAuth. · Publisher source

Available Tools

68 tools
archive-documentArchive documentA
DestructiveIdempotent
Inspect

Archives a document, hiding it from the account's default document lists.

Use this tool when:

  • A document is no longer actively worked with and should be moved out of the way

  • The user asks to archive, hide, or clean up a document

Archiving does not delete anything: the document keeps all its data and can be restored later with the restore-document tool. The document must not already be archived.

Inputs: document_uuid (required). Returns: url, name, uuid, stage, +5 more

attach-account-users-to-teamAttach account users to teamA
DestructiveIdempotent
Inspect

Add one or more account users as members of a team.

Use this tool when:

  • The user asks to add people to a team

Membership can give people access to the documents, templates, imports and automations assigned to the team, subject to their own permissions, so confirm who is being added when the user's request leaves room for doubt.

Existing members of the team are preserved. Use detach-account-users-from-team to remove members. Pass account_user_uuids from list-account-users, list-account-team-members (when copying members between teams), or the account-user uuids the user references.

Inputs: team_uuid (required), account_user_uuids (required). Returns: icon, name, uuid, _entity_type

create-account-document-typeCreate account document typeAInspect

Create a new custom document type for the account.

Use this tool when:

  • The user asks for a new kind of document to be distinguished, e.g. "add a Framework Agreement document type"

  • A document or template needs a document type that the account does not have yet

Call list-account-document-types first: fynk already provides system document types such as "Non-Disclosure Agreement", "Rental Agreement" or "Service Agreement" to every account, and a custom type that duplicates one of them splits the account's documents across two types. Create a new type only when none of the existing ones fits.

Write name in Title Case, the way fynk's own types are named ("Data Processing Agreement", "Letter of Intent"), rather than copying the user's phrasing verbatim - a request for "a type for supplier framework contracts" should produce "Supplier Framework Agreement".

description and prompt are how a new type is normally set up, so propose both from what the type is for rather than leaving them out:

  • description tells users what the type covers, in one sentence. fynk's "Rental Agreement" reads: "A contract between a landlord and tenant defining the terms under which property is rented, including duration, payment terms, and usage conditions."

  • prompt is what fynk's AI analyses read when deciding whether a document is of this type - without one, they rarely pick the type. Phrase it as a selection criterion, the way fynk's own types do. "Rental Agreement" reads: "Select this type if the document defines the terms under which a tenant rents property from a landlord, including rent amount, duration, deposit, and usage conditions."

relevant_metadata_uuids decides which metadata fields fynk's AI analyses look for in documents of this type, besides the fields already relevant for every document type, which apply to the new type automatically. Call list-account-metadata to find the candidates, and propose the fields that type's documents would carry, e.g. a "Net Rent" field for a lease type. The fields chosen here are made relevant for the new type alongside the types they already have, and list-account-metadata reports the result: each field there names the document types it is relevant for.

Inputs: name (required), prompt, description, relevant_metadata_uuids. Returns: name, uuid, prompt, customised, +3 more

create-account-metadataCreate account metadataAInspect

Create a new account-level metadata field definition.

Use this tool when:

  • The user asks for a new metadata field to track some piece of information on their documents

  • You need a metadata field to exist before writing values to it with update-document-metadata-values

Call list-account-metadata first: the account may already have a field for what the user wants, and fynk provides a range of system metadata fields that cannot be re-created under the same name.

name is the programmatic identifier (lowercase letters, digits and underscores only) and display_name is what the user sees. Write display_name in Title Case, the way fynk's own fields are named ("Signing Date", "Contract Value"), rather than copying the user's phrasing verbatim - a request for "a product colour metadata" should still produce product_colour / "Product Colour".

select and multi_select fields require select_values (the allowed options); no other field type accepts them. These strings are literally what the user picks from in the UI, so write them as presentable labels, capitalised like display_name: "Red", "Green", "Blue", not the "red, green or blue" lifted out of the request.

name and value_type are fixed at creation and cannot be changed afterwards, and it is worth getting the rest right first time rather than leaving a correction to make later. So confirm any detail the user has not spelled out instead of guessing at it - in particular the exact select_values strings, since a request like "a colour field with red, green or blue" names the options without settling how they should read.

prompt and keywords decide whether fynk's AI analyses fill this field in - a prompt puts the field into them, keywords only assist it and do nothing on their own. This is how a new field is normally set up: fynk's own creation form turns AI analysis on by default and requires both. So propose a prompt and keywords drawn from what the field is for rather than silently leaving them out, and omit both only for a field the user wants to fill in by hand. Set a description as well - it is what tells a user configuring the field what it holds.

Inputs: name (required), value_type (required), display_name (required), prompt, +5 more. Returns: name, type, uuid, settings, +8 more

create-account-tagCreate account tagAInspect

Create a new tag in the current account.

Use this tool when:

  • The user asks to create a new tag

  • You need a new tag to be available before attaching it to documents or templates

name (max 40 chars) and color (hex like "#FF0000") are required.

Inputs: name (required), color (required). Returns: name, uuid, color, _entity_type

create-account-teamCreate account teamAInspect

Create a new team in the current account.

Use this tool when:

  • The user asks to create a new team

  • You need a new team to be available before attaching it to documents or templates

The tool requires name. Do not ask the user about an icon — the team will use the default icon. Optionally pass account_user_uuids to add initial members. After creation, don't expose the UUID to the user.

Inputs: name (required), account_user_uuids. Returns: icon, name, uuid, _entity_type

create-document-from-pdf-uploadCreate document from PDF uploadAInspect

Create a new document from a PDF previously uploaded via create-document-pdf-upload-url.

Use this tool when:

  • The user wants to import an existing PDF into fynk as a draft document for further processing, OR

  • The user wants to record an already-signed PDF in fynk by setting initial_stage to "done"

Call create-document-pdf-upload-url first to obtain file_upload_uuid, then upload the PDF to the URL it returns with a multipart/form-data POST, as that tool describes, before calling this tool. initial_stage is required and must be either "draft" or "done"; ask the user which they want if it isn't clear from context. Depending on the account's settings, template_uuid may be required (it copies checkpoints, document type, metadata, parties, etc. from a template).

Only pass auto_apply_ai_analysis when the user has expressed whether AI analysis results should be applied to the document automatically; omit it to use the account's default setting.

The team_uuids, tag_uuids, and account_party_uuid arguments expect UUIDs, which can be discovered via list-account-teams, list-account-tags, and list-account-parties respectively.

Inputs: file_name (required), initial_stage (required), file_upload_uuid (required), tag_uuids, +5 more. Returns: url, name, tags, uuid, +23 more

create-document-from-scratchCreate document from scratchAInspect

Create a new, empty document from scratch (not based on a template), optionally assigning teams, tags, and an account party.

Use this tool when:

  • The user wants to start a new blank document that is not based on a template

The document is created in the draft stage with no content. To create a document based on a template instead, use create-document-from-template.

The team_uuids, tag_uuids, and account_party_uuid arguments expect UUIDs, which can be discovered via list-account-teams, list-account-tags, and list-account-parties respectively.

Inputs: name (required), tag_uuids, team_uuids, account_party_uuid. Returns: url, name, tags, uuid, +23 more

create-document-from-templateCreate document from templateA
Destructive
Inspect

Create a new document from a template, optionally pre-filling parties, signatories, and dynamic fields, and optionally starting the signing process immediately.

Use this tool when:

  • The user wants to generate a document based on an existing template

It is usually helpful to call get-template-info with include=["parties", "signatories", "dynamic_fields"] first to discover the template's parties, signatories, and dynamic fields so that the parties, signatories, and dynamic_field_values arguments can be populated correctly.

When completing dynamic fields, take note of the field's type when constructing the value. These are the rules to use when constructing the value string:

  • number: the numeric value in a string, using '.' as the decimal separator -> "1234.56"

  • currency: concatenate the ISO currency code and the numeric value with a ';' -> "EUR;1000.10" (for one thousand Euro and ten cents)

  • currency_duration: same as currency, but append another ';' followed by either monthly or yearly -> "EUR;1000.10;monthly" / "USD;1000.10;yearly"

  • select: one of the options from the field's select_values list -> "red"

  • multi_select: an array of the selected values in the values field -> ["red", "blue"]

  • bool: either of the strings "true" (displayed to the user as "Yes") or "false" (displayed to the user as "No") -> "true" / "false"

  • duration: a PHP-compatible duration specification -> "P6D" (6 days), "P2W" (2 weeks), "PT12H" (12 hours)

  • date: the date in the format "YYYY-MM-DD" -> "2026-12-31"

  • email, text, textarea, or any type not listed above: a string -> "test@example.com"

Setting start_signing=true will move the new document straight into the signing stage and invite the signatories to sign it; this fails if any required information (party data, mandatory dynamic field values, signature blocks) is missing.

Inputs: template_uuid (required), parties, signatories, document_name, +2 more. Returns: url, name, tags, uuid, +23 more

create-document-partyCreate document partyAInspect

Adds a party to a document, alongside any parties it already has.

Use this tool when:

  • A contracting party is missing from a document, e.g. the counterparty of a contract created from scratch

  • A signatory has to be added for a party the document does not have yet: create the party first, then add the signatory with create-document-signatory

Pass party_account_party_uuid to add one of the account's saved parties (list-account-parties), usually the user's own company. A saved party can be on a document only once, and is always internal. For any other party, give party_entity_name, party_address and party_scope instead.

Parties cannot be added while the document is archived, in the signing stage or an approved stage, going through an approval checkpoint, or bound by a preemptive signature.

Inputs: document_uuid (required), party_reference (required), party_scope, party_address, +2 more. Returns: uuid, address, ref_uuid, reference, +3 more

create-document-pdf-upload-urlCreate document PDF upload URLAInspect

Create a signed URL that a single PDF can be POST-uploaded to, for later use with create-document-from-pdf-upload.

Use this tool when:

  • The user wants to create a document from an existing PDF file and you need somewhere to upload it to first

Returns a uuid (pass it to create-document-from-pdf-upload after the upload completes), a url (target of the POST request), a fields map to send as form fields in the POST body before the file itself, and an expires_at timestamp after which the URL stops working.

Inputs: no named parameters. Returns: url, uuid, fields, expires_at

create-document-signatoryCreate document signatoryA
Destructive
Inspect

Adds a signatory to a document.

Use this tool when:

  • You have a document with one or more parties configured and want to add a signatory for one of the parties.

The signatory becomes a user of the document and is invited by email to sign it once the document moves to the signing stage, so confirm the email address with the user rather than inferring it.

When adding a signatory whose email corresponds to an existing user in the current fynk account, all of the optional arguments will be ignored and the signatory information will be populated from the existing user's profile.

Inputs: document_uuid (required), signatory_email (required), signatory_party_identifier (required), signatory_title, +3 more. Returns: name, uuid, email, party_uuid, +3 more

create-template-dynamic-fieldCreate template dynamic fieldAInspect

Create a new dynamic field on a template.

Use this tool when:

  • The user wants to add a variable / fill-in field (e.g. text, number, date, select) to a template

  • You are building up a template and need a placeholder whose value is filled in per document

IMPORTANT: this is only the first of two steps. Creating the field does NOT place it in the template content, so on its own the fill-in placeholder will not appear in the document text. To make it show up, reference the returned ref_uuid in the template body (via replace-template-content) as:

<span data-dynamic-field data-ref-uuid="<dynamic field ref_uuid>"></span>

Until it is referenced in the content the field exists but is rendered nowhere. The same two-step pattern applies to signature blocks (create-template-signature-block, then <div data-signatures><span data-signature-block data-ref-uuid="..."></span></div>).

Dynamic fields define the variable data filled in when a template is used to create a document. Each field has a type controlling what values it accepts, and a scope controlling who fills it in.

A party's name or address is never a dynamic field. Both live on the party record: add the party with create-template-party and render its details in the content with , taking data-format="address" for the address as a block and data-format="address:inline" for it on one line, as a preamble reads it. A document made from the template then follows its own parties.

select and multi_select fields require select_values (the allowed options).

The optional default value is set via value (for non-multi_select fields) or values (for multi_select fields). Construct the value string according to the field type:

  • number: the numeric value in a string, using '.' as the decimal separator -> "1234.56"

  • currency: concatenate the ISO currency code and the numeric value with a ';' -> "EUR;1000.10"

  • currency_duration: same as currency, but append another ';' followed by either monthly or yearly -> "EUR;1000.10;monthly"

  • select: one of the options from select_values -> "red"

  • multi_select: an array of the selected options in the values field -> ["red", "blue"]

  • bool: either of the strings "true" (shown as "Yes") or "false" (shown as "No")

  • duration: a PHP-compatible duration specification -> "P6D" (6 days)

  • date: the date in the format "YYYY-MM-DD" -> "2026-12-31"

  • email, text, textarea, or any type not listed above: a string -> "test@example.com"

Inputs: name (required), type (required), template_uuid (required), scope, +5 more. Returns: name, type, uuid, scope, +8 more

create-template-from-scratchCreate template from scratchAInspect

Create a new empty template with editable ProseMirror content.

Use this tool when:

  • The user wants to start building a new template from scratch (not from an existing PDF or template)

The new template is created empty and its content is authored in a later step. The body references parties, dynamic fields and signature blocks by ref_uuid, so those have to exist before the content can point at them. Build the template in this order:

  1. create-template-party for each contracting party.

  2. create-template-signature-block for each party that signs.

  3. create-template-dynamic-field for every value that varies per document - dates, amounts, notice periods, payment terms. A party's name or address is never one of them: both live on the party record and the content renders them from there.

  4. replace-template-content once, with a body that references all of them by their ref_uuids and wraps each clause in an ordered list node so fynk numbers it.

Authoring the content first and adding the parties, fields and signature blocks afterwards forces a second, destructive rewrite of the whole body to weave the references in, so plan them up front. This applies just as much when the content is derived from a source document such as a PDF: every filled-in blank in the source is a dynamic field unless it holds party identity, and its signature lines are signature blocks.

The locale defines the template's content language and default number formats. Never ask the user for it - a BCP 47 tag is not something they can be expected to know. Infer it from the conversation, e.g. the language the content is to be written in or a country or jurisdiction the user names, and otherwise omit it, which falls back to the account's locale.

Inputs: name (required), locale. Returns: url, name, tags, uuid, +19 more

create-template-partyCreate template partyAInspect

Add a party to a template.

Use this tool when:

  • The user wants to add a party (e.g. a counterparty, customer, or employer) to a template

  • You are building up a template and need parties before adding signatories or signature blocks

There are two ways to add a party:

  • Internal (saved) party: send account_party_uuid (from list-account-parties) together with reference. No other fields may be sent in this case.

  • External party: send reference and scope, and optionally entity_name and address.

The two names on a party say different things:

  • reference is the generic label for the party's role on the template (e.g. "Employer", "Customer"), and stays the same for every document made from it.

  • entity_name is the name of the legal entity itself: a company's name ("Acme GmbH") or, when the party is an individual rather than an organisation, that person's name. On a template it is usually only known for the account's own side; a counterparty's is filled in per document, so leave it out rather than inventing one.

To render the party's details inline in the template text, reference the returned ref_uuid in the body (via replace-template-content) as:

<span data-party data-ref-uuid="<party ref_uuid>" data-format="name"></span>

where data-format selects what is rendered: "name" (the party's entity/company name), "reference" (its reference label), "address", or "address:inline". A data-format is required.

Note: adding a party does not, by itself, give that party anywhere to sign. If the party is meant to sign documents created from the template, follow up with create-template-signature-block for the party — and remember that the signature block must in turn be placed in the template content (via replace-template-content) inside a signature container, <div data-signatures><span data-signature-block data-ref-uuid="..."></span></div>, before it will appear on any document.

Inputs: reference (required), template_uuid (required), scope, address, +2 more. Returns: uuid, address, ref_uuid, reference, +3 more

create-template-signature-blockCreate template signature blockAInspect

Add a signature block to a template, bound either to one of its parties or to a single signatory.

Use this tool when:

  • The user wants a party to have a place to sign on documents created from the template

  • The user wants one specific signatory to have their own place to sign

  • You are building up a template and need to add signing slots

Pass exactly one of party_uuid or document_user_uuid. A party-bound block is signed by every signatory of that party, whoever they turn out to be on a document created from the template; a user-bound block is signed only by the signatory it names. Use get-template-info with include=["parties", "signatories"] to discover the available parties and signatories and their UUIDs.

A user-bound block requires a signatory that belongs to a party, because the block records that party alongside the signatory.

IMPORTANT: this is only the first of two steps. Creating the signature block does NOT place it in the template content, so on its own it will not appear on any document. To make it show up, reference the returned ref_uuid in the template body (via replace-template-content) from a signature container, which houses one or more blocks:

<div data-signatures data-align="left"><span data-signature-block data-ref-uuid="<signature block ref_uuid>"></span></div>

A block is always placed inside such a container, even when it is the only one.

Until it is referenced in the content the block exists but is rendered nowhere. The same two-step pattern applies to dynamic fields (create-template-dynamic-field, then <span data-dynamic-field data-ref-uuid="...">).

style (regular or minimal) and scale (50–150, percent) are optional and default to "regular" and 100.

Inputs: template_uuid (required), scale, style, party_uuid, +1 more. Returns: uuid, scale, style, ref_uuid, +3 more

delete-account-document-typeDelete account document typeA
DestructiveIdempotent
Inspect

Remove a document type from the account, whether it is one of the account's own types or one of fynk's system document types.

Use this tool when:

  • The user explicitly asks to delete or remove a document type

document_type_uuid comes from list-account-document-types, and the user must have made clear which type they mean - either by naming it, or because it is the type this conversation has been about. Ask which one they mean when that is not clear, offering the candidates by name.

What removing a type does depends on what list-account-document-types reports for it. A type the account created itself, without provided_by_fynk, is deleted for good. One of fynk's own types, with provided_by_fynk, is deactivated instead: it disappears from the account but can be brought back as fynk provides it with update-account-document-type and reactivate: true. A customised type loses its customisation either way, so tell the user so before going ahead with one.

A type that documents or templates still use cannot be removed. The refusal says how many use it.

Inputs: document_type_uuid (required). Returns: deleted_document_type, deactivated_document_type

delete-account-metadataDelete account metadataA
DestructiveIdempotent
Inspect

Delete one of the account's own metadata field definitions.

Use this tool when:

  • The user explicitly asks to delete a metadata field

metadata_uuid comes from list-account-metadata, and the user must have made clear which field they mean - either by naming it, or because it is the field this conversation has been about. Ask which one they mean when that is not clear, offering the candidates by their display name.

Deleting a field also removes every value recorded for it, on every document and template in the account, and none of that can be brought back. So deleting a field the account has recorded values for is refused until the user has confirmed it: the refusal names the field and how many documents and templates hold a value for it - then repeat the call with confirmed_deleting_values_in_use: true once they have confirmed it. Send that only in answer to such a refusal, never as a matter of course.

Put the effect to the user in their own terms and ask before going ahead - "deleting Discount Rate would also remove the value 12 documents hold for it, shall I go ahead?" - rather than quoting the refusal back at them. Name the field you are about to delete either way, and never delete more than the user asked for.

Where the user wants a field to stop being filled in rather than to lose what it already holds, clear its prompt with update-account-metadata instead: that takes the field out of fynk's AI analyses and leaves the values on their documents alone.

Only the account's own fields can be deleted. fynk's system fields are provided to every account and cannot be removed, system_reference fields included - use update-account-metadata to change how one of those is configured for this account.

Deletion is refused while a bulk metadata operation is still running for the field.

Inputs: metadata_uuid (required), confirmed_deleting_values_in_use. Returns: removed_values, deleted_metadata

delete-account-tagDelete account tagA
DestructiveIdempotent
Inspect

Delete an existing tag.

Use this tool when:

  • The user explicitly asks to delete a tag

The specified tag is deleted and detached from documents and templates automatically.

Inputs: tag_uuid (required). Returns: deleted_tag

delete-account-teamDelete account teamA
DestructiveIdempotent
Inspect

Delete an existing team.

Use this tool when:

  • The user explicitly asks to delete a team

The specified team is deleted and detached from documents and templates automatically. Deletion will fail if the team is assigned as an approver on any template.

Inputs: team_uuid (required). Returns: deleted_team

delete-document-signatoryDelete document signatoryA
DestructiveIdempotent
Inspect

Remove a signatory from a document.

Use this tool when:

  • A signatory was added in error or should no longer sign and the document has not yet been signed by them

Identify the signatory to remove by document_uuid plus signatory_email. Removal may fail if the document's stage no longer permits signatory changes.

Inputs: document_uuid (required), signatory_email (required). Returns: removed_signatory

delete-template-dynamic-fieldDelete template dynamic fieldA
DestructiveIdempotent
Inspect

Delete a dynamic field from a template.

Use this tool when:

  • The user explicitly asks to remove a dynamic field (a variable / fill-in field) from a template

A dynamic field cannot be deleted while it is referenced by a condition or a metadata value on the template; remove those references first. Use get-template-info with include=["dynamic_fields"] to discover the dynamic fields on a template and their UUIDs.

Inputs: template_uuid (required), dynamic_field_uuid (required). Returns: deleted_dynamic_field

delete-template-partyDelete template partyA
DestructiveIdempotent
Inspect

Delete a party from a template.

Use this tool when:

  • The user explicitly asks to remove a party from a template

A party cannot be deleted while it still has signature blocks bound to it. Delete those signature blocks first with delete-template-signature-block. Use get-template-info to discover the parties on a template and their UUIDs.

Inputs: party_uuid (required), template_uuid (required). Returns: deleted_party

delete-template-signature-blockDelete template signature blockA
DestructiveIdempotent
Inspect

Delete a signature block from a template.

Use this tool when:

  • The user explicitly asks to remove a signature block (a party's signing slot) from a template

The party the signature block belonged to remains on the template; only the signing slot is removed. Use get-template-info with include=["signature_blocks"] to discover the signature blocks on a template and their UUIDs.

Inputs: template_uuid (required), signature_block_uuid (required). Returns: deleted_signature_block

detach-account-users-from-teamDetach account users from teamA
DestructiveIdempotent
Inspect

Remove one or more account users from a team.

Use this tool when:

  • The user asks to remove people from a team

Only the account users listed in account_user_uuids are removed; other team members stay attached. Passing a user that is not on the team is a no-op.

Inputs: team_uuid (required), account_user_uuids (required). Returns: icon, name, uuid, _entity_type

duplicate-documentDuplicate documentAInspect

Create a new draft document as a copy of an existing document.

Use this tool when:

  • The user wants to duplicate or copy a document, e.g. to reuse a previous contract as the starting point for a new one with a different counterparty

  • A new agreement should start from an existing document rather than from a template

The copy takes over the source document's content, parties, signatories, dynamic field values, metadata values, attachments, teams, tags, document type and template link. The new document always starts in the draft stage, whatever stage the source document is in, and a source document that is in signing or done is copied with its content as it was before signing started.

Change what differs in the new document afterwards with the update-* tools, e.g. update-document-party for the counterparty or update-document-dynamic-fields for amounts and dates.

Inputs: document_uuid (required), name. Returns: url, name, tags, uuid, +23 more

duplicate-templateDuplicate templateAInspect

Create a new template as a copy of an existing template.

Use this tool when:

  • The user wants to duplicate or copy a template, e.g. to build a variant of an existing contract for another jurisdiction or business line

  • A new template should start from an existing one rather than from scratch

The copy takes over the source template's content, parties, signatories, signature blocks, dynamic fields, conditions, metadata values, attachments, teams, tags, document type, locale and published state. Documents already created from the source template stay linked to the source.

Change what differs in the new template afterwards with the template tools, e.g. update-template-party, update-template-dynamic-field or replace-template-content. replace-template-content only writes a draft, so a copy of a published template has to be unpublished with set-template-published-state before its body can be rewritten.

Inputs: template_uuid (required), name. Returns: url, name, tags, uuid, +19 more

get-account-infoGet account infoA
Read-onlyIdempotent
Inspect

Get information about the current fynk account.

Use this tool when:

  • You need details about the active account (e.g. default document locale, signature settings) before tailoring a response

  • You are tailoring guidance to the account's business, and need what it reported about itself when signing up (industry, company size, the department the person who signed up works in)

For information about the current user, use get-user-info

Inputs: no named parameters. Returns: name, locale, status, created_at, +11 more

get-document-infoGet document infoA
Read-onlyIdempotent
Inspect

Gets information about a document.

Use this tool when:

  • You have a document's UUID and want to know more details about it. e.g. who is signing it, what values its dynamic fields or metadata have, etc

Called with no include parameter, returns the document's parties, teams, details, signatories, signing settings and workflow state. Use include to name the sections you want instead - among them dynamic_fields, conditions, metadata_values, signature_blocks, summary_text, tags, timestamps, attachments and stored_files - and the response carries exactly those, so a question about one aspect of a document costs one section rather than the whole document.

The stored_files section holds what the app shows as "Internal file storage", separate from attachments: call them that when talking to the user, never "stored files".

This tool covers a single document. Whenever possible avoid calling it once per document to gather the same information about several documents: list-documents returns parties, teams, tags and timestamps for a whole list via its include parameter, and specific metadata values for a whole list via its include_metadata parameter. Pass the UUIDs you already have to its filter_document_uuids parameter to get exactly the documents you are interested in.

The default response lists both the document's parties (the contracting entities, frequently organizations) and its signatories (the individual people who sign). These are distinct: a person often signs on behalf of a party (e.g. a business) without appearing as a party, so consider the signatories — not just the parties — when answering whether a specific named person is involved in or signs a document.

The dynamic_field_visibility argument narrows the dynamic_fields section to the fields that appear in the document itself, or to the ones that do not. A field belonging to a document is not necessarily written into it: fields get added and then never placed in the text, or the passage that referred to one gets rewritten, leaving a value no reader ever sees. Not every not_visible field is idle, though. Some exist only to drive a condition deciding which clauses the document shows, so they shape the contract without appearing in it (you can use the "conditions" include option to see which fields drive which conditions). Others sit inside a passage that a currently inactive condition removes, so they would appear if that condition flipped. Use "visible" when the question is about what the contract currently says. dynamic_field_visibility has no effect unless dynamic_fields is among the returned sections.

The workflow_state object - in the response by default, and requestable via include alongside other sections - describes what can currently be done with the document: whether the signing process can be started at all, which stages the document can be moved on to and everything standing in the way of each of them (stage_transitions, whose blockers say why), whether the requesting user can start signing, and — when a checkpoint blocks progress — who still needs to approve. Use it to answer questions like "why can't I sign this yet?", "what is blocking this document?" or "who still has to sign?", answering with the full list rather than one problem at a time. It is technical state, not display content: relay it to the user as natural-language prose and never echo raw field names or snake_case values.

Inputs: document_uuid (required), include, dynamic_field_visibility. Returns: url, name, tags, uuid, +23 more

get-latest-document-pdf-urlGet latest document PDF URLA
Read-onlyIdempotent
Inspect

Get a download URL for the latest revision of a document as a PDF.

Use this tool when:

  • The user wants to download the current state of a document as a PDF

  • You need a PDF link to share with the user for review

Returns the URL as plain text. The URL is short-lived; fetch a new one if it expires before download.

Inputs: document_uuid (required).

get-template-htmlGet template HTMLA
Read-onlyIdempotent
Inspect

Returns the content of a template serialised as HTML.

Use this tool when:

  • You want to read or navigate the content of a template

  • You want to understand the structure of a template before editing it

The HTML uses semantic data-* attributes to represent fynk-specific nodes such as dynamic fields, party references, and signature blocks. Addressable nodes (paragraphs, headings, etc.) carry a data-uuid attribute that can be used to target individual nodes in subsequent operations.

Clause numbering is dynamic. Numbered clauses are ordered list nodes — <div data-list data-kind="ordered"> — that contain the clause text and, when nested, sub-clauses. Their computed number is shown read-only via a data-number attribute (e.g. data-number="1.1."). Numbers are never part of the text; do not treat them as editable content.

A cross-reference to a clause appears as <span data-section-ref data-uuid="...">, where data-uuid is the data-uuid of the list node it points at. It is empty: what it renders is that clause's computed number, so it follows the clause rather than stating a number of its own.

Dynamic fields (fill-in placeholders) appear inline as <span data-dynamic-field data-ref-uuid="...">, where data-ref-uuid is the field's ref_uuid (see get-template-info include=["dynamic_fields"]). Signature blocks are grouped in a signature container — <div data-signatures data-align="..."><span data-signature-block data-ref-uuid="..."></span></div> — where each <span data-signature-block> points at one block by its ref_uuid (see get-template-info include=["signature_blocks"]). Legacy content may still show a block outside any container, as <div data-signature-block data-ref-uuid="...">; writing it back turns it into a container holding that one block. Party references appear as <span data-party data-ref-uuid="..." data-format="name|reference|address|address:inline">, where data-format selects what is rendered (name = the party's entity_name, reference = its reference name).

Images (<img data-image>), dynamic tables (<div data-dynamic-table>) and signing vote blocks (<span data-signing-vote-block>) appear as empty reference tags. Their contents are held outside the HTML and cannot be created or edited through it, so copy these tags over unchanged when rewriting the template; dropping one removes the image or table from the template.

Text formatting - bold, colour, font, size, highlight - is stated inline, as the style of the tag carrying it. A block's layout is not: the margins, indent and line height a paragraph or heading is laid out with stay on the block itself, so the HTML says nothing about them.

A block's alignment is stated, as data-text-align on the paragraph, heading or list node carrying it - left, center, right or justify - with a matching text-align style alongside it. A block carrying neither is aligned left.

Only available for templates with a prosemirror_data content type. Returns an error for PDF templates.

Inputs: template_uuid (required). Returns: html

get-template-infoGet template infoA
Read-onlyIdempotent
Inspect

Gets information about a template.

Use this tool when:

  • You have a template's UUID and want to know more details about it.

  • e.g. when you want to create a document from the template and need to know which parties, dynamic fields, etc are available in the template.

Called with no include parameter, returns the template's identity, its parties, its teams, its description and its signing settings. Use include to name the sections you want instead - among them signatories, signature_blocks, dynamic_fields, conditions, metadata_values, tags, timestamps, attachments and stored_files - and the response carries exactly those, so a question about one aspect of a template costs one section rather than the whole template.

The stored_files section holds what the app shows as "Internal file storage", separate from attachments: call them that when talking to the user, never "stored files".

Inputs: template_uuid (required), include. Returns: url, name, tags, uuid, +19 more

get-user-infoGet user infoA
Read-onlyIdempotent
Inspect

Get information about the current user.

Use this tool when:

  • You need to know who the current user is (email, locale, roles) before tailoring a response

For information about the current fynk account, use get-account-info

Inputs: no named parameters. Returns: email, roles, locale, _entity_type, +2 more

join-documentJoin documentA
DestructiveIdempotent
Inspect

Joins a document as a collaborator. If the current user is already an owner or collaborator on the document, they have already joined it: the tool returns their existing document user unchanged.

Use this tool when:

  • You need to make changes to a document, but do not have a 'document user' in the document yet.

  • You need to make changes to a document, but your existing 'document user' does not yet have permission to change it.

To join every document matching some conditions, find them with list-documents and filter_joined=false, which leaves out the documents you have already joined.

Inputs: document_uuid (required). Returns: name, email, party_uuid, _entity_type, +1 more

list-account-document-typesList account document typesA
Read-onlyIdempotent
Inspect

Get a list of the document types available in the account (fynk's system-provided types plus any custom types defined for the account).

Use this tool when:

  • You need a document type's UUID to filter list-documents by document type

  • You want to know which document types exist before referring to them by name in a response

  • You need to know what a document type covers, or how fynk's AI analyses recognise it (include=["details"])

Each document type is returned as its uuid and name by default. Request include=["details"] for its description and the prompt the AI analyses use to recognise it. Which metadata fields a document type has is reported from the other side, by list-account-metadata: each field there names the document types it is relevant for.

By default, only the types the account currently offers are returned. Removing one of fynk's system types deactivates it rather than deleting it: set filter_state to "deactivated" to list those types (e.g. when the user wants to reactivate one) or to "all" to list them alongside the rest.

Inputs: include, filter_state. Returns: document_types

list-account-metadataList account metadataA
Read-onlyIdempotent
Inspect

Get a list of the metadata fields available in the account to be associated with documents & templates.

Use this tool when:

  • You need to know which metadata names exist before referencing them in get-document-info / list-documents

  • You want to know the type, allowed values, or other configuration of an account's metadata fields

Inputs: no named parameters. Returns: metadata

list-account-partiesList account partiesA
Read-onlyIdempotent
Inspect

Get a list of the account parties saved on your account.

Account parties are the account's OWN entities — the company the user belongs to and its subsidiaries, group or parent companies. Phrasing like "our", "we", "us", "my company" or "our subsidiary" refers to an account party. These are the internal side of an agreement, as opposed to external parties (the counterparties on the other side), which you find with search-external-parties.

Use this tool when:

  • You need to know which pre-defined parties are available for use in documents or templates

  • You need to provide an account_party_uuid (use a uuid from this tool's response)

  • You need an account party's UUID to filter list-documents by account party (filter_account_parties) — e.g. to find documents involving "our" company or one of its subsidiaries

If you are looking for a named entity and it does not appear here, it may be an external party (counterparty) instead — try search-external-parties before concluding it does not exist.

Inputs: no named parameters. Returns: account_parties

list-account-playbooksList account playbooksA
Read-onlyIdempotent
Inspect

Get a list of the playbooks defined in the account.

Use this tool when:

  • You need a playbook's UUID to refer to it

  • You want to know which playbooks exist before referring to them by name in a response

Playbooks allow automating the review of documents based on predefined criteria.

Inputs: no named parameters. Returns: playbooks

list-account-tagsList account tagsA
Read-onlyIdempotent
Inspect

Get a list of the tags available in the account to be associated with documents & templates.

Use this tool when:

  • You need a tag's UUID to filter list-documents / list-templates by tag

  • You want to know which tags exist before referring to them by name in a response

Inputs: no named parameters. Returns: tags

list-account-team-membersList account team membersA
Read-onlyIdempotent
Inspect

List the members (account users) of a given team.

Use this tool when:

  • You need the account-user uuids of a team's members in order to add them to another team

  • The user asks who is in a team

  • You are merging or restructuring teams and need to know the current membership

Returns each member's uuid, first_name, last_name, and email. Pass the uuids to attach-account-users-to-team to add the same people to another team. Suspended users are not included.

Inputs: team_uuid (required). Returns: members

list-account-teamsList account teamsA
Read-onlyIdempotent
Inspect

Get a list of the teams available in the account.

Use this tool when:

  • You need a team's UUID to filter list-documents by team

  • You want to know which teams exist before referring to them by name in a response

Inputs: no named parameters. Returns: teams

list-account-usersList account usersA
Read-onlyIdempotent
Inspect

Get a list of the account users (the people who can log in to this fynk account).

Use this tool when:

  • You need an account user's uuid, e.g. to add them to a team via attach-account-users-to-team

  • The user refers to a colleague by name and you need to match them to an account user

  • The user asks who is part of the account

Returns each account user's uuid, first_name, last_name, and email. Only the account users the current user is allowed to see are returned: most users see everyone in the account, but 'limited manager's only see themselves and the members of their own teams. So this list is not necessarily the full set of people in the account - avoid presenting it as complete.

Inputs: no named parameters. Returns: account_users

list-documentsList documentsA
Read-onlyIdempotent
Inspect

Get a paginated list of the documents available to the current user.

Use this tool when:

  • You need to find a document_uuid to use as input for another tool

  • You need to know which documents the current user has access to

  • You want to search for a specific document

  • You are about to join several documents with join-document: pass filter_joined=false so that only the documents the current user has not joined yet are returned

By default, returns all active (non-archived) documents that the user has access to, with the most recently updated documents first. sort_by and sort_direction arguments can be used to control the sorting. Archived documents are included or targeted using the filter_archived_state parameter.

To keep responses small, each document is returned as a compact summary by default. Use the include parameter to request additional sections (parties, teams, tags, details, signing_settings, timestamps) when the user's question needs them, and prefer get-document-info when you need full information about a single document.

When you need particular metadata values for several documents, name those fields in include_metadata and they are returned for every document in the response. Do not call get-document-info once per document to collect the same fields — one list-documents call with include_metadata answers the whole question. When you already have the UUIDs of the documents you care about, pass them as filter_document_uuids and combine that with include or include_metadata to gather information about exactly those documents in a single call.

Each account has its own vocabulary — discover it before filtering

Accounts classify their documents using structures they define themselves: tags, document types, metadata fields (and their select options), teams and parties. The words a user puts in a question are usually the words their own account already uses as labels. "our customers", "suppliers", "key accounts", "renewals", "EMEA" and "high value" all sound like descriptions of content, but each is far more likely to be a tag, a document type, or a metadata field or option in this account.

Tags in particular are the account's own free-form classification labels, commonly covering relationship type (customer, supplier, partner, reseller), commercial significance (key account, strategic), lifecycle or region. A plain category noun in a question very often corresponds to a tag rather than to anything in the document text — so check list-account-tags whenever a question groups documents into a category that isn't available as a document type.

These lookups are cheap and return small, complete lists, so look rather than guess:

  • list-account-tags: the account's classification labels

  • list-account-document-types: e.g. NDA, MSA, Customer Agreement, DPA

  • list-account-metadata: field names, value types and select option values

  • list-account-teams / list-account-parties / search-external-parties: teams and contracting entities

Decompose the request, then map every part to a filter

A question usually contains several independent conditions. Handle each one separately:

  1. Split the request into its conditions. "what logo usage rights do we have for our largest customers?" is three: "logo usage rights", "largest", "customers".

  2. For each condition, ask what kind of structured thing it could be: a tag, a document type, a metadata field or option, a party (account or external), a document user, a team, a template, an automation, an import, a stage, or an origin.

  3. Look up the candidates with the companion tools above, then filter with the matching filter_ parameter.

  4. Only leave a condition to filter_query once you have confirmed that no structured filter covers it.

Finding a structured filter for one condition does NOT mean you are done — work through every condition before answering. In the example above, "largest" is a currency metadata field such as contract value (filter_metadata range, or sort_by that field), "customers" is very likely a tag or a document type, and "logo usage rights" may also be available from a metadata. Answering with just one of the three silently answers a different question than the user asked.

filter_query is a last resort

filter_query is only a fuzzy full-text search, so it gives inaccurate results for any specific structured attribute. This holds even when the request is phrased loosely or topically ("documents about product variant Alpha", "anything to do with Acme") — topical phrasing does NOT mean the term is free-text rather than a structured field or value. Prefer filter_query only for genuinely free-text conditions, or when the user is clearly searching by document name.

If filter_query returns no results, do not conclude that no matching documents exist before checking whether the search term corresponds to a tag, a document type, a metadata field or value, or a party. If it does, retry with the matching filter_ parameter instead.

Filters that take looked-up identifiers

The various 'filter_' parameters can be used to limit the list of returned documents. Several filters take identifiers or names you can look up with companion tools:

  • filter_account_parties: list-account-parties

  • filter_external_parties: search-external-parties

  • filter_automations: search-automations

  • filter_document_types: list-account-document-types

  • filter_document_users: search-document-users

  • filter_imports: search-imports

  • filter_metadata (field names, types and option values): list-account-metadata

  • filter_tags / filter_excluded_tags: list-account-tags

  • filter_teams: list-account-teams

  • filter_templates: list-templates

Parties vs. people, and account vs. external parties

Note that a document's parties (the contracting entities, frequently organizations) are distinct from its signatories and other document users (the individual people on the document). A named person commonly signs or is involved on behalf of a party without being a party themselves — so to find documents involving a specific person, use filter_document_users rather than a party filter.

Parties also come in two kinds. Account parties are the account's OWN entities — the company the user belongs to and its subsidiaries, group or parent companies; phrasing like "our", "we", "us", "my company" or "our subsidiary" points to an account party (look them up with list-account-parties and filter with filter_account_parties). External parties are the counterparties on the other side of an agreement (look them up with search-external-parties and filter with filter_external_parties). When it is not clear which kind a named entity is, or when one lookup returns nothing, check the other kind before concluding that no matching party or documents exist.

Active vs. archived documents

Only active — i.e. not archived — documents are returned by default, so a default call silently leaves archived documents out of the answer. Archiving is not deletion: an archived document still exists, and for questions about past, completed or superseded contracts it may be the document being asked about.

  • Set filter_archived_state=all whenever the answer is meant to cover a complete set or a count — "all our NDAs", "how many contracts do we have with Acme", "which suppliers have we signed with", "what is our total contract value". A default call answers such a question with a number that is too low, and nothing in the response reveals that.

  • Set filter_archived_state=archived only when the user asks specifically about archived documents.

  • If a call returns no results, retry with filter_archived_state=all before concluding that no matching documents exist — alongside the other checks above, i.e. whether a term you passed to filter_query is really a tag, document type, metadata field or party, and whether a named entity is the other kind of party.

When an answer draws on results that include archived documents, say which ones are archived. Request include=["timestamps"] to see this: archived_at is set on archived documents and null on active ones.

Inputs: page, include, sort_by, per_page, +24 more. Returns: total, max_page, documents, in_app_url, +1 more

list-templatesList templatesA
Read-onlyIdempotent
Inspect

Get a paginated list of the templates available to the current user.

Use this tool when:

  • You need to know which templates are available for creating documents from

  • You need to know which templates the user may edit in fynk. These will have a "url" field pointing to the edit page. No "url" means no permission to edit

By default, returns all active (non-archived) templates that the user has access to, with the most recently updated templates first. sort_by and sort_direction arguments can be used to control the sorting.

To keep responses small, each template is returned as a compact summary by default. Use the include parameter to request additional sections (parties, teams, tags, details, signing_settings, timestamps) when the user's question needs them, and prefer get-template-info when you need full information about a single template.

The various 'filter_' arguments can be used to limit the list of returned templates.

Active vs. archived templates

Only active — i.e. not archived — templates are returned by default. Archiving is not deletion: an archived template still exists and its past documents still reference it. Set filter_archived_state=all when the answer is meant to cover every template the account has, and retry with it if a call returns no results, before concluding that no matching template exists. Set filter_archived_state=archived only when the user asks specifically about archived templates. When picking a template to create a new document from, keep the default: an archived template is one the account has retired from use. A response only reveals which templates are archived if you request include=["timestamps"], which carries archived_at.

Inputs: page, include, sort_by, per_page, +10 more. Returns: total, max_page, templates, in_app_url, +1 more

move-document-to-done-stageMove document to done stageA
DestructiveIdempotent
Inspect

Moves a document to the done stage.

Use this tool when:

  • The document's current stage is one of: draft, approved_draft, review, approved_review

  • The document will NOT be signed through fynk (documents signed through fynk automatically move to done when fully signed)

This stage transition may be blocked by checkpoints on the document, or by unresolved preconditions (unresolved proposals, mandatory dynamic fields without values, active editor sessions or working copies, active signing phases, etc.). A refusal here reports just the first problem it runs into; call get-document-info first and read workflow_state.stage_transitions.done.blockers to see everything that is in the way at once.

Inputs: document_uuid (required). Returns: url, name, uuid, stage, +3 more

move-document-to-review-stageMove document to review stageA
DestructiveIdempotent
Inspect

Moves a document to the review stage.

Use this tool when:

  • The document's current stage is one of: draft, approved_draft, approved_review, signing or done

  • You want to share the document for review before moving to a later stage

This stage transition may be blocked by checkpoints on the document, or - when reverting a document that was not created from a template - by an account that only allows signing to start from a template. A refusal here reports just the first problem it runs into; call get-document-info first and read workflow_state.stage_transitions.review.blockers to see everything that is in the way at once.

If the document is in the process of being signed, or has been signed already, moving back to review will cancel the current signing process and invalidate any existing signatures.

Inputs: document_uuid (required). Returns: url, name, uuid, stage, +3 more

move-document-to-signing-stageMove document to signing stageA
DestructiveIdempotent
Inspect

Moves a document to the signing stage and invites signatories to sign.

Use this tool when:

  • The document's current stage is one of: draft, approved_draft, review, approved_review

  • You want to start the signing process

This stage transition may be blocked by checkpoints on the document, or by unresolved preconditions (missing signature blocks, unresolved proposals, mandatory dynamic fields without values, active editor sessions or working copies, etc.). A refusal here reports just the first problem it runs into; call get-document-info first and read workflow_state.stage_transitions.signing.blockers to see everything that is in the way at once.

If the document has a signature_type set, the signature_type argument - if provided - must match it; otherwise the document's signature_type will be used. If the document has no signature_type, the one provided here (or the account default) will be used.

A qes or aes_eid signature_type requires sequential_signing=true. aes_eid is only available when the account has enabled AES (eID) in its settings.

Inputs: document_uuid (required), message, signature_type, sequential_signing. Returns: url, name, uuid, stage, +3 more

replace-template-contentReplace template contentA
Destructive
Inspect

Replaces the ENTIRE content of a draft template from an HTML string in a single destructive write.

Use this tool ONLY when:

  • You are authoring the initial content of an empty, freshly created template (e.g. after create-template-from-scratch), or

  • The user has explicitly asked to discard the current content and rewrite the whole template.

This is the right tool for laying down a large body of content at once (e.g. a whole NDA). It writes the whole template body in one go; there is no way to edit an individual node.

Do NOT use this tool to edit a template that already has content. Overwriting throws the existing content away. If the template already has content, this tool refuses to run unless you pass replace_existing_content=true to confirm the destructive overwrite. Read the current content with get-template-html first, so anything worth keeping can be carried over into the new HTML.

Overwriting an existing body cannot be undone, so ask the user to confirm it before passing replace_existing_content=true.

Only allowed on unpublished (draft) templates. Once a template is published its content can no longer be changed with this tool.

Use the same data-* attribute conventions as get-template-html. UUIDs present on nodes (e.g. data-uuid on a paragraph or heading) are preserved; nodes without a UUID are assigned one automatically. The returned HTML reflects the stored result, with every addressable node carrying a data-uuid you can use in subsequent operations.

Each data-uuid identifies exactly one node, so no two nodes may carry the same one. When you copy an existing node to build a similar one, drop its data-uuid (a fresh one is assigned on write) - reusing it is rejected and nothing is written at all. A cross-reference is the one exception: it carries the uuid of the clause it points at rather than one of its own, so that uuid appears twice by design.

Numbering follows the source. A block the source numbers becomes an ordered list node; a block it does not keeps the tag it had - an stays an , prose stays a . A source that numbers nothing gets no list node at all: a contract written entirely as headings and paragraphs is a correct result.

Headings go three levels deep, to . An or deeper is rejected and nothing is written, so carry a hierarchy past three levels with nested list nodes rather than with a deeper heading.

The numbers themselves are ALWAYS computed by fynk, never typed into the text. HTML whose text starts with a clause marker ("1. Confidentiality", "2)", "(a)", "iv.", "§ 5") is rejected and nothing is written. Where the source numbers a clause, wrap it in an ordered list node instead:

<div data-list data-kind="ordered" data-numbering-type="continue"><p>Confidentiality.</p></div>
<div data-list data-kind="ordered" data-numbering-type="continue"><p>Term.</p></div>

Nest another such <div data-list> inside a clause to create sub-clauses (1.1, 1.2). fynk computes the numbers (1., 2., 1.1., …) automatically and returns them as read-only data-number attributes, which are ignored on input.

To cross-reference a clause, give that clause a data-uuid of your own - any uuid you generate, as long as it appears on exactly one node - and point the reference at it:

<div data-list data-kind="ordered" data-uuid="11111111-1111-4111-8111-111111111111">
    <p>Confidentiality.</p></div>
…
<p>As set out in <span data-section-ref data-uuid="11111111-1111-4111-8111-111111111111"></span>,
notices are written.</p>

which renders the clause's computed number ("1.") in place of the reference, following it wherever the clause moves rather than hardcoding it. Both go in the same call: there is no need to write the body first and read the uuids back. A cross-reference carrying no data-uuid points at nothing and is rejected, so drop the reference where you have no clause to name.

A list node decides how its own number is rendered, so any scheme a source document uses is computed rather than typed:

  • data-numbering-style: decimal (default), upper-roman, lower-roman, upper-alpha, lower-alpha.

  • data-delimiter-style: dot (default, "1."), parenthesis ("1)"), double-parenthesis ("(1)"), section-mark ("§ 1").

  • data-numbering-type: continue (default) carries on from the preceding list node, restart begins a new count at 1.

  • data-show-nested-order-representation: true (default) prefixes a nested clause with its parent's number ("10.1."), false numbers it on its own ("1.", "(a)"). Leave it on where the clause continues the parent's count (1.1., 1.2.), turn it off where the clause has a style of its own that reads wrong with the parent in front of it ("X.1.", "1.(a)").

A heading never carries a number, so a section the source numbers is a list node holding its clauses as nested list nodes - not an followed by clauses. One list node is one number: its own text is its first paragraph, so every clause of its own beside that paragraph needs its own nested :

<div data-list data-kind="ordered" data-numbering-style="upper-roman" data-numbering-type="restart">
    <p>Subject of the lease</p>
    <div data-list data-kind="ordered" data-numbering-type="restart" data-show-nested-order-representation="false"><p>The lessor lets the premises.</p></div>
    <div data-list data-kind="ordered" data-numbering-type="continue" data-show-nested-order-representation="false"><p>The premises comprise.</p></div>
</div>

which fynk numbers I., 1., 2., with the next such section continuing at II. Writing those two clauses as plain inside the section instead numbers the section I. and leaves both clauses with no number at all.

Where the source's section titles carry no number, the section stays an with its prose as plain beneath it. A list node placed beside such a heading numbers the prose rather than the section, so every section reads "1." and its title ends up written twice.

The opposite mistake numbers prose that has no number of its own. Text belonging to a clause stays a plain beside the list node's own first paragraph:

<div data-list data-kind="ordered" data-numbering-type="continue">
    <p>Purpose</p>
    <p>The parties wish to explore a potential business relationship. Each may disclose confidential
    information to the other in the course of it.</p>
</div>

which fynk numbers 1., with the prose under it unnumbered. Nesting that paragraph in a of its own numbers it as well, leaving the section with a clause that is only its own body text.

To insert a dynamic field (a fill-in placeholder), reference it inline by its ref_uuid:

<span data-dynamic-field data-ref-uuid="<dynamic field ref_uuid>"></span>

Discover the available fields and their ref_uuids with get-template-info (include=["dynamic_fields"]), or create a new one with create-template-dynamic-field (which returns its ref_uuid). Referencing a ref_uuid that does not belong to the template is rejected.

Signatures are always placed as a signature container holding one or more signature blocks - even a single block needs one:

<div data-signatures data-align="left"><span data-signature-block data-ref-uuid="<signature block ref_uuid>"></span><span data-signature-block data-ref-uuid="<another ref_uuid>"></span></div>

Each inside the container points at one signature block by its ref_uuid; data-align is optional on the container (left, center, right, or justify; default left). A block placed outside a container, as , is legacy: it is still accepted so existing content can be written back unchanged, but it is stored as a container holding that one block.

Discover signature blocks and their ref_uuids with get-template-info (include=["signature_blocks"]), or create one with create-template-signature-block (which returns its ref_uuid). Referencing a ref_uuid that does not belong to the template (in either form) is rejected.

To reference a contracting party, point at it by ref_uuid and choose what is rendered with data-format:

<span data-party data-ref-uuid="<party ref_uuid>" data-format="name"></span>       (the party's entity/company name)
<span data-party data-ref-uuid="<party ref_uuid>" data-format="reference"></span>  (the party's reference name)

Other formats are "address" and "address:inline". A data-format is required and must be one of name/reference/address/address:inline. Discover parties and their ref_uuids with get-template-info, or create one with create-template-party. A ref_uuid not on the template, or a missing/invalid data-format, is rejected.

Images (<img data-image>), dynamic tables (<div data-dynamic-table>) and signing vote blocks (<span data-signing-vote-block>) cannot be created here — there is no way to author one through this tool. They can only be preserved: copy the tag exactly as get-template-html returned it, including its data-uuid / data-ref-uuid / data-table-uuid, and the underlying image or table is kept. Omitting the tag removes it from the template.

A block's layout cannot be authored here either. The margins, indent and line height a block is laid out with are kept per block and matched by data-uuid on a block of the same kind, so a block you copy over with the data-uuid it came with keeps the spacing it had. A block you write fresh is laid out the way the editor lays out a new block, and so is one you rewrite as a different kind of block - a paragraph turned heading. A style stating a margin, an indent or a line height is ignored; the text formatting inside the block - bold, colour, font, size, highlight - is not.

A block's alignment is authored here, as data-text-align on the paragraph, heading or list node carrying it - left, center, right or justify:

<h1 data-text-align="center">Mutual Non-Disclosure Agreement</h1>

A text-align style is not read, and any other value of the attribute counts as stating no alignment: a block you write fresh is then aligned left, and one you copy over with the data-uuid it came with keeps the alignment it already had - state data-text-align="left" to align such a block left again.

When you are laying down content derived from a source document (e.g. a PDF), create the parties, dynamic fields and signature blocks first, so this single write can reference them. Weaving them in afterwards costs a second, destructive rewrite of the whole body.

The response carries a warnings list alongside the stored HTML: advisory notes on what the template is still missing to behave as a template rather than as a flat copy of its source text - dynamic fields or signature blocks that exist but are placed nowhere, a body naming its parties as fixed text. The write succeeded either way, but act on them before reporting the template as finished.

Only available for templates with a prosemirror_data content type.

Inputs: html (required), template_uuid (required), replace_existing_content. Returns: html, warnings

restore-documentRestore documentA
DestructiveIdempotent
Inspect

Restores an archived document, making it show up in the account's default document lists again.

Use this tool when:

  • An archived document should become actively used again

  • The user asks to restore or unarchive a document

The document must currently be archived. Archived documents do not appear in list-documents results by default: pass filter_archived_state: "archived" to the list-documents tool to find them.

Inputs: document_uuid (required). Returns: url, name, uuid, stage, +5 more

search-automationsSearch automationsA
Read-onlyIdempotent
Inspect

Search the account's automations by name.

Use this tool when:

  • You need an automation's UUID to filter list-documents by automation

  • You want to find automations matching a search term

Returns automations whose name matches the query, most recently created first. Results are capped, so narrow the query if you don't find what you're looking for.

Inputs: query (required), limit. Returns: automations

search-document-usersSearch document usersA
Read-onlyIdempotent
Inspect

Search the account's document users (individual people who have access to documents) by name or email.

Use this tool when:

  • You need a person's name to filter list-documents by document user

  • You want to find document users matching a search term

Searches first name, last name and email. A two-word query is matched as firstname + lastname. Results are capped and de-duplicated by name, so narrow the query if you don't find who you're looking for.

Inputs: query (required), limit. Returns: document_users

search-external-partiesSearch external partiesA
Read-onlyIdempotent
Inspect

Search the account's external parties (people and businesses that appear on documents) by name.

External parties are the counterparties on documents — the entities on the OTHER side of an agreement, which do not belong to the account. They are distinct from account parties, which are the account's own entities (the company the user belongs to and its subsidiaries / group companies). Phrasing like "our", "we", "us", "my company" or "our subsidiary" refers to an account party, not an external party — in that case use list-account-parties instead.

Use this tool when:

  • You need a party's name to filter list-documents by external party

  • You want to find parties matching a search term

Matches the party's name (entity_name). Results are capped and de-duplicated by name, so narrow the query if you don't find who you're looking for. If you are looking for a named entity and it does not appear here, it may be an account party (the account's own side) instead — try list-account-parties before concluding it does not exist.

Inputs: query (required), limit. Returns: external_parties

search-importsSearch importsA
Read-onlyIdempotent
Inspect

Search the account's imports by name.

Use this tool when:

  • You need an import's UUID to filter list-documents by import

  • You want to find imports matching a search term

Returns imports whose name matches the query, most recently created first. Results are capped, so narrow the query if you don't find what you're looking for.

Inputs: query (required), limit. Returns: imports

set-template-published-statePublish or unpublish templateA
DestructiveIdempotent
Inspect

Publishes a template, making it available to the whole account, or unpublishes it back to a draft.

Use this tool when:

  • A template is finished, the user has read it over and asks to publish it, release it or hand it to their colleagues

  • Documents are to be created from a template that is still a draft

  • The user asks to take a published template out of circulation

  • A published template's content has to be rewritten, which replace-template-content refuses until the template is a draft again

Publishing is what puts a template into service. list-templates shows a draft only to the users who manage templates, so until it is published nobody else can find it to create a document from. It also settles the body, which replace-template-content only writes while the template is a draft.

A template that was just authored is therefore left as a draft rather than published on the spot. Tell the user what was written, let them read it over, and publish once they say it is right. Confirm either direction with them: publishing offers the template to their colleagues, unpublishing takes it away from them.

Unpublishing changes nothing about the documents already created from the template. They keep the content they were created with; the template is simply no longer offered for new ones.

Inputs: published (required), template_uuid (required). Returns: url, name, uuid, locale, +3 more

update-account-document-typeUpdate account document typeA
DestructiveIdempotent
Inspect

Change a document type the account can see, whether it is one of the account's own types or one of fynk's system document types.

Use this tool when:

  • The user asks to rename a document type, or to change what it covers

  • AI analyses keep picking the wrong document type, or miss one, and its prompt needs sharpening

  • The user asks to change which metadata fields are relevant for documents of a type

  • The user asks to put one of fynk's document types back to how fynk provides it

  • The user asks to bring back one of fynk's document types that was removed from the account

document_type_uuid comes from list-account-document-types; request include=["details"] there to see a type's current description and prompt. Send only the arguments that should change; everything left out keeps its current value. Sending null for description or prompt clears it.

list-account-document-types marks fynk's own document types with provided_by_fynk, and those this account has customised with customised as well. A change to one of fynk's types applies to this account alone. The first change to one that is not customised yet replaces it, for this account, with a customised copy that has a uuid of its own, and moves the account's documents and templates onto it; use the uuid this tool returns from then on. That first change must include name, because the copy carries its name as written here in every language the account's users read fynk in, instead of fynk's translations. So send the name the user knows the type by, e.g. "Non-Disclosure Agreement", rather than a respelling of the listed name.

Send reset_to_fynk_default: true on its own for a customised type to drop the customisation, putting fynk's own name, description and prompt back and moving the documents and templates back onto it. The type's uuid changes back to fynk's, which this tool returns.

A type that list-account-document-types reports as deactivated (with filter_state "deactivated" or "all") is one of fynk's that was removed from the account. Send reactivate: true on its own to bring it back as fynk provides it; customise it afterwards with a further call.

prompt is what fynk's AI analyses read when deciding whether a document is of this type. Phrase it as a selection criterion, the way fynk's own types do: "Select this type if the document defines the terms under which a tenant rents property from a landlord, including rent amount, duration, deposit, and usage conditions."

relevant_metadata_uuids replaces the metadata fields specifically relevant for the type, which decides the fields fynk's AI analyses look for in documents of this type. Send every field that should remain: one left out is no longer extracted from the type's documents, though values already recorded stay. Fields relevant for every document type apply regardless and are unaffected. list-account-metadata reports the current state: each field there names the document types it is relevant for.

Inputs: document_type_uuid (required), name, prompt, reactivate, +3 more. Returns: name, uuid, prompt, customised, +3 more

update-account-metadataUpdate account metadataA
DestructiveIdempotent
Inspect

Change the definition of a metadata field the account can see, whether it is one of the account's own fields or a system_reference field provided by fynk.

Use this tool when:

  • The user asks to rename a metadata field, or to change what it holds

  • The user asks to start or stop having fynk's AI analyses fill a field in

  • The user asks to change which document types a field applies to

  • The user asks to put one of fynk's fields back to how fynk provides it

metadata_uuid comes from list-account-metadata. Send only the arguments that should change; everything left out keeps its current value. Sending null for description, prompt or keywords clears it.

A field's name and value_type are fixed at creation and this tool cannot change either. To rename a field for the people using it, change display_name - in Title Case, the way fynk's own fields are named ("Signing Date", "Contract Value").

fynk's own system_reference fields can be reconfigured per account: the change applies to this account alone and leaves the field as fynk defines it everywhere else, and putting an argument back to fynk's own value stops overriding it. fynk's other system field types (system, system_autofilled, system_computed) are maintained entirely by fynk and cannot be changed at all.

One of fynk's fields that an account has reconfigured reports the arguments it overrides as overridden_fields, from this tool and from list-account-metadata alike. Send reset_to_fynk_default: true on its own to drop all of them at once, leaving the account reading the field exactly as fynk provides it; there is no per-argument reset, so re-send whichever of them are still wanted afterwards.

select_values replaces the whole list of options, which are literally what a user picks from, so write them as presentable labels: "Net 30", not "net 30". They govern what can be chosen from now on and leave values already recorded on documents as they are, so prefer adding an option to renaming or removing one. Since the list is replaced wholesale, send every option that should remain: one left out is one taken away.

Taking away an option that documents already hold is refused until the user has confirmed it. Such a value stays on its document but can no longer be filtered for. The refusal names the options and how many documents and templates still use each - then repeat the call with confirmed_removing_options_in_use: true. Send that only in answer to such a refusal, never as a matter of course. reset_to_fynk_default is covered the same way, since putting fynk's own options back takes away any the account added to them.

Put the effect to the user in their own terms and ask before going ahead - "removing Net 90 would affect 3 documents that still use it, shall I go ahead?" - rather than quoting the refusal back at them.

prompt and keywords decide whether fynk's AI analyses fill this field in - a prompt puts the field into them, keywords only assist it and do nothing on their own. So set both together to have a field extracted, and clear prompt to take a field back out of the analyses and leave it to only be filled in by hand.

Inputs: metadata_uuid (required), prompt, keywords, description, +7 more. Returns: name, type, uuid, settings, +8 more

update-account-tagUpdate account tagA
DestructiveIdempotent
Inspect

Update an existing tag's name and/or color.

Use this tool when:

  • The user asks to rename a tag

  • The user asks to change a tag's color

tag_uuid is required. Send only the fields that should change.

Inputs: tag_uuid (required), name, color. Returns: name, uuid, color, _entity_type

update-account-teamUpdate account teamA
DestructiveIdempotent
Inspect

Update an existing team's name and/or icon.

Use this tool when:

  • The user asks to rename a team

  • The user asks to change a team's icon

team_uuid is required. Send only the fields that should change.

Inputs: team_uuid (required), icon, name. Returns: icon, name, uuid, _entity_type

update-documentUpdate documentA
DestructiveIdempotent
Inspect

Updates a document's name, locale, document type, signing settings and/or external signatory invitation message.

Use this tool when:

  • A document should be renamed

  • The document's content language (locale) or document type should change

  • The signature type or sequential signing setting should change before signing starts

  • The message included in the email inviting external signatories should be set or changed

All arguments except document_uuid are optional and only need to be sent if their value should change. signature_type and sequential_signing cannot be changed once signing has started, and signature_type cannot be changed if it was specified by the document's template. Use the list-account-document-types tool to discover valid document type UUIDs. This tool cannot change the document's stage (use the move-document-to-*-stage tools for that).

Inputs: document_uuid (required), name, locale, signature_type, +3 more. Returns: url, name, uuid, stage, +8 more

update-document-dynamic-fieldsUpdate document dynamic fieldsA
DestructiveIdempotent
Inspect

Update the value of one or more of a document's dynamic fields.

Use this tool when:

  • You want to fill in (or change) values for fields like text inputs, dates, numbers, or selects on a document

  • A user asks to set values that signing requires before it can begin (mandatory dynamic fields)

Each entry in dynamic_field_values identifies the field by its ref_uuid or name (use get-document-info with include=["dynamic_fields"] to discover them) — sending the wrong key will fail validation.

Take note of the field's type when constructing the value. These are the rules to use when constructing the value string:

  • number: the numeric value in a string, using '.' as the decimal separator -> "1234.56"

  • currency: concatenate the ISO currency code and the numeric value with a ';' -> "EUR;1000.10" (for one thousand Euro and ten cents)

  • currency_duration: same as currency, but append another ';' followed by either monthly or yearly -> "EUR;1000.10;monthly" / "USD;1000.10;yearly"

  • select: one of the options from the field's select_values list -> "red"

  • multi_select: an array of the selected values in the values field -> ["red", "blue"]

  • bool: either of the strings "true" (displayed to the user as "Yes") or "false" (displayed to the user as "No") -> "true" / "false"

  • duration: a PHP-compatible duration specification -> "P6D" (6 days), "P2W" (2 weeks), "PT12H" (12 hours)

  • date: the date in the format "YYYY-MM-DD" -> "2026-12-31"

  • email, text, textarea, or any type not listed above: a string -> "test@example.com"

To unset a dynamic field, send a null value.

Inputs: document_uuid (required), dynamic_field_values. Returns: dynamic_fields

update-document-metadata-valuesUpdate document metadata valuesA
DestructiveIdempotent
Inspect

Set or unset the value of one or more of a document's metadata.

Use this tool when:

  • You want to fill in (or change) a document's metadata values

  • You want to remove a value the document currently has for a metadata

Each entry in metadata_value_changes identifies the metadata by its metadata_uuid or name (use list-account-metadata, or get-document-info with include=["metadata_values"], to discover them) — sending an identifier that does not match any of the account's metadata will fail validation.

Each entry also has an operation:

  • set: create the metadata value (if the document does not have one yet) or update the existing value

  • unset: remove the document's value for the metadata (no value is required)

For a set, take note of the metadata's value_type when constructing the value. These are the rules to use when constructing the value string:

  • number: the numeric value in a string, using '.' as the decimal separator -> "1234.56"

  • currency: concatenate the ISO currency code and the numeric value with a ';' -> "EUR;1000.10" (for one thousand Euro and ten cents)

  • currency_duration: same as currency, but append another ';' followed by either monthly or yearly -> "EUR;1000.10;monthly" / "USD;1000.10;yearly"

  • select: one of the options from the metadata's select_values list -> "red"

  • multi_select: an array of the selected values in the values field -> ["red", "blue"]

  • bool: either of the strings "true" (displayed to the user as "Yes") or "false" (displayed to the user as "No") -> "true" / "false"

  • duration: a PHP-compatible duration specification -> "P6D" (6 days), "P2W" (2 weeks), "PT12H" (12 hours)

  • date: the date in the format "YYYY-MM-DD" -> "2026-12-31"

  • email, text, textarea, or any type not listed above: a string -> "test@example.com"

Some metadata cannot be changed this way (e.g. computed metadata, or metadata whose value is driven by a dynamic field) — attempting to do so will fail validation.

Inputs: document_uuid (required), metadata_value_changes. Returns: unset_metadata, set_metadata_values

update-document-partyUpdate document partyA
DestructiveIdempotent
Inspect

Edit the details of a party on a document.

Use this tool when:

  • A party's reference, entity type, entity name, address, or scope needs to change on an existing document

document_uuid and party_identifier (a ref_uuid, reference, or entity_name of a party on the document) are required to identify the party. All other arguments are optional and only need to be sent if their value should change. For parties linked to an account party, only party_reference can be changed — attempting to update other fields will fail.

Inputs: document_uuid (required), party_identifier (required), party_scope, party_address, +2 more. Returns: uuid, address, ref_uuid, reference, +3 more

update-document-signatoryUpdate document signatoryA
DestructiveIdempotent
Inspect

Edit the details of a document signatory.

Use this tool when:

  • A signatory's name, title, mobile phone, or party assignment needs to change before signing starts

  • You need to move an existing signatory to a different party on the document

document_uuid and signatory_email are required to identify the signatory. All other arguments are optional and only need to be sent if their value should change. For internal signatories (linked to an account user), signatory_first_name, signatory_last_name, and signatory_title cannot be changed — they come from the user's profile.

Inputs: document_uuid (required), signatory_email (required), signatory_title, signatory_last_name, +3 more. Returns: name, uuid, email, party_uuid, +3 more

update-document-tagsUpdate document tagsA
DestructiveIdempotent
Inspect

Adds tags to and/or removes tags from a document.

Use this tool when:

  • One or more tags should be added to a document

  • A tag should be removed from a document

  • A document's tag should be replaced with another (one remove and one add action)

Actions are applied on top of the document's current tags: tags not mentioned in tag_actions stay attached. Each tag may appear in at most one action per call. Adding an already-attached tag or removing a tag that is not attached has no effect. Use the list-account-tags tool to discover valid tag UUIDs, and the create-account-tag tool to create a new tag first if no suitable one exists.

Inputs: tag_actions (required), document_uuid (required). Returns: url, name, tags, uuid, +3 more

update-document-teamsUpdate document teamsA
DestructiveIdempotent
Inspect

Adds teams to and/or removes teams from a document.

Use this tool when:

  • A document should be assigned to one or more teams

  • A team assignment should be removed from a document

  • A document should be moved from one team to another (one remove and one add action)

Actions are applied on top of the document's current team assignments: teams not mentioned in team_actions keep their assignment. Each team may appear in at most one action per call. Adding an already-assigned team or removing a team that is not assigned has no effect. Use the list-account-teams tool to discover valid team UUIDs. Some accounts enforce team assignment, in which case the last remaining team cannot be removed.

Inputs: team_actions (required), document_uuid (required). Returns: url, name, uuid, stage, +3 more

update-template-dynamic-fieldUpdate template dynamic fieldA
DestructiveIdempotent
Inspect

Update an existing dynamic field on a template.

Use this tool when:

  • The user wants to change a dynamic field's name, scope, options, default value, or other properties

Only send the fields you want to change. A field's type cannot be changed after creation; to change the type, delete the field and create a new one.

select and multi_select fields still require non-empty select_values.

The default value is set via value (for non-multi_select fields) or values (for multi_select fields), formatted according to the field's type (see create-template-dynamic-field for the per-type format). Setting a default value clears any autofill configured on the field. Use get-template-info with include=["dynamic_fields"] to discover the dynamic fields on a template and their UUIDs and types.

Inputs: template_uuid (required), dynamic_field_uuid (required), name, scope, +5 more. Returns: name, type, uuid, scope, +8 more

update-template-partyUpdate template partyA
DestructiveIdempotent
Inspect

Update an existing party on a template.

Use this tool when:

  • The user wants to change a party's role label, entity details, or scope

  • The user wants to link an existing external party to a saved account party, or unlink it again

Only send the fields you want to change. reference is the party's role label on the template (e.g. "Employer").

Account party linkage:

  • Send account_party_uuid (from list-account-parties) to link the party to a saved account party. While linked, only reference may be changed; entity_name, address, and scope cannot be sent.

  • Send account_party_uuid as null to unlink the party, turning it back into an external party whose entity details and scope you can then set.

Use get-template-info to discover the parties on a template and their UUIDs.

Inputs: party_uuid (required), template_uuid (required), scope, address, +3 more. Returns: uuid, address, ref_uuid, reference, +3 more

update-template-signature-blockUpdate template signature blockA
DestructiveIdempotent
Inspect

Update the presentation of a signature block on a template.

Use this tool when:

  • The user wants to change how an existing signature block looks (its style or scale)

Only style and scale can be changed, and a field left out keeps its current value. The party a signature block belongs to cannot be reassigned; to move a signature block to a different party, delete it and create a new one. Use get-template-info with include=["signature_blocks"] to discover the signature blocks on a template and their UUIDs.

Inputs: template_uuid (required), signature_block_uuid (required), scale, style. Returns: uuid, scale, style, ref_uuid, +3 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Remote MCP server that lets AI assistants read tracked competitive intelligence — competitor news, reviews, website changes, social posts and ads — and act on it by managing projects, competitors, battle cards, reports and canvases. Every answer carries a source and a date, and write actions only publish when explicitly shared.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.
      16
      9 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
      MIT
    Try in Browser

    Glama MCP Gateway

    Add one secure layer between your agents and this server.

    Resources