Skip to main content
Glama

Lovie Company Formation

Import SAFE

cap_table_import_safe
Destructive

Imports a SAFE from an uploaded SAFE PDF and stores the document in S3. USE THIS (not RecordCapTableInvestment) whenever the user provides or uploads a SAFE PDF file. Flow: (1) call GetOcrUploadUrl with kind=SAFE and mime_type=application/pdf to get a presigned PUT URL + source_s3_uri, (2) upload the PDF bytes to that PUT URL, (3) call ImportSAFE with that source_s3_uri. This runs OCR to extract the terms; pass valuation_cap / investment_amount / discount_rate only to CORRECT a value the user says the OCR misread, and leave them empty to keep what the document says. Call ExtractSafeTerms first and get the user's confirmation before importing. effective_date is required — never import a SAFE without a date. If the company named on the document differs from this company, say both names and get the user's confirmation before importing. It copies the PDF to the canonical cap-table SAFE location, links it to a SAFE agreement, resolves the investor by name (matching an existing stakeholder or creating a new one), and papers that investor's existing SAFE holding (the one carrying the document's amount, else their only unfunded one) rather than creating a second; only with none to paper does it create the security. Pass security_id to name the exact holding to paper (the web investor card does). An unsent generated SAFE draft that the import replaces is voided. With security_id naming the holding, the import is refused with FAILED_PRECONDITION when that investor already has a SAFE signed or out for signature (the user must void that envelope first) or when a wired holding's amount differs from the document's; a typed investment_amount does not unlock a wired holding. A document_id whose hub row is itself out for signature is refused with FAILED_PRECONDITION even without security_id, as is one already filed for another record (including a second submit of the same document). WITHOUT security_id, an investor whose SAFE is already signed or out for signature gets an additional SAFE holding beside it rather than a refusal — tell the user a second SAFE was recorded for that investor. Either way, the import is refused when the investor's SAFE signing state cannot be confirmed: when the document hub is unreachable tell the user to try again shortly, and when that SAFE is not filed in documents tell them support has to file it first. Pass post_money=true only when the user says the SAFE is post-money and the extraction did not; false leaves the document's own answer. A preview whose investor_name is empty found no investor named on the document: ask the user who the investor is and pass new_stakeholder_name on the import. The security is marked signed only if the document is actually signed; an unsigned SAFE PDF is still stored and left committed. Whenever the user has the PDF — including when they attached it to this conversation — upload it and pass source_s3_uri so the document itself is stored; a SAFE created from typed terms alone has nothing on record proving its date or signature, and the cap table flags it as missing its document. Use RecordCapTableInvestment only for a SAFE the user genuinely has no document for. The response carries the cap table before this call, what it added, and the cap table after — report an import in exactly that order (current table, new additions, final table) and take the totals from the response rather than reading the cap table again. For several SAFEs at once, list every one you are about to add and get a yes before the first call, not after the last.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
previewNo
roundIdNoUUID value wrapper.
companyIdYesUUID value wrapper.
postMoneyNo
documentIdNoUUID value wrapper.
securityIdNoUUID value wrapper.
sourceS3UriNo
discountRateNo
valuationCapNo
effectiveDateNo
stakeholderIdNoUUID value wrapper.
consentToAiReadNo
investmentAmountNo
unsignedDocumentNo
newStakeholderNameNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
changeNo
statusNo
createdNo
previewNo
securityIdNo
agreementIdNo
stakeholderIdNo
consentVersionNo
consentBodyMarkdownNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / securityId
      Added value: +{
      +  "description": "UUID value wrapper.",
      +  "properties": {
      +    "value": {
      +      "format": "uuid",
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  2. Changed19 schema fields changed
    • addedInput schema / properties / unsignedDocument
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / agreementId / anyOf
      Added value: +[
      +  {
      +    "description": "UUID value wrapper.",
      +    "properties": {
      +      "value": {
      +        "format": "uuid",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / agreementId / description
      Removed value: -"UUID value wrapper."
    • removedOutput schema / properties / agreementId / properties
      Removed value: -{
      -  "value": {
      -    "format": "uuid",
      -    "type": "string"
      -  }
      -}
    • removedOutput schema / properties / agreementId / type
      Removed value: -"object"
    • addedOutput schema / properties / change / anyOf
      Added value: +[
      +  {
      +    "properties": {
      +      "added": {
      +        "items": {
      +          "properties": {
      +            "capitalCommitted": {
      +              "type": "string"
      +            },
      +            "discountRate": {
      +              "type": "string"
      +            },
      +            "instrumentType": {
      +              "type": "string"
      +            },
      +            "stakeholderName": {
      +              "type": "string"
      +            },
      +            "valuationCap": {
      +              "type": "string"
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "after": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "fullyDilutedShares": {
      +                "type": "string"
      +              },
      +              "stakeholderCount": {
      +                "type": "integer"
      +              },
      +              "totalCommitted": {
      +                "type": "string"
      +              },
      +              "totalInvested": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "before": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "fullyDilutedShares": {
      +                "type": "string"
      +              },
      +              "stakeholderCount": {
      +                "type": "integer"
      +              },
      +              "totalCommitted": {
      +                "type": "string"
      +              },
      +              "totalInvested": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / change / properties
      Removed value: -{
      -  "added": {
      -    "items": {
      -      "properties": {
      -        "capitalCommitted": {
      -          "type": "string"
      -        },
      -        "discountRate": {
      -          "type": "string"
      -        },
      -        "instrumentType": {
      -          "type": "string"
      -        },
      -        "stakeholderName": {
      -          "type": "string"
      -        },
      -        "valuationCap": {
      -          "type": "string"
      -        }
      -      },
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  "after": {
      -    "properties": {
      -      "fullyDilutedShares": {
      -        "type": "string"
      -      },
      -      "stakeholderCount": {
      -        "type": "integer"
      -      },
      -      "totalCommitted": {
      -        "type": "string"
      -      },
      -      "totalInvested": {
      -        "type": "string"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  "before": {
      -    "properties": {
      -      "fullyDilutedShares": {
      -        "type": "string"
      -      },
      -      "stakeholderCount": {
      -        "type": "integer"
      -      },
      -      "totalCommitted": {
      -        "type": "string"
      -      },
      -      "totalInvested": {
      -        "type": "string"
      -      }
      -    },
      -    "type": "object"
      -  }
      -}
    • removedOutput schema / properties / change / type
      Removed value: -"object"
    • addedOutput schema / properties / preview / anyOf
      Added value: +[
      +  {
      +    "properties": {
      +      "discountRate": {
      +        "type": "string"
      +      },
      +      "effectiveDate": {
      +        "type": "string"
      +      },
      +      "investmentAmount": {
      +        "type": "string"
      +      },
      +      "investorName": {
      +        "type": "string"
      +      },
      +      "isSigned": {
      +        "type": "boolean"
      +      },
      +      "matchedStakeholderId": {
      +        "anyOf": [
      +          {
      +            "description": "UUID value wrapper.",
      +            "properties": {
      +              "value": {
      +                "format": "uuid",
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "postMoney": {
      +        "type": "boolean"
      +      },
      +      "termsSource": {
      +        "type": "string"
      +      },
      +      "valuationCap": {
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / preview / properties
      Removed value: -{
      -  "discountRate": {
      -    "type": "string"
      -  },
      -  "effectiveDate": {
      -    "type": "string"
      -  },
      -  "investmentAmount": {
      -    "type": "string"
      -  },
      -  "investorName": {
      -    "type": "string"
      -  },
      -  "isSigned": {
      -    "type": "boolean"
      -  },
      -  "matchedStakeholderId": {
      -    "description": "UUID value wrapper.",
      -    "properties": {
      -      "value": {
      -        "format": "uuid",
      -        "type": "string"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  "postMoney": {
      -    "type": "boolean"
      -  },
      -  "termsSource": {
      -    "type": "string"
      -  },
      -  "valuationCap": {
      -    "type": "string"
      -  }
      -}
    • removedOutput schema / properties / preview / type
      Removed value: -"object"
    • addedOutput schema / properties / securityId / anyOf
      Added value: +[
      +  {
      +    "description": "UUID value wrapper.",
      +    "properties": {
      +      "value": {
      +        "format": "uuid",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / securityId / description
      Removed value: -"UUID value wrapper."
    • removedOutput schema / properties / securityId / properties
      Removed value: -{
      -  "value": {
      -    "format": "uuid",
      -    "type": "string"
      -  }
      -}
    • removedOutput schema / properties / securityId / type
      Removed value: -"object"
    • addedOutput schema / properties / stakeholderId / anyOf
      Added value: +[
      +  {
      +    "description": "UUID value wrapper.",
      +    "properties": {
      +      "value": {
      +        "format": "uuid",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / stakeholderId / description
      Removed value: -"UUID value wrapper."
    • removedOutput schema / properties / stakeholderId / properties
      Removed value: -{
      -  "value": {
      -    "format": "uuid",
      -    "type": "string"
      -  }
      -}
    • removedOutput schema / properties / stakeholderId / type
      Removed value: -"object"
  3. Changed3 schema fields changed
    • addedInput schema / properties / documentId
      Added value: +{
      +  "description": "UUID value wrapper.",
      +  "properties": {
      +    "value": {
      +      "format": "uuid",
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / preview
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / preview
      Added value: +{
      +  "properties": {
      +    "discountRate": {
      +      "type": "string"
      +    },
      +    "effectiveDate": {
      +      "type": "string"
      +    },
      +    "investmentAmount": {
      +      "type": "string"
      +    },
      +    "investorName": {
      +      "type": "string"
      +    },
      +    "isSigned": {
      +      "type": "boolean"
      +    },
      +    "matchedStakeholderId": {
      +      "description": "UUID value wrapper.",
      +      "properties": {
      +        "value": {
      +          "format": "uuid",
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "postMoney": {
      +      "type": "boolean"
      +    },
      +    "termsSource": {
      +      "type": "string"
      +    },
      +    "valuationCap": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply openWorldHint=false and destructiveHint=true; the description adds the far richer behavior the agent actually needs: the 3-step OCR upload flow, what the tool creates (agreement, investor resolution, holding papering vs. new security), which conditions return FAILED_PRECONDITION and how to remediate, the voiding of an unsent draft, and the fallback behavior when security_id is absent. This goes well beyond what any structured field declares and is consistent with destructiveHint=true (it modifies and voids records).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a dense wall of text rather than a front-loaded summary — a very long single block covering flow, correction semantics, refusal conditions, and reporting order with no paragraph breaks or lists. Every sentence carries information, but the agent pays a high reading cost to extract it, and the refusal/precondition clauses are buried mid-paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter mutation tool with a rich output schema, the description covers the full lifecycle (upload → import → report), all refusal states and their remedies, the investor-resolution and dedup logic, and how to interpret the response ('report an import in exactly that order... take the totals from the response'). Nothing material an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (mostly UUID wrappers), so the description must compensate and largely does: it explains that source_s3_uri IS the uploaded document, that valuation_cap/investment_amount/discount_rate are correction-only overrides, that post_money=true vs false follows the document, that effective_date is mandatory, that new_stakeholder_name is used when the preview's investor_name is empty, and what security_id targets. Some parameters (preview, consentToAiRead, unsignedDocument, stakeholderId, roundId, documentId) remain undocumented in the description, keeping it just short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Imports a SAFE from an uploaded SAFE PDF') and immediately routes against the sibling by name ('USE THIS (not RecordCapTableInvestment) whenever the user provides or uploads a SAFE PDF file'). An agent can distinguish this from cap_table_record_cap_table_investment and cap_table_import_rsa without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use (user has/attaches a SAFE PDF), when-not-to-use and the alternative (RecordCapTableInvestment only for a SAFE with no document), mandatory prerequisites (ExtractSafeTerms first, user confirmation, effective_date required), and a multi-item batching protocol ('get a yes before the first call, not after the last'). This is about as complete as usage guidance gets.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.