# Obsidian MCP Actor (`litezero/obsidian-mcp-actor`) Actor

Bridge the web and your Obsidian vault! Scrapes articles, strips ads, downloads images locally, generates AI tags, and syncs perfectly formatted Markdown notes directly to your hard drive via the MCP protocol.

- **URL**: https://apify.com/litezero/obsidian-mcp-actor.md
- **Developed by:** [LiteZero](https://apify.com/litezero) (community)
- **Categories:** Automation, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 result extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Obsidian MCP Actor

The **Obsidian MCP Actor** bridges the gap between your local Obsidian knowledge base and the web. It uses Apify's powerful scraping capabilities (Crawlee) to fetch content from the internet, uses LLMs (OpenAI) to generate intelligent tags and summaries, downloads all media assets, and securely pushes the newly created notes directly into your local Obsidian vault via the Model Context Protocol (MCP).

***

### 🌟 Key Features

#### 1. **Automated Note Creation (Reader Mode)**

Scrapes any webpage and transforms its main content into clean, GitHub-Flavored Markdown. It uses Mozilla's `Readability.js` (the exact engine behind Firefox's Reader View) to instantly strip out all advertisements, navigation sidebars, cookie banners, and footers, leaving only the pure article text.

#### 2. **Media & Image Downloading (Local Resilience)**

No more broken image links! If enabled, the Actor will automatically detect all images in the scraped article, download them, and save them directly to an attachments folder inside your Obsidian Vault. The Markdown will then be rewritten to use native Obsidian embeds (e.g., `![[image.jpg]]`).

#### 3. **Intelligent Tagging & Summarization (Optional AI Extraction)**

Uses OpenAI to read the scraped content and generate metadata for you. By default, it generates a brief summary and relevant tags. You can easily pass a **Custom AI Prompt** to extract specialized information (e.g., "Extract all quotes", "List the top 5 companies mentioned", or "Format the output into a specific Obsidian YAML template").

#### 4. **High-Performance & Cost-Effective**

The headless browser is configured to actively block the loading of heavy CSS, fonts, and tracking scripts, drastically reducing execution time and saving your Apify compute credits.

#### 5. **Seamless Obsidian Integration**

Connects directly to your Obsidian vault's local MCP Server using Server-Sent Events (SSE). It creates the `.md` files directly on your local hard drive—no manual copying and pasting required.

***

### 🛠️ Architecture: How it works

Because Obsidian runs locally on your computer, the Apify Actor (running in the cloud) needs a secure way to talk to it.

1. **The MCP Server**: You install an MCP Server plugin in your Obsidian vault. This opens a local port (e.g., `http://127.0.0.1:3000`).
2. **The Secure Tunnel**: You use a tool like `ngrok` to expose that local port to the internet securely (e.g., `https://1a2b3c4d.ngrok.app`).
3. **The MCP Client**: The Apify Actor acts as the client. It connects to your `ngrok` URL.
4. **The Scraping Loop**:
   - The Actor visits a URL from your `startUrls` list.
   - It extracts and cleans the text via Readability.js.
   - It downloads all images and saves them to your vault via the MCP `write_file` tool.
   - It sends the final Markdown note to your vault using the MCP `create_note` or `write_file` tool.

***

### 🚀 Step-by-Step Setup Guide

#### Phase 1: Obsidian Setup

1. Open your Obsidian vault.
2. Install an MCP Server plugin (such as `obsidian-mcp` or `cyanheads/obsidian-mcp-server`) via the Community Plugins tab, or manually if it's in early development.
3. Enable the plugin. Take note of the port it runs on (usually `3000` or `3001`).

#### Phase 2: Exposing the Server (ngrok)

To allow Apify to reach your local computer, we need a tunnel.

1. Download and install [ngrok](https://ngrok.com/).
2. Run the following command in your terminal to expose your MCP server port:
   ```bash
   ngrok http 3000
   ```
3. Copy the secure HTTPS URL ngrok provides (e.g., `https://1a2b3c4d.ngrok.app`). **Keep this terminal window open** while you want the integration to work.

#### Phase 3: Apify Setup

1. Deploy this Actor to your Apify account.
2. In the Actor's Input configuration, configure the following:
   - **Start URLs**: Add the web pages you want to scrape.
   - **Obsidian MCP Server URL**: Paste your ngrok URL here, appending `/sse` (e.g., `https://1a2b3c4d.ngrok.app/sse`).
   - **Target Folder**: Where notes should be saved in your vault (e.g., `Research/Web`).

#### Phase 4: Optional Features Setup

- **Image Downloading**: Toggle `Download Images locally` and set your `Attachment Folder` (e.g., `Research/Attachments`).
- **AI Extraction**: Toggle `Enable AI Extraction` and paste your OpenAI API Key. You can leave the `Custom AI Prompt` blank for default summarization, or write your own specific instructions.

***

### ⚙️ Input Parameters Reference

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `startUrls` | Array | **Yes** | The list of URLs you want to scrape and turn into notes. |
| `obsidianMcpUrl` | String | **Yes** | The public URL of your Obsidian MCP Server (e.g., `https://xyz.ngrok.app/sse`). |
| `obsidianMcpApiKey` | String | No | If your MCP server requires an authorization token. |
| `targetFolder` | String | **Yes** | The folder in your Obsidian vault where notes will be saved. |
| `downloadImages` | Boolean | No | Check to download all images from the article directly to your vault. |
| `attachmentFolder` | String | No | The folder for downloaded images. Only used if `downloadImages` is true. |
| `aiExtraction` | Boolean | No | Toggle to enable LLM-based summaries and tags. |
| `aiPrompt` | String | No | Override the default extraction prompt to get exactly the data you want. |
| `openaiApiKey` | String | No | Required if AI extraction is enabled. |

***

### ⚠️ Troubleshooting & FAQs

**Q: The Actor fails immediately with a "Failed to connect" error.**

- Ensure your `ngrok` terminal is running.
- Ensure your Obsidian app is open and the MCP plugin is enabled.
- Check that the `obsidianMcpUrl` in the Apify input ends with `/sse` if your server uses Server-Sent Events.

**Q: Images are not downloading or rendering.**

- Ensure your `attachmentFolder` exists in Obsidian. Some MCP servers cannot create nested folders automatically.
- Check if your MCP server supports writing base64 binary files via the `write_file` tool. If the images appear as text files containing base64 strings in your vault, the server may require an update to support binary encoding.

**Q: AI Extraction isn't working.**

- Ensure your `openaiApiKey` is valid and has sufficient credits.
- If you used a custom prompt, ensure it explicitly asks for a JSON output with `summary` and `tags` keys, otherwise the parser may fail.

***

### 📝 Example Output Note

```markdown
---
title: "The Future of AI Agents"
source: https://example.com/future-ai-agents
date_scraped: 2025-10-22
tags: [artificialintelligence, agents, future]
---

## The Future of AI Agents

> **AI Summary**: This article discusses the evolution of AI agents and how they are transitioning from simple chat interfaces to autonomous systems that can interact with APIs and local environments.

### Content

Here is an image of the architecture:

![[img_7f8a9b2c.jpg]]

[Clean, reader-mode markdown representation of the article...]
```

# Actor input Schema

## `startUrls` (type: `array`):

URLs to scrape and import into Obsidian.

## `obsidianMcpUrl` (type: `string`):

The URL where your Obsidian MCP Server is exposed (e.g., via ngrok). Supports SSE/HTTP connections.

## `obsidianMcpApiKey` (type: `string`):

Optional API key or token for the MCP server.

## `targetFolder` (type: `string`):

The folder path inside Obsidian where notes should be created.

## `downloadImages` (type: `boolean`):

If enabled, downloads all images from the article and saves them to your vault.

## `attachmentFolder` (type: `string`):

The folder in your Obsidian vault where downloaded images should be saved (e.g., 'Research/Attachments'). Only used if 'Download Images' is enabled.

## `aiExtraction` (type: `boolean`):

If enabled, uses an LLM to generate tags, summaries, and wikilinks.

## `aiPrompt` (type: `string`):

Optional custom instructions for the AI on how to summarize or extract data from the article.

## `openaiApiKey` (type: `string`):

Required if AI Extraction is enabled.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "targetFolder": "Research/Scraped",
  "downloadImages": false,
  "attachmentFolder": "Research/Attachments",
  "aiExtraction": false
}
```

# Actor output Schema

## `resultsDataset` (type: `string`):

Click here to view the scraped notes dataset in the Apify Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://example.com"
        }
    ],
    "targetFolder": "Research/Scraped",
    "attachmentFolder": "Research/Attachments"
};

// Run the Actor and wait for it to finish
const run = await client.actor("litezero/obsidian-mcp-actor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://example.com" }],
    "targetFolder": "Research/Scraped",
    "attachmentFolder": "Research/Attachments",
}

# Run the Actor and wait for it to finish
run = client.actor("litezero/obsidian-mcp-actor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "targetFolder": "Research/Scraped",
  "attachmentFolder": "Research/Attachments"
}' |
apify call litezero/obsidian-mcp-actor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,litezero/obsidian-mcp-actor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/akdj3SmEYXnYJ8Pu9/builds/JSXZ1oVRIexxHnh21/openapi.json
