Skip to main content
Glama

get_document_download_link

Retrieve a download link for SignNow documents or document groups using the entity ID. Provides access to signed documents and related files for sharing or storage.

Instructions

Get download link for a document or document group

Note: If your client supports MCP Resources, prefer the resource version of this endpoint; this tool exists as a compatibility fallback for tool-only clients.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entity_idYesID of the document or document group
entity_typeNoType of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
linkYesDownload link for the document

Implementation Reference

  • MCP tool handler function for get_document_download_link, including registration via @mcp.tool decorator, input schema via Annotated Fields, and delegation to helper implementation.
    @mcp.tool(name="get_document_download_link", description="Get download link for a document or document group" + TOOL_FALLBACK_SUFFIX, tags=["document", "document_group", "download", "link"])
    def get_document_download_link(
        ctx: Context,
        entity_id: Annotated[str, Field(description="ID of the document or document group")],
        entity_type: Annotated[
            Literal["document", "document_group"] | None,
            Field(description="Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type."),
        ] = None,
    ) -> DocumentDownloadLinkResponse:
        """Get download link for a document or document group.
    
        For documents: Returns direct download link.
        For document groups: Merges all documents in the group and returns download link for the merged document.
    
        Args:
            entity_id: ID of the document or document group
            entity_type: Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.
    
        Returns:
            DocumentDownloadLinkResponse with download link
        """
        return _get_document_download_link_impl(ctx, entity_id, entity_type)
  • Core helper function implementing the download link logic: auto-detects entity type, handles document groups by merging documents if multiple, calls SignNow client API.
    def _get_document_download_link(entity_id: str, entity_type: Literal["document", "document_group"] | None, token: str, client: SignNowAPIClient) -> DocumentDownloadLinkResponse:
        """Private function to get download link for a document or document group.
    
        Args:
            entity_id: ID of the document or document group
            entity_type: Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.
            token: Access token for SignNow API
            client: SignNow API client instance
    
        Returns:
            DocumentDownloadLinkResponse with download link
        """
    
        # Determine entity type if not provided
        document_group = None  # Store document group if found during auto-detection
    
        if not entity_type:
            # Try to determine entity type by attempting to get document group first (higher priority)
            try:
                document_group = client.get_document_group(token, entity_id)
                entity_type = "document_group"
            except Exception:
                # If document group not found, try document
                try:
                    client.get_document(token, entity_id)
                    entity_type = "document"
                except Exception:
                    raise ValueError(f"Entity with ID {entity_id} not found as either document group or document") from None
    
        if entity_type == "document_group":
            # For document group, we need to merge all documents first
            # Get the document group if we don't have it yet
            if not document_group:
                document_group = client.get_document_group(token, entity_id)
    
            # Extract document IDs from the group
            document_ids = [doc.id for doc in document_group.documents]
    
            if not document_ids:
                raise ValueError(f"Document group {entity_id} contains no documents")
    
            # If only one document, just get its download link directly
            if len(document_ids) == 1:
                response = client.get_document_download_link(token, document_ids[0])
                return DocumentDownloadLinkResponse(link=response.link)
    
            # Merge all documents in the group
            merge_request = MergeDocumentsRequest(name=document_group.group_name, document_ids=document_ids, upload_document=True)
    
            merge_response = client.merge_documents(token, merge_request)
    
            # Get download link for the merged document
            response = client.get_document_download_link(token, merge_response.document_id)
            return DocumentDownloadLinkResponse(link=response.link)
        else:
            # For single document, just get its download link
            response = client.get_document_download_link(token, entity_id)
            return DocumentDownloadLinkResponse(link=response.link)
  • Pydantic model defining the output schema for the tool response, containing the download link.
    class DocumentDownloadLinkResponse(BaseModel):
        """Response model for document download link."""
    
        link: str = Field(..., description="Download link for the document")
  • Internal helper that obtains token and client, then delegates to the core download link helper.
    def _get_document_download_link_impl(ctx: Context, entity_id: str, entity_type: Literal["document", "document_group"] | None) -> DocumentDownloadLinkResponse:
        token, client = _get_token_and_client(token_provider)
    
        # Initialize client and use the imported function from document_download_link module
        return _get_document_download_link(entity_id, entity_type, token, client)
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. The description mentions it's a 'compatibility fallback' which hints at its role, but doesn't disclose critical behavioral traits: whether this requires authentication, rate limits, what format the download link takes, if links expire, or any side effects. For a tool that presumably generates access links, this is a significant gap in transparency.

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

Conciseness5/5

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

The description is appropriately sized and front-loaded: the first sentence states the core purpose, and the second (in a Note) provides crucial usage guidance. Every sentence earns its place with no wasted words, making it easy for an agent to parse quickly.

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

Completeness4/5

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

Given the tool's moderate complexity (2 parameters, one optional), 100% schema coverage, and the presence of an output schema (which means return values are documented elsewhere), the description is reasonably complete. It covers purpose and client-compatibility guidance well. However, the lack of behavioral details (like auth or link behavior) and no mention of error cases slightly limits completeness for a tool that generates access links.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already fully documents both parameters (entity_id and entity_type). The description doesn't add any parameter-specific semantics beyond what's in the schema—it doesn't explain the relationship between entity_id and entity_type, or provide examples. With high schema coverage, the baseline is 3 even without extra param info in the description.

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

Purpose4/5

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

The description clearly states the tool's purpose with a specific verb ('Get download link') and resource ('for a document or document group'). It distinguishes from siblings by focusing on download links rather than document retrieval, editing, or template operations. However, it doesn't explicitly differentiate from all siblings (e.g., 'get_document' is a close sibling for document access).

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

Usage Guidelines4/5

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

The description provides clear context about when to use this tool vs. alternatives: it explicitly states to prefer the MCP Resource version if available, positioning this as a 'compatibility fallback for tool-only clients.' This gives good guidance on tool selection based on client capabilities, though it doesn't specify when to use this vs. other document-access siblings like 'get_document'.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/signnow/sn-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server