API & MCP

Filestash exposes two ways to interact with your remote storages: a built in API and a MCP server. Those options make it possible to interact with a remote storage in a consistent manner whether it’s S3, SFTP, FTP, SMB, ....

MCP

The Model Context Protocol enables tool usage by an LLM. If you use claude code, you can set it up like this:

~/$ claude mcp add filestash npx mcp-remote https://demo.filestash.app/sse
Added stdio MCP server filestash with command: npx mcp-remote https://demo.filestash.app/sse to local config

Next time you open up claude, it will open up a browser window to the authentication page and you should see something like this: mcp screenshot

> /mcp
╭───────────────────────────────────────────────────────────╮
│ Manage MCP servers                                        │
│                                                           │
│ ❯ 1. filestash ✔ connected · Enter to view details        │
╰───────────────────────────────────────────────────────────╯
     Esc to exit

> can you list the files at the root of the remote storage?
● I'll help you list the files at the root of the remote
storage. Let me use the MCP filestash tool to do this.

filestash:ls (MCP)(path: "/")
⎿  [DIR] Pictures
    [DIR] Music
    [DIR] Videos
    … +2 lines (ctrl+r to expand)

● The root directory contains:
  - Pictures/ (directory)
  - Music/ (directory)
  - Videos/ (directory)
  - README.org (file)
  - Documents/ (directory)



API

To use the builtin API, you first need to generate an API key from the admin console:

For this demo we've set up the "foobar" API key and enabled some CORS rules to make this page interactive.

Then, create a shared link, here "shareID" which we will use when calling the remote storage API. There's an API endpoint for every possible file management operation you can think of:

If you want to copy paste the curl commands scattered in this page, you will need to do a bit of setup:

export INSTANCE=https://demo.filestash.app
export SHARE=shareID
export KEY=foobar
GET
/api/files/ls?path={path}&key={key}&share={shareID}
List files and folder under the specified path. The results key will show the content of a folder and the metadata key will show what you can and cannot do from there.
curl "$INSTANCE/api/files/ls?share=$SHARE&key=$KEY&path=/"
{
    "status": "ok",
    "results": [
        {
            "name": "README.org",
            "type": "file",
            "size": 281,
            "time": 1591432761000
        },
        {
            "name": "Documents",
            "type": "directory",
            "size": 0,
            "time": 1591432774000
        }
    ]
}
POST
/api/files/cat?path={path}&key={key}&share={shareID}
Upload a file at the specified path
curl "$INSTANCE/api/files/cat?share=$SHARE&key=$KEY&path=/input.txt" \
    -X POST --data @input.txt

      
GET
/api/files/cat?path={path}&key={key}&share={shareID}
Download the file located under the specified path. Plugins can further expand of what is possible here, eg: plg_image_ascii which can render images as ascii art

curl -X GET "$INSTANCE/api/files/cat?key=$KEY&share=$SHARE&path=/input.txt"

      
GET
/api/files/zip?path={path}&key={key}&share={shareID}
Create a Zip file from something
curl "$INSTANCE/api/files/zip?share=$SHARE&key=$KEY&path=/input.txt"

      
POST
/api/files/mkdir?path={path}&key={key}&share={shareID}
Create a new folder
curl -X POST "$INSTANCE/api/files/mkdir?key=$KEY&share=$SHARE&path=/tmp/"

      
POST
/api/files/touch?path={path}&key={key}&share={shareID}
Create an empty file
curl -X POST "$INSTANCE/api/files/touch?key=$KEY&share=$SHARE&path=/test.txt" 

      
POST
/api/files/mv?from={path}&to={path}&key={key}&share={shareID}
Rename a file / folder from the specified path to the specified destination
curl -X POST "$INSTANCE/api/files/mv?key=$KEY&share=$SHARE&from=/input.txt&to=/test/input.txt"

      
POST
/api/files/rm?path={path}&key={key}&share={shareID}
Remove the file/folder at the specified path
curl -X POST "$INSTANCE/api/files/rm?key=$KEY&share=$SHARE&path=/test/" 

      

If you want to create shared links programmatically, check this out