{"url_pattern":"^https?://dev\\.to(/.*)?$","site_name":"devto","allowed_domains":["dev.to","example.com"],"tools":[{"name":"devto_search","description":"Search Dev.to articles by keyword","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Search keyword or phrase"},"count":{"type":"number","description":"Number of results (max 100)","default":10}},"required":["query"]},"handler":"(params) => {\n  const run = async function(args) {\n\n      const query = args.query;\n      if (!query) return { error: 'query is required' };\n      const count = Math.min(args.count || 10, 100);\n\n      const url = 'https://dev.to/search/feed_content?per_page=' + count +\n        '&page=0&search_fields=' + encodeURIComponent(query) + '&class_name=Article';\n\n      const resp = await fetch(url);\n      if (!resp.ok) return { error: 'HTTP ' + resp.status };\n\n      const data = await resp.json();\n      const articles = data.result || [];\n\n      return {\n        query: query,\n        count: articles.length,\n        articles: articles.map(a => ({\n          title: a.title,\n          url: a.path ? ('https://dev.to' + a.path) : null,\n          description: (a.cloudinary_video_url ? '[video] ' : '') +\n            (a.body_text || '').substring(0, 300),\n          author: a.user ? a.user.name : null,\n          username: a.user ? a.user.username : null,\n          published_at: a.published_at_int ? new Date(a.published_at_int * 1000).toISOString() : null,\n          reactions: a.public_reactions_count || 0,\n          comments: a.comments_count || 0,\n          tags: a.tag_list || [],\n          reading_time: a.reading_time || null\n        }))\n      };\n  };\n  return run(params || {});\n}"},{"name":"devto_tag","description":"Latest DEV.to articles for a specific tag","inputSchema":{"type":"object","properties":{"tag":{"type":"string","description":"Tag name (e.g. javascript, python, webdev)"},"limit":{"type":"number","description":"Number of articles","default":20}},"required":["tag"]},"handler":"(params) => {\n  const args = Object.assign({\"limit\": 20}, params || {});\n  let data = null;\n  let __wbContextUrl = globalThis.location?.href || '';\n  let __wbContextDocument = globalThis.document || null;\n    const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);\n    const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');\n    const __wbGet = (value, path) => {\n      if (!path) return value;\n      return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);\n    };\n    const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');\n    const __wbResolve = (target, base) => {\n      if (target == null) return '';\n      const text = String(target);\n      try {\n        return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();\n      } catch (_error) {\n        return text;\n      }\n    };\n    const __wbFetch = async (target, options) => {\n      const url = __wbResolve(target, __wbBaseUrl());\n      const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));\n      if (!resp.ok) {\n        throw new Error(`HTTP ${resp.status} for ${url}`);\n      }\n      const text = await resp.text();\n      try {\n        return { url, text, data: JSON.parse(text) };\n      } catch (_error) {\n        return { url, text, data: text };\n      }\n    };\n  return (async () => {\n    {\n      const __wbResp = await __wbFetch(`https://dev.to/api/articles?tag=${args.tag}&per_page=${args.limit}`);\n      data = __wbResp.data;\n    }\n    {\n      const source = Array.isArray(data) ? data : (data == null ? [] : [data]);\n      data = source.map((item, index) => ({\n        \"rank\": index + 1,\n        \"title\": item.title,\n        \"author\": item.user.username,\n        \"reactions\": item.public_reactions_count,\n        \"comments\": item.comments_count,\n        \"tags\": __wbJoin((item.tag_list), ', '),\n        \"url\": item.url,\n      }));\n    }\n    if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);\n    return data;\n  })();\n}"},{"name":"devto_top","description":"Top DEV.to articles of the day","inputSchema":{"type":"object","properties":{"limit":{"type":"number","description":"Number of articles","default":20}},"required":null},"handler":"(params) => {\n  const args = Object.assign({\"limit\": 20}, params || {});\n  let data = null;\n  let __wbContextUrl = globalThis.location?.href || '';\n  let __wbContextDocument = globalThis.document || null;\n    const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);\n    const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');\n    const __wbGet = (value, path) => {\n      if (!path) return value;\n      return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);\n    };\n    const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');\n    const __wbResolve = (target, base) => {\n      if (target == null) return '';\n      const text = String(target);\n      try {\n        return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();\n      } catch (_error) {\n        return text;\n      }\n    };\n    const __wbFetch = async (target, options) => {\n      const url = __wbResolve(target, __wbBaseUrl());\n      const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));\n      if (!resp.ok) {\n        throw new Error(`HTTP ${resp.status} for ${url}`);\n      }\n      const text = await resp.text();\n      try {\n        return { url, text, data: JSON.parse(text) };\n      } catch (_error) {\n        return { url, text, data: text };\n      }\n    };\n  return (async () => {\n    {\n      const __wbResp = await __wbFetch(`https://dev.to/api/articles?top=1&per_page=${args.limit}`);\n      data = __wbResp.data;\n    }\n    {\n      const source = Array.isArray(data) ? data : (data == null ? [] : [data]);\n      data = source.map((item, index) => ({\n        \"rank\": index + 1,\n        \"title\": item.title,\n        \"author\": item.user.username,\n        \"reactions\": item.public_reactions_count,\n        \"comments\": item.comments_count,\n        \"tags\": __wbJoin((item.tag_list), ', '),\n        \"url\": item.url,\n      }));\n    }\n    if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);\n    return data;\n  })();\n}"},{"name":"devto_user","description":"Recent DEV.to articles from a specific user","inputSchema":{"type":"object","properties":{"username":{"type":"string","description":"DEV.to username (e.g. ben, thepracticaldev)"},"limit":{"type":"number","description":"Number of articles","default":20}},"required":["username"]},"handler":"(params) => {\n  const args = Object.assign({\"limit\": 20}, params || {});\n  let data = null;\n  let __wbContextUrl = globalThis.location?.href || '';\n  let __wbContextDocument = globalThis.document || null;\n    const __wbDefault = (value, fallback) => (value === undefined || value === null || value === '' ? fallback : value);\n    const __wbJoin = (value, separator) => Array.isArray(value) ? value.join(separator) : (value ?? '');\n    const __wbGet = (value, path) => {\n      if (!path) return value;\n      return String(path).split('.').reduce((acc, part) => (acc == null ? undefined : acc[part]), value);\n    };\n    const __wbBaseUrl = () => (__wbContextUrl || globalThis.location?.href || 'https://example.com/');\n    const __wbResolve = (target, base) => {\n      if (target == null) return '';\n      const text = String(target);\n      try {\n        return /^https?:/i.test(text) ? text : new URL(text, base || __wbBaseUrl()).toString();\n      } catch (_error) {\n        return text;\n      }\n    };\n    const __wbFetch = async (target, options) => {\n      const url = __wbResolve(target, __wbBaseUrl());\n      const resp = await globalThis.fetch(url, Object.assign({ credentials: 'include' }, options || {}));\n      if (!resp.ok) {\n        throw new Error(`HTTP ${resp.status} for ${url}`);\n      }\n      const text = await resp.text();\n      try {\n        return { url, text, data: JSON.parse(text) };\n      } catch (_error) {\n        return { url, text, data: text };\n      }\n    };\n  return (async () => {\n    {\n      const __wbResp = await __wbFetch(`https://dev.to/api/articles?username=${args.username}&per_page=${args.limit}`);\n      data = __wbResp.data;\n    }\n    {\n      const source = Array.isArray(data) ? data : (data == null ? [] : [data]);\n      data = source.map((item, index) => ({\n        \"rank\": index + 1,\n        \"title\": item.title,\n        \"reactions\": item.public_reactions_count,\n        \"comments\": item.comments_count,\n        \"tags\": __wbJoin((item.tag_list), ', '),\n        \"url\": item.url,\n      }));\n    }\n    if (Array.isArray(data)) data = data.slice(0, Number(args.limit) || 0);\n    return data;\n  })();\n}"}]}