# MCP Server for AI Agents: Discourse Forum Search & Threads (`mutualistic_housing/discourse-forum-mcp`) Actor

Standby MCP Server (/mcp) and batch Actor for AI agents to search public Discourse forums, list latest and top topics, and extract full discussion threads, categories and accepted answers as clean text. No proxy, no login.

- **URL**: https://apify.com/mutualistic_housing/discourse-forum-mcp.md
- **Developed by:** [Mutualistic Labs](https://apify.com/mutualistic_housing) (community)
- **Categories:** AI, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## MCP Server for AI Agents: Discourse Forum Search & Threads

An always-on **Model Context Protocol (MCP) server** and batch Actor that searches **public Discourse forums**, lists latest and top
topics, lists categories and extracts **full discussion threads as clean text** (fenced code blocks and links preserved, accepted
answers flagged). Built for AI agents (Claude Desktop, Cursor, Windsurf, OpenAI Agents, LangChain), support research, developer
relations and community monitoring.

No proxies, no browser, no logins, no cookies: only the public Discourse JSON endpoints (`search.json`, `latest.json`, `top.json`,
`t/{id}.json`, `categories.json`) are called.

### What you get

| `item_type` | Mode | What it is |
|---|---|---|
| `search_result` | `search` | One matching post joined with its topic (title, URL, excerpt, likes, views, replies, solved flag) |
| `topic_summary` | `latest`, `top` | One topic from the latest or top list |
| `thread` | `thread` | A full thread: topic metadata plus `posts` with clean `content_text` and the accepted answer |
| `category` | `categories` | One forum category with topic and post counts |

### Preset forums

Use the key or the domain in `forums`; any other public Discourse domain or `https://` URL works too (up to 10 forums per call).

| Key | Domain |
|---|---|
| `openai` | community.openai.com |
| `huggingface` | discuss.huggingface.co |
| `discourse` | meta.discourse.org |
| `python` | discuss.python.org |
| `rust` | users.rust-lang.org |
| `pytorch` | discuss.pytorch.org |
| `cloudflare` | community.cloudflare.com |
| `n8n` | community.n8n.io |
| `obsidian` | forum.obsidian.md |
| `julia` | discourse.julialang.org |
| `golang` | forum.golangbridge.org |
| `kubernetes` | discuss.kubernetes.io |
| `flyio` | community.fly.io |
| `render` | community.render.com |
| `homeassistant` | community.home-assistant.io |

### Input

| Field | Type | Default |
|---|---|---|
| `mode` | `search`, `latest`, `top`, `thread`, `categories` | `search` |
| `query` | string (required when `mode` is `search`, max 200 chars) | `mcp server` (applied by the Apify platform when the input omits it, so an empty `{}` input runs) |
| `forums` | string\[] (preset keys, domains or https URLs, 1 to 10) | `["discourse"]` |
| `topic_ids` | string\[] of ids or topic URLs (mode `thread`, max 50) | none |
| `period` | `daily`, `weekly`, `monthly`, `quarterly`, `yearly`, `all` | `weekly` |
| `include_thread_posts` | boolean (mode `search`) | `false` |
| `max_posts_per_thread` | integer 1 to 100 | `20` |
| `max_items` | integer 1 to 500 | `25` |
| `max_total_charge_usd` | number or null | no cap |

camelCase aliases (`topicIds`, `includeThreadPosts`, `maxPostsPerThread`, `maxItems`, `maxTotalChargeUsd`) are accepted.
Invalid input is rejected with `INVALID_INPUT_ZERO_CHARGE` before any network call or charge.

#### Batch input examples

Search two forums:

```json
{"mode": "search", "query": "mcp server", "forums": ["discourse", "openai"], "max_items": 25}
```

Search and attach thread text to each hit:

```json
{"mode": "search", "query": "function calling status:solved", "forums": ["openai"], "include_thread_posts": true, "max_posts_per_thread": 10}
```

Latest topics:

```json
{"mode": "latest", "forums": ["huggingface", "pytorch"], "max_items": 50}
```

Top topics of the month:

```json
{"mode": "top", "forums": ["python"], "period": "monthly", "max_items": 30}
```

Full threads (ids bind to the first forum, or use full URLs):

```json
{"mode": "thread", "forums": ["discourse"], "topic_ids": ["12345", "https://community.openai.com/t/some-topic/67890"], "max_posts_per_thread": 50}
```

Categories:

```json
{"mode": "categories", "forums": ["n8n", "obsidian"]}
```

### Output examples

`search_result`:

```json
{
  "item_type": "search_result", "forum_domain": "meta.discourse.org", "forum_url": "https://meta.discourse.org",
  "topic_id": 12345, "topic_title": "How to build an MCP server plugin", "topic_slug": "how-to-build-an-mcp-server-plugin",
  "topic_url": "https://meta.discourse.org/t/how-to-build-an-mcp-server-plugin/12345",
  "post_id": 98765, "post_number": 3, "post_url": "https://meta.discourse.org/t/how-to-build-an-mcp-server-plugin/12345/3",
  "author_username": "alice", "author_name": "Alice", "excerpt": "You can expose the JSON API as an MCP server...",
  "like_count": 4, "views": 820, "posts_count": 9, "reply_count": 7, "has_accepted_answer": true, "tags": ["plugin"],
  "category_id": 7, "created_at": "2026-01-10T09:00:00.000Z", "last_posted_at": "2026-01-12T10:30:00.000Z", "uid": "<sha256>"
}
```

`topic_summary` (`source` is `latest` or `top`, `period` is `null` for latest):

```json
{
  "item_type": "topic_summary", "forum_domain": "discuss.huggingface.co", "topic_id": 555, "topic_title": "Fine-tuning question",
  "topic_url": "https://discuss.huggingface.co/t/fine-tuning-question/555", "excerpt": "I am trying to...", "views": 120,
  "like_count": 2, "posts_count": 4, "reply_count": 3, "has_accepted_answer": false, "closed": false, "archived": false,
  "pinned": false, "tags": [], "category_id": 9, "last_poster_username": "bob", "source": "top", "period": "weekly", "uid": "<sha256>"
}
```

`thread` (`posts` has at most `max_posts_per_thread` entries):

````json
{
  "item_type": "thread", "forum_domain": "meta.discourse.org", "topic_id": 12345, "topic_title": "How to build an MCP server plugin",
  "has_accepted_answer": true, "accepted_answer_post_number": 3, "author_username": "alice", "posts_returned": 2,
  "posts": [
    {"post_id": 1, "post_number": 1, "author_username": "alice", "content_text": "How do I...\n```ruby\nputs 1\n```", "like_count": 1, "is_accepted_answer": false},
    {"post_id": 3, "post_number": 3, "author_username": "bob", "content_text": "Use the API (https://example.com/docs)", "like_count": 4, "is_accepted_answer": true}
  ],
  "uid": "<sha256>"
}
````

`category`:

```json
{
  "item_type": "category", "forum_domain": "community.n8n.io", "category_id": 12, "name": "Questions", "slug": "questions",
  "description_text": "Ask the community", "topic_count": 4100, "post_count": 21000, "color": "0088CC", "parent_category_id": null,
  "category_url": "https://community.n8n.io/c/questions/12", "uid": "<sha256>"
}
```

### Standby MCP usage

Standby URL: `https://mutualistic-housing--discourse-forum-mcp.apify.actor/mcp` (authenticate with your Apify API token).

```json
{
  "mcpServers": {
    "discourse-forums": {
      "url": "https://mutualistic-housing--discourse-forum-mcp.apify.actor/mcp",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}
```

Tools:

- **`search_forums`**: `query` (required), `forums`, `max_items`, `include_thread_posts`.
- **`get_latest_or_top_topics`**: `forums`, `mode` (`latest` or `top`), `period`, `max_items`.
- **`get_thread`**: `forum`, `topic_id` (id or URL), `max_posts`.
- **`list_forums_and_categories`**: `forum` optional; without it the preset forums are listed, with it that forum's categories.

```bash
curl -X POST "https://mutualistic-housing--discourse-forum-mcp.apify.actor/mcp" \
  -H "Authorization: Bearer <APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_forums","arguments":{"query":"mcp server","forums":["discourse","openai"],"max_items":10}}}'
```

`GET /` and `GET /health` return `{"status":"ok","actor":"discourse-forum-mcp",...}`.

### Security and limits

- **https only**: bare hostnames become `https://host`; `http://`, `file:` and other schemes are rejected.
- **SSRF protections**: credentials in URLs, non-443 ports, `..` path traversal, query strings and fragments are rejected; IP literals,
  `localhost`, `.local` and `.internal` names are blocked; DNS results that resolve to loopback, private, link-local, multicast or
  unspecified addresses are refused; redirects must stay on the same host over https.
- **Bounds**: at most 500 items per run, 10 forums per call, 100 posts per thread, a 120 s global deadline, a 15 s per-request
  timeout and a 2 MiB response size cap.
- **MCP server**: request bodies above 64 KiB return `413`, `POST /mcp` requires `Content-Type: application/json` (`415` otherwise)
  and at most 8 tool calls run concurrently (`503` when busy).
- Rate limits (`429`) and 5xx responses are retried with back-off; per-forum failures are reported in `errors` and never abort other forums.

### Pricing

Pay per event: **$0.001 per result-item** (`result-item`: one search result, topic summary, thread or category); the `actor-start`
event is free. `max_items` and `max_total_charge_usd` are hard caps enforced in code, so a run never charges more than you
configure. Invalid input and empty results are never charged.

### Related MCP Servers by Mutualistic Labs

| Actor | Covers | Store | Standby MCP URL |
|---|---|---|---|
| Multi-ATS Career Jobs Search MCP | Greenhouse, Lever, Ashby, SmartRecruiters, Workable | https://apify.com/mutualistic_housing/multi-ats-career-jobs-mcp | https://mutualistic-housing--multi-ats-career-jobs-mcp.apify.actor/mcp |
| Google Ads Transparency & Ad Spy MCP | SearchCreatives, SearchSuggestions, `content.js` ad-copy & video metadata | https://apify.com/mutualistic_housing/google-ads-transparency-mcp | https://mutualistic-housing--google-ads-transparency-mcp.apify.actor/mcp |
| Multi-Engine Keyword & Autocomplete MCP | Google, YouTube, Amazon, Bing, DuckDuckGo, Brave + `google:suggestrelevance` & search intent | https://apify.com/mutualistic_housing/keyword-autocomplete-mcp | https://mutualistic-housing--keyword-autocomplete-mcp.apify.actor/mcp |
| Discourse Forum Search & Threads MCP | community.openai.com, discuss.huggingface.co, meta.discourse.org + any public Discourse | https://apify.com/mutualistic_housing/discourse-forum-mcp | https://mutualistic-housing--discourse-forum-mcp.apify.actor/mcp |

# Actor input Schema

## `mode` (type: `string`):

search = full-text search (needs query); latest = newest topics; top = top topics for the period; thread = full threads for topic_ids; categories = category list of each forum.

## `query` (type: `string`):

Required when mode = search (up to 200 characters). Supports Discourse search syntax such as tags:mcp or status:solved. Ignored by the other modes.

## `forums` (type: `array`):

Preset keys (openai, huggingface, discourse, python, rust, pytorch, cloudflare, n8n, obsidian, julia, golang, kubernetes, flyio, render, homeassistant) or public Discourse domains/https URLs. 1 to 10 forums. Empty means discourse.

## `topic_ids` (type: `array`):

Mode thread only (1 to 50 entries): numeric topic ids (bound to the first forum) or full topic URLs such as https://meta.discourse.org/t/some-topic/12345.

## `period` (type: `string`):

Time window for mode top.

## `include_thread_posts` (type: `boolean`):

Mode search only: attach thread_posts (clean text) to search results for up to 25 distinct topics.

## `max_posts_per_thread` (type: `integer`):

Maximum posts returned per thread (1 to 100).

## `max_items` (type: `integer`):

Maximum number of result items to return (and be charged for), 1 to 500.

## `max_total_charge_usd` (type: `number`):

Hard spending cap for this run; results are truncated so the charge never exceeds it.

## Actor input object example

```json
{
  "mode": "search",
  "query": "mcp server",
  "forums": [
    "discourse",
    "openai"
  ],
  "period": "weekly",
  "include_thread_posts": false,
  "max_posts_per_thread": 20,
  "max_items": 25
}
```

# Actor output Schema

## `items` (type: `string`):

Dataset items: search_result, topic_summary, thread and category records.

# 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 = {
    "query": "mcp server",
    "forums": [
        "discourse",
        "openai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mutualistic_housing/discourse-forum-mcp").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 = {
    "query": "mcp server",
    "forums": [
        "discourse",
        "openai",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("mutualistic_housing/discourse-forum-mcp").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 '{
  "query": "mcp server",
  "forums": [
    "discourse",
    "openai"
  ]
}' |
apify call mutualistic_housing/discourse-forum-mcp --silent --output-dataset

```

## MCP server setup

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

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/i9DTCes36USSD0XOk/builds/cedylR5DsReMfwL8k/openapi.json
