Skip to content
ajan.io

Docs menu

On this page

MCP File Outputs

Learn how MCP servers can expose files to ajan through resources. ajan turns MCP resource content with text or base64 data into downloadable file attachments.

The MCP specification defines resources as the standard way for MCP servers to expose files and other contextual data to clients. Resources are application-driven: the host application decides how users discover, select, read, preview, or attach them.

In ajan, MCP resources can become regular file attachments that users can preview, download, and pass to other tools.

MCP Resources for Files

How Resources Work

An MCP server exposes files as resources with stable URIs. A client can discover them through resources/list, then fetch their content through resources/read.

The important part for file output is the resources/read response. Resource contents can be text:

json
{
  "contents": [
    {
      "uri": "file:///reports/summary.md",
      "mimeType": "text/markdown",
      "text": "# Summary\n\nGenerated by my MCP server."
    }
  ]
}

Or binary data, encoded as base64 in blob:

json
{
  "contents": [
    {
      "uri": "file:///reports/report.pdf",
      "mimeType": "application/pdf",
      "blob": "<base64-encoded file bytes>"
    }
  ]
}

ajan reads these contents entries and stores them as action-style file outputs. The uri provides the filename, the mimeType tells ajan how to process the file, and either text or blob contains the file content.

Demo Resource Server

This minimal server exposes one Markdown file as an MCP resource:

typescript
server.registerResource(
  "summary",
  "file:///reports/summary.md",
  {
    title: "Generated Summary",
    description: "A Markdown summary generated by the MCP server",
    mimeType: "text/markdown",
  },
  async (uri) => ({
    contents: [
      {
        uri: uri.href,
        mimeType: "text/markdown",
        text: "# Summary\n\nThis file came from an MCP resource.",
      },
    ],
  }),
);

When ajan reads this resource, it attaches summary.md to the conversation.

Requirements

  • Return file data in contents.
  • Include mimeType; ajan needs it to process the file correctly.
  • Include a meaningful uri; the last path segment becomes the filename.
  • Use blob for binary files, base64-encoded without a data URI prefix.
  • Use text for plain text, Markdown, JSON, HTML, and other text-based files.

Example Resource Output

json
{
  "contents": [
    {
      "uri": "file:///example.txt",
      "mimeType": "text/plain",
      "text": "Hello world"
    }
  ]
}

ajan stores this as an attachment. The tool result keeps the original contents array and adds file access metadata under files:

json
{
  "contents": [
    {
      "uri": "file:///example.txt",
      "mimeType": "text/plain",
      "text": "Hello world"
    }
  ],
  "files": {
    "successful_files": [
      {
        "fileName": "example.txt",
        "mimeType": "text/plain",
        "status": "completed",
        "access_methods": {
          "document_search": false,
          "file_input_actions": true,
          "download_available": true
        }
      }
    ]
  }
}

The text or blob value stays in the tool result after ajan stores the file as an attachment, so the resource content counts toward the model's context window. For binary files, the base64 blob can take up a large share of the available context. Keep resource contents small so the model retains room for the rest of the conversation.

FAQ

Expose a file as a resource when the result is better handled as a downloadable artifact, such as a generated document, transformed file, report, export, or binary asset. ajan creates attachments from resources. Files inside regular MCP tool results do not become attachments.

Check that the MCP server exposes the file as a supported resource, returns the expected metadata, and uses a format ajan can turn into an attachment. Also confirm the resource read completed successfully.