v2ex WebMCP
Browser tool configuration for v2ex
Tools (8)
v2ex_hot()
获取 V2EX 最热主题
Parameters
No parameters
JavaScript Handler
(params) => {
const run = async function(args) {
const resp = await fetch('https://www.v2ex.com/api/topics/hot.json');
if (!resp.ok) return {error: 'HTTP ' + resp.status};
const topics = await resp.json();
return {count: topics.length, topics: topics.map(t => ({
id: t.id, title: t.title, content: (t.content || '').substring(0, 300),
node: t.node?.title, nodeSlug: t.node?.name,
author: t.member?.username, replies: t.replies,
created: t.created, url: t.url
}))};
};
return run(params || {});
}
v2ex_latest()
获取 V2EX 最新主题
Parameters
No parameters
JavaScript Handler
(params) => {
const run = async function(args) {
const resp = await fetch('https://www.v2ex.com/api/topics/latest.json');
if (!resp.ok) return {error: 'HTTP ' + resp.status};
const topics = await resp.json();
return {count: topics.length, topics: topics.map(t => ({
id: t.id, title: t.title, content: (t.content || '').substring(0, 300),
node: t.node?.title, nodeSlug: t.node?.name,
author: t.member?.username, replies: t.replies,
created: t.created, url: t.url
}))};
};
return run(params || {});
}
v2ex_member()
V2EX 用户资料
Parameters
JavaScript Handler
(params) => {
const args = Object.assign({}, params || {});
let data = null;
let __wbContextUrl = globalThis.location?.href || '';
let __wbContextDocument = globalThis.document || null;
const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);
const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');
const __wbGet = (value, path) => {
if (!path) return value;
return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);
};
const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');
const __wbResolve = (target, base) => {
if (target == null) return '';
const text = String(target);
try {
return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();
} catch (_error) {
return text;
}
};
const __wbFetch = async (target, options) => {
const url = __wbResolve(target, __wbBaseUrl());
const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} for ${url}`);
}
const text = await resp.text();
try {
return { url, text, data: JSON.parse(text) };
} catch (_error) {
return { url, text, data: text };
}
};
return (async () => {
{
const __wbResp = await __wbFetch("https://www.v2ex.com/api/members/show.json");
data = __wbResp.data;
}
{
const source = Array.isArray(data) ? data : (data == null ? [] : [data]);
data = source.map((item, index) => ({
"username": item.username,
"tagline": item.tagline,
"website": item.website,
"github": item.github,
"twitter": item.twitter,
"location": item.location,
}));
}
return data;
})();
}
v2ex_node()
V2EX 节点话题列表
Parameters
JavaScript Handler
(params) => {
const args = Object.assign({"limit": 10}, params || {});
let data = null;
let __wbContextUrl = globalThis.location?.href || '';
let __wbContextDocument = globalThis.document || null;
const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);
const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');
const __wbGet = (value, path) => {
if (!path) return value;
return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);
};
const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');
const __wbResolve = (target, base) => {
if (target == null) return '';
const text = String(target);
try {
return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();
} catch (_error) {
return text;
}
};
const __wbFetch = async (target, options) => {
const url = __wbResolve(target, __wbBaseUrl());
const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} for ${url}`);
}
const text = await resp.text();
try {
return { url, text, data: JSON.parse(text) };
} catch (_error) {
return { url, text, data: text };
}
};
return (async () => {
{
const __wbResp = await __wbFetch("https://www.v2ex.com/api/topics/show.json");
data = __wbResp.data;
}
{
const source = Array.isArray(data) ? data : (data == null ? [] : [data]);
data = source.map((item, index) => ({
"rank": index + 1,
"title": item.title,
"author": item.member.username,
"replies": item.replies,
"url": item.url,
}));
}
if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);
return data;
})();
}
v2ex_nodes()
V2EX 所有节点列表
Parameters
JavaScript Handler
(params) => {
const args = Object.assign({"limit": 30}, params || {});
let data = null;
let __wbContextUrl = globalThis.location?.href || '';
let __wbContextDocument = globalThis.document || null;
const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);
const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');
const __wbGet = (value, path) => {
if (!path) return value;
return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);
};
const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');
const __wbResolve = (target, base) => {
if (target == null) return '';
const text = String(target);
try {
return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();
} catch (_error) {
return text;
}
};
const __wbFetch = async (target, options) => {
const url = __wbResolve(target, __wbBaseUrl());
const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} for ${url}`);
}
const text = await resp.text();
try {
return { url, text, data: JSON.parse(text) };
} catch (_error) {
return { url, text, data: text };
}
};
return (async () => {
{
const __wbResp = await __wbFetch("https://www.v2ex.com/api/nodes/all.json");
data = __wbResp.data;
}
{
const source = Array.isArray(data) ? [...data] : (data == null ? [] : [data]);
const by = "topics";
const desc = true;
source.sort((left, right) => {
const a = __wbGet(left, by);
const b = __wbGet(right, by);
if (a === b) return 0;
if (a == null) return desc ? 1 : -1;
if (b == null) return desc ? -1 : 1;
return desc ? (a < b ? 1 : -1) : (a > b ? 1 : -1);
});
data = source;
}
{
const source = Array.isArray(data) ? data : (data == null ? [] : [data]);
data = source.map((item, index) => ({
"rank": index + 1,
"name": item.name,
"title": item.title,
"topics": item.topics,
"stars": item.stars,
}));
}
if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);
return data;
})();
}
v2ex_replies()
V2EX 主题回复列表
Parameters
JavaScript Handler
(params) => {
const args = Object.assign({"limit": 20}, params || {});
let data = null;
let __wbContextUrl = globalThis.location?.href || '';
let __wbContextDocument = globalThis.document || null;
const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);
const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');
const __wbGet = (value, path) => {
if (!path) return value;
return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);
};
const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');
const __wbResolve = (target, base) => {
if (target == null) return '';
const text = String(target);
try {
return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();
} catch (_error) {
return text;
}
};
const __wbFetch = async (target, options) => {
const url = __wbResolve(target, __wbBaseUrl());
const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} for ${url}`);
}
const text = await resp.text();
try {
return { url, text, data: JSON.parse(text) };
} catch (_error) {
return { url, text, data: text };
}
};
return (async () => {
{
const __wbResp = await __wbFetch("https://www.v2ex.com/api/replies/show.json");
data = __wbResp.data;
}
{
const source = Array.isArray(data) ? data : (data == null ? [] : [data]);
data = source.map((item, index) => ({
"floor": index + 1,
"author": item.member.username,
"content": item.content,
}));
}
if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);
return data;
})();
}
v2ex_topic()
获取 V2EX 主题详情和回复
Parameters
JavaScript Handler
(params) => {
const run = async function(args) {
if (!args.id) return {error: 'Missing argument: id', hint: 'Provide a topic ID'};
const [topicResp, repliesResp] = await Promise.all([
fetch('https://www.v2ex.com/api/topics/show.json?id=' + args.id),
fetch('https://www.v2ex.com/api/replies/show.json?topic_id=' + args.id)
]);
if (!topicResp.ok) return {error: 'HTTP ' + topicResp.status};
const topics = await topicResp.json();
const replies = repliesResp.ok ? await repliesResp.json() : [];
const t = topics[0];
if (!t) return {error: 'Topic not found'};
return {
id: t.id, title: t.title, content: t.content,
node: t.node?.title, author: t.member?.username,
replies: t.replies, created: t.created, url: t.url,
comments: replies.map(r => ({
author: r.member?.username, content: r.content, created: r.created
}))
};
};
return run(params || {});
}
v2ex_user()
V2EX 用户发帖列表
Parameters
JavaScript Handler
(params) => {
const args = Object.assign({"limit": 10}, params || {});
let data = null;
let __wbContextUrl = globalThis.location?.href || '';
let __wbContextDocument = globalThis.document || null;
const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);
const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');
const __wbGet = (value, path) => {
if (!path) return value;
return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);
};
const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');
const __wbResolve = (target, base) => {
if (target == null) return '';
const text = String(target);
try {
return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();
} catch (_error) {
return text;
}
};
const __wbFetch = async (target, options) => {
const url = __wbResolve(target, __wbBaseUrl());
const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));
if (!resp.ok) {
throw new Error(`HTTP ${resp.status} for ${url}`);
}
const text = await resp.text();
try {
return { url, text, data: JSON.parse(text) };
} catch (_error) {
return { url, text, data: text };
}
};
return (async () => {
{
const __wbResp = await __wbFetch("https://www.v2ex.com/api/topics/show.json");
data = __wbResp.data;
}
{
const source = Array.isArray(data) ? data : (data == null ? [] : [data]);
data = source.map((item, index) => ({
"rank": index + 1,
"title": item.title,
"node": item.node.title,
"replies": item.replies,
"url": item.url,
}));
}
if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);
return data;
})();
}
🔌 Chrome MCP Server Extension
Use these tools with Claude, ChatGPT, and other AI assistants.
How to Use WebMCP
WebMCP tools are designed for browser extensions or automation frameworks. The browser extension matches the current URL against the pattern and executes the JavaScript handler when the tool is invoked.
API Endpoint:
GET /api/webmcp/match?url=https://www.v2ex.com/...