pro-fetch-mcp 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +119 -0
- package/LICENSE +21 -0
- package/README.md +157 -2
- package/README.uz.md +158 -0
- package/dist/core/archive-monitoring-tools.js +152 -0
- package/dist/core/binary-source.js +23 -0
- package/dist/core/bounded-env.js +21 -0
- package/dist/core/browser-tools.js +486 -0
- package/dist/core/cache.js +95 -0
- package/dist/core/chunker.js +16 -0
- package/dist/core/composite-budget.js +138 -0
- package/dist/core/composite-gates.js +97 -0
- package/dist/core/composite.js +283 -0
- package/dist/core/crawl-tools.js +650 -0
- package/dist/core/credentials.js +40 -0
- package/dist/core/execution-engine.js +241 -0
- package/dist/core/extract-tools.js +74 -0
- package/dist/core/fetcher.js +56 -0
- package/dist/core/format.js +15 -0
- package/dist/core/github-input-guard.js +115 -0
- package/dist/core/http-client.js +430 -0
- package/dist/core/input.js +157 -0
- package/dist/core/integration-tools.js +570 -0
- package/dist/core/intent-search.js +207 -0
- package/dist/core/json-response.js +27 -0
- package/dist/core/log.js +9 -0
- package/dist/core/max-platform-tools.js +2649 -0
- package/dist/core/media-tools.js +0 -0
- package/dist/core/network-gate.js +69 -0
- package/dist/core/parser.js +27 -0
- package/dist/core/profile.js +94 -0
- package/dist/core/ratelimit.js +26 -0
- package/dist/core/research-tools.js +1017 -0
- package/dist/core/search-providers.js +101 -0
- package/dist/core/search-ranking.js +52 -0
- package/dist/core/security-policy.js +118 -0
- package/dist/core/source-from.js +50 -0
- package/dist/core/ssrf-guard.js +79 -0
- package/dist/core/text-source.js +23 -0
- package/dist/core/tool-classification.js +83 -0
- package/dist/core/tool.js +723 -0
- package/dist/core/types.js +1 -0
- package/dist/core/version.js +29 -0
- package/dist/env.js +47 -0
- package/dist/loader.js +28 -0
- package/dist/router.js +8 -0
- package/dist/server.js +65 -0
- package/dist/tools/admin/batch_schedule.js +53 -0
- package/dist/tools/admin/cache_tune.js +29 -0
- package/dist/tools/admin/capability_call.js +138 -0
- package/dist/tools/admin/capability_map.js +118 -0
- package/dist/tools/admin/category_stats.js +35 -0
- package/dist/tools/admin/config_get.js +47 -0
- package/dist/tools/admin/config_set.js +34 -0
- package/dist/tools/admin/diagnostics.js +50 -0
- package/dist/tools/admin/env_check.js +33 -0
- package/dist/tools/admin/health_check.js +39 -0
- package/dist/tools/admin/index.js +49 -0
- package/dist/tools/admin/log_tail.js +25 -0
- package/dist/tools/admin/memory_stats.js +28 -0
- package/dist/tools/admin/profile_switch.js +30 -0
- package/dist/tools/admin/proxy_status.js +53 -0
- package/dist/tools/admin/rate_limit_status.js +21 -0
- package/dist/tools/admin/registry_summary.js +32 -0
- package/dist/tools/admin/result_preview.js +30 -0
- package/dist/tools/admin/token_count.js +25 -0
- package/dist/tools/admin/tool_execute.js +44 -0
- package/dist/tools/admin/tool_list_details.js +79 -0
- package/dist/tools/admin/tool_schema.js +30 -0
- package/dist/tools/admin/tool_search.js +32 -0
- package/dist/tools/admin/usage_stats.js +31 -0
- package/dist/tools/apitest/api_diff.js +21 -0
- package/dist/tools/apitest/api_mock_respond.js +21 -0
- package/dist/tools/apitest/api_rate_limit_probe.js +21 -0
- package/dist/tools/apitest/graphql_introspect.js +21 -0
- package/dist/tools/apitest/graphql_schema_read.js +21 -0
- package/dist/tools/apitest/index.js +26 -0
- package/dist/tools/apitest/json_schema_infer.js +21 -0
- package/dist/tools/apitest/openapi_endpoints_list.js +21 -0
- package/dist/tools/apitest/openapi_fetch.js +21 -0
- package/dist/tools/apitest/openapi_parse.js +21 -0
- package/dist/tools/apitest/openapi_try.js +21 -0
- package/dist/tools/apitest/swagger_validate.js +21 -0
- package/dist/tools/apitest/wsdl_parse.js +21 -0
- package/dist/tools/archive/archive_org_fetch.js +45 -0
- package/dist/tools/archive/archive_org_save.js +42 -0
- package/dist/tools/archive/cache_clear.js +25 -0
- package/dist/tools/archive/cache_get.js +27 -0
- package/dist/tools/archive/cache_put.js +27 -0
- package/dist/tools/archive/cache_search.js +25 -0
- package/dist/tools/archive/cache_stats.js +24 -0
- package/dist/tools/archive/export_bundle.js +31 -0
- package/dist/tools/archive/google_cache_fetch.js +57 -0
- package/dist/tools/archive/import_bundle.js +36 -0
- package/dist/tools/archive/index.js +32 -0
- package/dist/tools/archive/offline_browse.js +76 -0
- package/dist/tools/archive/snapshot_diff.js +36 -0
- package/dist/tools/archive/version_history.js +31 -0
- package/dist/tools/archive/wayback_fetch.js +27 -0
- package/dist/tools/archive/wayback_lookup.js +25 -0
- package/dist/tools/auth/api_key_set.js +35 -0
- package/dist/tools/auth/basic_auth_fetch.js +62 -0
- package/dist/tools/auth/bearer_fetch.js +69 -0
- package/dist/tools/auth/cookie_jar_manage.js +66 -0
- package/dist/tools/auth/credential_test.js +18 -0
- package/dist/tools/auth/github_auth_status.js +48 -0
- package/dist/tools/auth/index.js +26 -0
- package/dist/tools/auth/oauth_device_flow.js +41 -0
- package/dist/tools/auth/scopes_audit.js +18 -0
- package/dist/tools/auth/session_list.js +25 -0
- package/dist/tools/auth/session_restore.js +26 -0
- package/dist/tools/auth/session_revoke.js +23 -0
- package/dist/tools/auth/session_save.js +40 -0
- package/dist/tools/browser/browser_action.js +64 -0
- package/dist/tools/browser/browser_back.js +20 -0
- package/dist/tools/browser/browser_clear_cookies.js +20 -0
- package/dist/tools/browser/browser_click.js +22 -0
- package/dist/tools/browser/browser_close.js +22 -0
- package/dist/tools/browser/browser_close_all.js +20 -0
- package/dist/tools/browser/browser_close_session.js +20 -0
- package/dist/tools/browser/browser_close_tab.js +23 -0
- package/dist/tools/browser/browser_console_log.js +22 -0
- package/dist/tools/browser/browser_cookies.js +27 -0
- package/dist/tools/browser/browser_device_emulate.js +22 -0
- package/dist/tools/browser/browser_dialog.js +24 -0
- package/dist/tools/browser/browser_download.js +25 -0
- package/dist/tools/browser/browser_drag.js +25 -0
- package/dist/tools/browser/browser_evaluate_js.js +22 -0
- package/dist/tools/browser/browser_extract_after_action.js +22 -0
- package/dist/tools/browser/browser_form_fill.js +22 -0
- package/dist/tools/browser/browser_forward.js +20 -0
- package/dist/tools/browser/browser_get_html.js +23 -0
- package/dist/tools/browser/browser_get_state.js +23 -0
- package/dist/tools/browser/browser_get_text.js +23 -0
- package/dist/tools/browser/browser_get_title.js +20 -0
- package/dist/tools/browser/browser_get_url.js +20 -0
- package/dist/tools/browser/browser_hover.js +24 -0
- package/dist/tools/browser/browser_list_sessions.js +20 -0
- package/dist/tools/browser/browser_list_tabs.js +20 -0
- package/dist/tools/browser/browser_login_session.js +22 -0
- package/dist/tools/browser/browser_network_log.js +22 -0
- package/dist/tools/browser/browser_new_tab.js +24 -0
- package/dist/tools/browser/browser_open.js +22 -0
- package/dist/tools/browser/browser_press_key.js +24 -0
- package/dist/tools/browser/browser_print_pdf.js +22 -0
- package/dist/tools/browser/browser_reload.js +23 -0
- package/dist/tools/browser/browser_screenshot.js +22 -0
- package/dist/tools/browser/browser_scroll.js +22 -0
- package/dist/tools/browser/browser_select.js +24 -0
- package/dist/tools/browser/browser_set_headers.js +23 -0
- package/dist/tools/browser/browser_switch_tab.js +23 -0
- package/dist/tools/browser/browser_type.js +22 -0
- package/dist/tools/browser/browser_upload_file.js +24 -0
- package/dist/tools/browser/browser_wait.js +22 -0
- package/dist/tools/browser/index.js +84 -0
- package/dist/tools/codehost/service_ops.js +3 -0
- package/dist/tools/convert/atom_to_markdown.js +53 -0
- package/dist/tools/convert/csv_to_json.js +88 -0
- package/dist/tools/convert/csv_to_markdown_table.js +42 -0
- package/dist/tools/convert/docx_to_markdown.js +71 -0
- package/dist/tools/convert/epub_to_text.js +69 -0
- package/dist/tools/convert/html_to_markdown.js +31 -0
- package/dist/tools/convert/html_to_text.js +40 -0
- package/dist/tools/convert/ical_to_json.js +73 -0
- package/dist/tools/convert/index.js +62 -0
- package/dist/tools/convert/ipynb_to_markdown.js +69 -0
- package/dist/tools/convert/json_minify.js +35 -0
- package/dist/tools/convert/json_to_csv.js +48 -0
- package/dist/tools/convert/json_to_yaml.js +36 -0
- package/dist/tools/convert/markdown_to_html.js +64 -0
- package/dist/tools/convert/mbox_to_text.js +71 -0
- package/dist/tools/convert/ocr_image.js +45 -0
- package/dist/tools/convert/odt_to_text.js +46 -0
- package/dist/tools/convert/pdf_split_pages.js +54 -0
- package/dist/tools/convert/pdf_to_markdown.js +42 -0
- package/dist/tools/convert/pdf_to_text.js +42 -0
- package/dist/tools/convert/pptx_to_text.js +70 -0
- package/dist/tools/convert/readability_extract.js +50 -0
- package/dist/tools/convert/rss_to_markdown.js +48 -0
- package/dist/tools/convert/rtf_to_text.js +111 -0
- package/dist/tools/convert/text_to_json_lines.js +29 -0
- package/dist/tools/convert/tsv_to_json.js +75 -0
- package/dist/tools/convert/vcard_to_json.js +68 -0
- package/dist/tools/convert/xlsx_to_csv.js +114 -0
- package/dist/tools/convert/xlsx_to_json.js +123 -0
- package/dist/tools/convert/xml_to_json.js +72 -0
- package/dist/tools/convert/yaml_to_json.js +36 -0
- package/dist/tools/crawl/broken_links.js +21 -0
- package/dist/tools/crawl/canonical_url.js +21 -0
- package/dist/tools/crawl/composites.js +161 -0
- package/dist/tools/crawl/crawl_depth_control.js +21 -0
- package/dist/tools/crawl/crawl_domain_scope.js +21 -0
- package/dist/tools/crawl/crawl_export.js +21 -0
- package/dist/tools/crawl/crawl_filter.js +21 -0
- package/dist/tools/crawl/crawl_pause_resume.js +21 -0
- package/dist/tools/crawl/crawl_result_merge.js +21 -0
- package/dist/tools/crawl/crawl_site.js +21 -0
- package/dist/tools/crawl/crawl_speed.js +21 -0
- package/dist/tools/crawl/extract_links.js +21 -0
- package/dist/tools/crawl/extract_metadata.js +21 -0
- package/dist/tools/crawl/extract_pagination.js +21 -0
- package/dist/tools/crawl/extract_tables.js +21 -0
- package/dist/tools/crawl/index.js +48 -0
- package/dist/tools/crawl/link_graph.js +21 -0
- package/dist/tools/crawl/page_diff.js +3 -0
- package/dist/tools/crawl/page_weight.js +21 -0
- package/dist/tools/crawl/robots_check.js +21 -0
- package/dist/tools/crawl/site_scan.js +3 -0
- package/dist/tools/crawl/sitemap_read.js +21 -0
- package/dist/tools/crawl/spa_render.js +21 -0
- package/dist/tools/crawl/url_queue_manage.js +21 -0
- package/dist/tools/data/array_ops.js +67 -0
- package/dist/tools/data/csv_stats.js +46 -0
- package/dist/tools/data/data_pipeline.js +3 -0
- package/dist/tools/data/date_convert.js +68 -0
- package/dist/tools/data/dedupe_text.js +41 -0
- package/dist/tools/data/diff_json.js +51 -0
- package/dist/tools/data/diff_text.js +33 -0
- package/dist/tools/data/encode_decode.js +44 -0
- package/dist/tools/data/group_by.js +30 -0
- package/dist/tools/data/hash_string.js +34 -0
- package/dist/tools/data/index.js +55 -0
- package/dist/tools/data/json_diff.js +53 -0
- package/dist/tools/data/json_flatten.js +42 -0
- package/dist/tools/data/jwt_decode.js +31 -0
- package/dist/tools/data/keyword_extract.js +67 -0
- package/dist/tools/data/language_detect.js +45 -0
- package/dist/tools/data/merge_results.js +32 -0
- package/dist/tools/data/ner_extract.js +32 -0
- package/dist/tools/data/number_format.js +39 -0
- package/dist/tools/data/query_string.js +42 -0
- package/dist/tools/data/random_string.js +32 -0
- package/dist/tools/data/readability_score.js +35 -0
- package/dist/tools/data/sentiment_analyze.js +60 -0
- package/dist/tools/data/text_stats.js +32 -0
- package/dist/tools/data/text_summarize.js +40 -0
- package/dist/tools/data/uuid_generate.js +23 -0
- package/dist/tools/data/word_frequency.js +31 -0
- package/dist/tools/docs/arxiv_paper_read.js +35 -0
- package/dist/tools/docs/changelog_read.js +38 -0
- package/dist/tools/docs/dockerhub_read.js +36 -0
- package/dist/tools/docs/doi_resolve.js +28 -0
- package/dist/tools/docs/huggingface_model_card.js +36 -0
- package/dist/tools/docs/index.js +32 -0
- package/dist/tools/docs/mdn_docs_read.js +28 -0
- package/dist/tools/docs/npm_package_read.js +39 -0
- package/dist/tools/docs/pubmed_read.js +28 -0
- package/dist/tools/docs/pypi_package_read.js +36 -0
- package/dist/tools/docs/readthedocs_fetch.js +27 -0
- package/dist/tools/docs/registry_api_read.js +40 -0
- package/dist/tools/docs/rfc_read.js +35 -0
- package/dist/tools/docs/stackoverflow_read.js +42 -0
- package/dist/tools/docs/w3c_spec_read.js +28 -0
- package/dist/tools/docs/wikipedia_deep_read.js +31 -0
- package/dist/tools/extract/audit_page.js +96 -0
- package/dist/tools/extract/comment_strip.js +32 -0
- package/dist/tools/extract/css_select.js +37 -0
- package/dist/tools/extract/date_extract.js +37 -0
- package/dist/tools/extract/email_extract.js +28 -0
- package/dist/tools/extract/footnote_extract.js +34 -0
- package/dist/tools/extract/form_extract.js +43 -0
- package/dist/tools/extract/heading_outline.js +43 -0
- package/dist/tools/extract/hreflang_extract.js +40 -0
- package/dist/tools/extract/image_alt_extract.js +42 -0
- package/dist/tools/extract/index.js +51 -0
- package/dist/tools/extract/json_ld_extract.js +39 -0
- package/dist/tools/extract/json_path.js +40 -0
- package/dist/tools/extract/link_classify.js +67 -0
- package/dist/tools/extract/link_domains.js +46 -0
- package/dist/tools/extract/list_extract.js +40 -0
- package/dist/tools/extract/main_content_detect.js +38 -0
- package/dist/tools/extract/meta_og_extract.js +45 -0
- package/dist/tools/extract/paginated_table_read.js +77 -0
- package/dist/tools/extract/phone_extract.js +38 -0
- package/dist/tools/extract/price_extract.js +37 -0
- package/dist/tools/extract/regex_extract.js +45 -0
- package/dist/tools/extract/schema_org_extract.js +37 -0
- package/dist/tools/extract/table_to_dataframe.js +48 -0
- package/dist/tools/extract/xpath_select.js +67 -0
- package/dist/tools/git/workspace_ops.js +145 -0
- package/dist/tools/git/workspace_ops_composites.js +180 -0
- package/dist/tools/git/workspace_ops_tool.js +2 -0
- package/dist/tools/github/_api.js +127 -0
- package/dist/tools/github/_env.js +6 -0
- package/dist/tools/github/actions_runs.js +52 -0
- package/dist/tools/github/branches_list.js +50 -0
- package/dist/tools/github/code_search.js +31 -0
- package/dist/tools/github/commit_read.js +52 -0
- package/dist/tools/github/commits_list.js +61 -0
- package/dist/tools/github/gist_read.js +33 -0
- package/dist/tools/github/index.js +102 -0
- package/dist/tools/github/issue_comments.js +51 -0
- package/dist/tools/github/issue_read.js +55 -0
- package/dist/tools/github/issue_timeline.js +45 -0
- package/dist/tools/github/issues_list.js +55 -0
- package/dist/tools/github/issues_search.js +49 -0
- package/dist/tools/github/org_repos.js +35 -0
- package/dist/tools/github/pr_checks.js +57 -0
- package/dist/tools/github/pr_diff.js +44 -0
- package/dist/tools/github/pr_files.js +45 -0
- package/dist/tools/github/pr_read.js +57 -0
- package/dist/tools/github/pr_review_comments.js +53 -0
- package/dist/tools/github/pr_review_tool.js +3 -0
- package/dist/tools/github/pr_reviews.js +51 -0
- package/dist/tools/github/prs_list.js +61 -0
- package/dist/tools/github/release_diff.js +51 -0
- package/dist/tools/github/release_read.js +48 -0
- package/dist/tools/github/releases_list.js +59 -0
- package/dist/tools/github/repo_audit.js +103 -0
- package/dist/tools/github/repo_audit_tool.js +2 -0
- package/dist/tools/github/repo_commit_activity.js +46 -0
- package/dist/tools/github/repo_compare.js +52 -0
- package/dist/tools/github/repo_contributors.js +52 -0
- package/dist/tools/github/repo_dependents.js +54 -0
- package/dist/tools/github/repo_directory_read.js +52 -0
- package/dist/tools/github/repo_docs_extract.js +50 -0
- package/dist/tools/github/repo_file_blame.js +53 -0
- package/dist/tools/github/repo_file_history.js +57 -0
- package/dist/tools/github/repo_file_read.js +47 -0
- package/dist/tools/github/repo_fork_network.js +43 -0
- package/dist/tools/github/repo_full_clone.js +78 -0
- package/dist/tools/github/repo_info.js +57 -0
- package/dist/tools/github/repo_languages.js +42 -0
- package/dist/tools/github/repo_license.js +42 -0
- package/dist/tools/github/repo_raw_file.js +51 -0
- package/dist/tools/github/repo_readme.js +42 -0
- package/dist/tools/github/repo_search.js +28 -0
- package/dist/tools/github/repo_stats.js +43 -0
- package/dist/tools/github/repo_structure_summary.js +75 -0
- package/dist/tools/github/repo_submodules.js +43 -0
- package/dist/tools/github/repo_topics.js +42 -0
- package/dist/tools/github/repo_tree.js +52 -0
- package/dist/tools/github/repo_wiki_read.js +43 -0
- package/dist/tools/github/tags_list.js +46 -0
- package/dist/tools/github/user_profile.js +33 -0
- package/dist/tools/http/download_file.js +32 -0
- package/dist/tools/http/fetch_api.js +35 -0
- package/dist/tools/http/fetch_batch.js +31 -0
- package/dist/tools/http/fetch_graphql.js +31 -0
- package/dist/tools/http/fetch_head.js +25 -0
- package/dist/tools/http/fetch_ingest.js +68 -0
- package/dist/tools/http/fetch_options.js +30 -0
- package/dist/tools/http/fetch_raw.js +27 -0
- package/dist/tools/http/fetch_retry.js +30 -0
- package/dist/tools/http/fetch_soap.js +30 -0
- package/dist/tools/http/fetch_url.js +42 -0
- package/dist/tools/http/fetch_with_proxy.js +30 -0
- package/dist/tools/http/http_status.js +31 -0
- package/dist/tools/http/index.js +41 -0
- package/dist/tools/http/post_form.js +30 -0
- package/dist/tools/http/post_multipart.js +48 -0
- package/dist/tools/http/redirect_trace.js +28 -0
- package/dist/tools/http/sse_subscribe.js +86 -0
- package/dist/tools/http/stream_fetch.js +26 -0
- package/dist/tools/http/websocket_listen.js +95 -0
- package/dist/tools/i18n/case_convert.js +60 -0
- package/dist/tools/i18n/i18n_strings_extract.js +22 -0
- package/dist/tools/i18n/index.js +26 -0
- package/dist/tools/i18n/locale_detect.js +22 -0
- package/dist/tools/i18n/mixed_lang_split.js +22 -0
- package/dist/tools/i18n/reading_time.js +36 -0
- package/dist/tools/i18n/rtl_normalize.js +22 -0
- package/dist/tools/i18n/script_convert.js +22 -0
- package/dist/tools/i18n/slugify.js +31 -0
- package/dist/tools/i18n/translate_page.js +22 -0
- package/dist/tools/i18n/translate_text.js +22 -0
- package/dist/tools/i18n/transliterate.js +22 -0
- package/dist/tools/i18n/unicode_normalize.js +27 -0
- package/dist/tools/max-platform/index.js +2 -0
- package/dist/tools/media/audio_transcribe.js +21 -0
- package/dist/tools/media/barcode_qr_read.js +21 -0
- package/dist/tools/media/exif_read.js +21 -0
- package/dist/tools/media/favicon_fetch.js +21 -0
- package/dist/tools/media/image_convert.js +21 -0
- package/dist/tools/media/image_info.js +21 -0
- package/dist/tools/media/image_ocr.js +21 -0
- package/dist/tools/media/image_resize.js +21 -0
- package/dist/tools/media/index.js +32 -0
- package/dist/tools/media/media_download.js +21 -0
- package/dist/tools/media/pdf_ocr.js +21 -0
- package/dist/tools/media/screenshot_full_page.js +21 -0
- package/dist/tools/media/screenshot_page.js +21 -0
- package/dist/tools/media/svg_to_png.js +21 -0
- package/dist/tools/media/thumbnail_generate.js +21 -0
- package/dist/tools/media/video_metadata.js +21 -0
- package/dist/tools/monitoring/digest_build.js +59 -0
- package/dist/tools/monitoring/feed_subscribe.js +88 -0
- package/dist/tools/monitoring/index.js +22 -0
- package/dist/tools/monitoring/jobs_watch.js +75 -0
- package/dist/tools/monitoring/keyword_alert.js +64 -0
- package/dist/tools/monitoring/page_diff_notify.js +36 -0
- package/dist/tools/monitoring/price_watch.js +91 -0
- package/dist/tools/monitoring/release_watch.js +60 -0
- package/dist/tools/monitoring/uptime_check.js +39 -0
- package/dist/tools/monitoring/url_watch.js +32 -0
- package/dist/tools/monitoring/watch_list.js +40 -0
- package/dist/tools/research/build_knowledge_graph.js +21 -0
- package/dist/tools/research/citation_format.js +21 -0
- package/dist/tools/research/citation_graph.js +21 -0
- package/dist/tools/research/compare_sources.js +21 -0
- package/dist/tools/research/contradiction_detect.js +21 -0
- package/dist/tools/research/crawl_for_topic.js +21 -0
- package/dist/tools/research/cross_check.js +21 -0
- package/dist/tools/research/dedupe_sources.js +21 -0
- package/dist/tools/research/entity_resolve.js +21 -0
- package/dist/tools/research/evidence_strength.js +21 -0
- package/dist/tools/research/extract_facts.js +21 -0
- package/dist/tools/research/fact_ledger.js +21 -0
- package/dist/tools/research/followup_questions.js +21 -0
- package/dist/tools/research/gap_analysis.js +21 -0
- package/dist/tools/research/gather_sources.js +21 -0
- package/dist/tools/research/hypothesis_generate.js +21 -0
- package/dist/tools/research/index.js +55 -0
- package/dist/tools/research/multi_lang_research.js +21 -0
- package/dist/tools/research/rank_sources.js +21 -0
- package/dist/tools/research/research_deep.js +110 -0
- package/dist/tools/research/research_iterate.js +21 -0
- package/dist/tools/research/research_plan.js +21 -0
- package/dist/tools/research/research_report.js +21 -0
- package/dist/tools/research/research_summarize.js +21 -0
- package/dist/tools/research/source_bias_detect.js +21 -0
- package/dist/tools/research/timeline_build.js +21 -0
- package/dist/tools/research/verify_claim.js +21 -0
- package/dist/tools/search/academic_search.js +48 -0
- package/dist/tools/search/blog_search.js +47 -0
- package/dist/tools/search/books_search.js +48 -0
- package/dist/tools/search/cached_search.js +32 -0
- package/dist/tools/search/code_search.js +49 -0
- package/dist/tools/search/dataset_search.js +47 -0
- package/dist/tools/search/date_filter_search.js +45 -0
- package/dist/tools/search/forum_search.js +55 -0
- package/dist/tools/search/image_search.js +63 -0
- package/dist/tools/search/index.js +42 -0
- package/dist/tools/search/jobs_search.js +52 -0
- package/dist/tools/search/market_search.js +54 -0
- package/dist/tools/search/news_search.js +56 -0
- package/dist/tools/search/patent_search.js +45 -0
- package/dist/tools/search/related_queries.js +39 -0
- package/dist/tools/search/reverse_image_search.js +48 -0
- package/dist/tools/search/search_suggest.js +57 -0
- package/dist/tools/search/site_search.js +39 -0
- package/dist/tools/search/video_search.js +55 -0
- package/dist/tools/search/web_search.js +40 -0
- package/dist/tools/search/wiki_search.js +52 -0
- package/package.json +90 -4
package/.env.example
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# pro-fetch-mcp — environment reference
|
|
2
|
+
#
|
|
3
|
+
# Copy to `.env` or (recommended on Windows) set these as USER environment variables.
|
|
4
|
+
# NEVER commit real secrets. Every secret below may alternatively be supplied as
|
|
5
|
+
# <NAME>_FILE=<path to a local file containing only the value> (max 16 KiB).
|
|
6
|
+
# Empty values mean "not configured".
|
|
7
|
+
|
|
8
|
+
# ── Profile / tool visibility ────────────────────────────────────────────────
|
|
9
|
+
# smart (5 meta-tools, default in mcp.json) | minimal | standard (default) | full
|
|
10
|
+
PRO_FETCH_PROFILE=smart
|
|
11
|
+
|
|
12
|
+
# ── Safety policy ────────────────────────────────────────────────────────────
|
|
13
|
+
# true => block every mutating tool and every non-GET/HEAD/OPTIONS HTTP method
|
|
14
|
+
PRO_FETCH_READ_ONLY=
|
|
15
|
+
# Comma-separated tool names allowed even in read-only mode
|
|
16
|
+
PRO_FETCH_MUTATION_ALLOWLIST=
|
|
17
|
+
# Comma-separated policy lists (tool names / category names)
|
|
18
|
+
PRO_FETCH_ALLOWED_TOOLS=
|
|
19
|
+
PRO_FETCH_DENIED_TOOLS=
|
|
20
|
+
PRO_FETCH_DENIED_CATEGORIES=
|
|
21
|
+
# Files written via output_path / storage_state_path must live under this directory
|
|
22
|
+
PRO_FETCH_OUTPUT_ROOT=
|
|
23
|
+
# Required to run `npm test` / `npm build` tools (still needs confirm=true per call)
|
|
24
|
+
PRO_FETCH_ALLOW_COMMANDS=
|
|
25
|
+
# Required for browser evaluate/execute/script tools (run arbitrary page JavaScript)
|
|
26
|
+
PRO_FETCH_ALLOW_JS=
|
|
27
|
+
# Relax network hardening (leave unset unless you know you need them)
|
|
28
|
+
PRO_FETCH_ALLOW_HTTPS_DOWNGRADE=
|
|
29
|
+
PRO_FETCH_ALLOW_UNPINNED_PROXY_DNS=
|
|
30
|
+
|
|
31
|
+
# ── Limits ───────────────────────────────────────────────────────────────────
|
|
32
|
+
PRO_FETCH_TOOL_TIMEOUT_MS=180000
|
|
33
|
+
# After a tool timeout, how long its concurrency slots stay reserved while the
|
|
34
|
+
# handler is still running before they are force-released (default 30000)
|
|
35
|
+
PRO_FETCH_ABANDON_GRACE_MS=30000
|
|
36
|
+
PRO_FETCH_MAX_CONCURRENCY=32
|
|
37
|
+
PRO_FETCH_MAX_CATEGORY_CONCURRENCY=8
|
|
38
|
+
PRO_FETCH_MAX_NETWORK_CONCURRENCY=32
|
|
39
|
+
PRO_FETCH_MAX_PER_HOST_CONCURRENCY=4
|
|
40
|
+
PRO_FETCH_MAX_INPUT_BYTES=2097152
|
|
41
|
+
PRO_FETCH_MAX_BYTES=
|
|
42
|
+
PRO_FETCH_TIMEOUT_MS=
|
|
43
|
+
PRO_FETCH_COMMAND_TIMEOUT_MS=30000
|
|
44
|
+
PRO_FETCH_BROWSER_MAX_SESSIONS=
|
|
45
|
+
PRO_FETCH_GITHUB_MAX_PAGES=5
|
|
46
|
+
|
|
47
|
+
# ── Paths ────────────────────────────────────────────────────────────────────
|
|
48
|
+
PRO_FETCH_CACHE_DIR=.pro-fetch-cache
|
|
49
|
+
PRO_FETCH_HTTP_CACHE_TTL_MS=
|
|
50
|
+
# Root for local git/devops/database/storage tools (defaults to the process cwd)
|
|
51
|
+
PRO_FETCH_WORKSPACE=
|
|
52
|
+
PRO_FETCH_SQLITE_PATH=
|
|
53
|
+
PRO_FETCH_KNOWLEDGE_DB=
|
|
54
|
+
# Playwright build to drive: chrome | msedge | chromium | firefox | webkit
|
|
55
|
+
# Empty = Playwright's own bundled build.
|
|
56
|
+
PRO_FETCH_BROWSER_CHANNEL=
|
|
57
|
+
# IANA timezone applied to browser contexts, for example Europe/Tashkent.
|
|
58
|
+
# Empty = the host timezone.
|
|
59
|
+
PRO_FETCH_BROWSER_TZ=
|
|
60
|
+
|
|
61
|
+
# ── Proxy (standard variables are honoured) ──────────────────────────────────
|
|
62
|
+
HTTP_PROXY=
|
|
63
|
+
HTTPS_PROXY=
|
|
64
|
+
ALL_PROXY=
|
|
65
|
+
NO_PROXY=
|
|
66
|
+
|
|
67
|
+
# ── Credentials (leave empty in version control) ─────────────────────────────
|
|
68
|
+
# Any credential may instead be supplied as <NAME>_FILE=<path>. A relative path is
|
|
69
|
+
# resolved against the package root, not the process working directory, so it keeps
|
|
70
|
+
# working regardless of where the MCP client spawns the server. `.secrets/` is
|
|
71
|
+
# git-ignored and is the recommended location for local secret files.
|
|
72
|
+
#
|
|
73
|
+
# JIRA_TOKEN_FILE=.secrets/JIRA_TOKEN.txt
|
|
74
|
+
#
|
|
75
|
+
# GitHub (REST tools, code search, release monitoring)
|
|
76
|
+
GITHUB_TOKEN=
|
|
77
|
+
GITHUB_CLIENT_ID=
|
|
78
|
+
# Web search (Serper/Google yoki Brave API; ikkalasi ham bo'sh bo'lsa DuckDuckGo'ga tushadi)
|
|
79
|
+
SERPER_API_KEY=
|
|
80
|
+
SEARCH_API_KEY=
|
|
81
|
+
SERPAPI_API_KEY=
|
|
82
|
+
YOUTUBE_API_KEY=
|
|
83
|
+
|
|
84
|
+
# OpenAI-compatible endpoint for embeddings / media tools
|
|
85
|
+
OPENAI_API_KEY=
|
|
86
|
+
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
87
|
+
OPENAI_EMBEDDINGS_BASE_URL=
|
|
88
|
+
OPENAI_EMBEDDING_MODEL=
|
|
89
|
+
|
|
90
|
+
# Code hosts (MAX codehost pack)
|
|
91
|
+
GITLAB_TOKEN=
|
|
92
|
+
GITEA_TOKEN=
|
|
93
|
+
FORGEJO_TOKEN=
|
|
94
|
+
BITBUCKET_TOKEN=
|
|
95
|
+
|
|
96
|
+
# Collaboration
|
|
97
|
+
SLACK_BOT_TOKEN=
|
|
98
|
+
LINEAR_API_KEY=
|
|
99
|
+
JIRA_BASE_URL=
|
|
100
|
+
JIRA_EMAIL=
|
|
101
|
+
JIRA_TOKEN=
|
|
102
|
+
NOTION_TOKEN=
|
|
103
|
+
|
|
104
|
+
# Storage / productivity
|
|
105
|
+
DROPBOX_TOKEN=
|
|
106
|
+
GOOGLE_DRIVE_TOKEN=
|
|
107
|
+
MICROSOFT_GRAPH_TOKEN=
|
|
108
|
+
GOOGLE_ACCESS_TOKEN=
|
|
109
|
+
GMAIL_TOKEN=
|
|
110
|
+
TODOIST_API_TOKEN=
|
|
111
|
+
|
|
112
|
+
# Databases (MAX database pack; connection strings contain secrets)
|
|
113
|
+
DATABASE_URL=
|
|
114
|
+
POSTGRES_URL=
|
|
115
|
+
MYSQL_URL=
|
|
116
|
+
REDIS_URL=
|
|
117
|
+
# Optional exact host allowlist for self-hosted GitLab/Gitea/Forgejo/Bitbucket APIs.
|
|
118
|
+
# Comma-separated hostnames only, without scheme or path. Empty means official defaults only.
|
|
119
|
+
PRO_FETCH_ALLOWED_CODEHOST_HOSTS=
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shuhratbek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,158 @@
|
|
|
1
|
-
#
|
|
1
|
+
# pro-fetch-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Professional fetch, deep-research & GitHub MCP server — **571 MCP tool, 26 categories, one security engine**.
|
|
4
|
+
|
|
5
|
+
A model gets the tools it actually needs: the default `smart` profile exposes **10 meta-tools** that compose all 571, so any MCP client works without drowning in schemas.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Why
|
|
13
|
+
|
|
14
|
+
- **571 working tools** — fetch, crawl, extract, convert, OCR, search, research, git, GitHub, GitLab/Gitea/Forgejo/Bitbucket, SQLite, security, Slack/Jira/Linear/Notion, storage, and more. Every one is a real implementation, not a stub.
|
|
15
|
+
- **Smart System** — 10 meta-tools (`pro_capability_call`, `pro_capability_map`, `pro_research_deep`, …) that dispatch to the full catalog in a single round trip. Batch execution, BM25 task-to-tool discovery, and a `detail` mode that cut a 17-step audit from 43 KB to 3.8 KB (**91% token savings**, measured).
|
|
16
|
+
- **Security is the engine, not a warning** — SSRF guard with DNS pinning, workspace sandbox with symlink tracking, per-call permission policy, credential stripping on cross-origin redirects, HTTPS→HTTP downgrade blocking. Every composite call passes through the same `dispatch()` gate.
|
|
17
|
+
- **Degrades, never dies** — native binaries (sharp, canvas, tesseract) are lazy-loaded; missing git/docker/kubectl produce a clear `COMMAND_NOT_FOUND`; the server boots and serves 500+ tools on a host with none of them.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y pro-fetch-mcp # stdio MCP server, zero config
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Any MCP client — Claude Desktop, Cursor, Qwen, VS Code, your own harness:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"pro-fetch": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "pro-fetch-mcp"],
|
|
33
|
+
"env": { "PRO_FETCH_PROFILE": "smart" }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Ready-to-copy config: [`mcp.example.json`](mcp.example.json).
|
|
40
|
+
|
|
41
|
+
Credentials go in a `.env` next to the server (or `*_FILE` env vars pointing at a file — never the value itself). `.env` is never committed and never ships in the npm package.
|
|
42
|
+
|
|
43
|
+
| Credential | Unlocks |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `GITHUB_TOKEN` | code search, private repos, higher rate limits |
|
|
46
|
+
| `SERPER_API_KEY` | Google-backed web search |
|
|
47
|
+
| `OPENAI_API_KEY` | audio transcription, embedding hybrid retrieval |
|
|
48
|
+
| `SEARCH_API_KEY` | Brave search (DuckDuckGo fallback otherwise) |
|
|
49
|
+
| `GITLAB_TOKEN`, `SLACK_BOT_TOKEN`, `JIRA_TOKEN`, … | the matching adapter pack — see [`.env.example`](.env.example) |
|
|
50
|
+
|
|
51
|
+
## The Smart System
|
|
52
|
+
|
|
53
|
+
Most MCP clients choke on hundreds of tool schemas. `smart` (the default) shows the model **10 tools** that compose everything:
|
|
54
|
+
|
|
55
|
+
| Tool | What it does |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `pro_capability_call` | **Batch executor** — runs a list of `{tool, arguments}` in one call; each result returns its own `ok`/`error` |
|
|
58
|
+
| `pro_capability_map` | Plain-language task → exact tools with their schemas (BM25 + morphological expansion) |
|
|
59
|
+
| `pro_fetch_tool_execute` | Call any tool by exact name |
|
|
60
|
+
| `pro_research_deep` | Search → read → facts → verify → report |
|
|
61
|
+
| `pro_fetch_ingest` | Any URL → clean structured data (page, PDF, CSV, feed) |
|
|
62
|
+
| `pro_audit_page` | One page → every relevant extraction |
|
|
63
|
+
| `pro_repo_audit` | Repo → full report (metadata, README, tree, issues, PRs, releases) |
|
|
64
|
+
| `pro_pr_review` | PR → full review (diff, checks, reviews, comments) |
|
|
65
|
+
| `pro_site_scan` | Crawl a site and explain it |
|
|
66
|
+
| `pro_data_pipeline` | Load, profile and transform a dataset |
|
|
67
|
+
|
|
68
|
+
Three round trips become one:
|
|
69
|
+
|
|
70
|
+
```jsonc
|
|
71
|
+
{ "tool": "pro_capability_call", "arguments": {
|
|
72
|
+
"calls": [
|
|
73
|
+
{ "tool": "pro_fetch_web_search", "arguments": { "query": "RAG architecture 2025" }, "label": "search" },
|
|
74
|
+
{ "tool": "pro_fetch_academic_search", "arguments": { "query": "retrieval augmented generation" }, "label": "papers" },
|
|
75
|
+
{ "tool": "pro_fetch_news_search", "arguments": { "query": "RAG news" }, "label": "news" }
|
|
76
|
+
]
|
|
77
|
+
}}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Security is not weakened by composition.** Every internal call goes through the central `dispatch()`, so `PRO_FETCH_ALLOWED_TOOLS`, `PRO_FETCH_READ_ONLY`, the SSRF check, the output sandbox and timeouts apply unchanged. If `pro_capability_call` itself is not on the allowlist, it does not run.
|
|
81
|
+
|
|
82
|
+
## Tool catalog
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary><b>All 26 categories — 571 tools</b></summary>
|
|
86
|
+
|
|
87
|
+
| Category | Tools | Category | Tools |
|
|
88
|
+
|---|---:|---|---:|
|
|
89
|
+
| github | 49 | crawl | 22 |
|
|
90
|
+
| browser (Playwright) | 41 | search | 20 |
|
|
91
|
+
| convert | 30 | http | 19 |
|
|
92
|
+
| collaboration (Slack/Linear/Jira/Notion) | 28 | knowledge (local store) | 18 |
|
|
93
|
+
| research | 26 | productivity (Gmail/Calendar/Todoist) | 18 |
|
|
94
|
+
| data | 26 | storage (S3/Drive/Dropbox/OneDrive) | 16 |
|
|
95
|
+
| codehost (GitLab/Gitea/Forgejo/Bitbucket) | 25 | media (sharp/EXIF/QR/OCR/PDF) | 15 |
|
|
96
|
+
| extract (CSS/XPath/JSONPath/OG) | 24 | archive | 15 |
|
|
97
|
+
| devops (docker/kubectl/terraform/npm) | 24 | docs (arXiv/npm/PyPI/RFC/PubMed) | 15 |
|
|
98
|
+
| database (SQLite/Postgres/MySQL/Redis) | 24 | auth (sessions & keys, in-memory only) | 12 |
|
|
99
|
+
| security (OSV/secret scan/SBOM) | 24 | apitest (OpenAPI/GraphQL/WSDL) | 12 |
|
|
100
|
+
| admin (discovery, metrics, policy) | 23 | i18n | 12 |
|
|
101
|
+
| git | 23 | monitoring | 10 |
|
|
102
|
+
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
**Profiles** control how many schemas the model sees — not the security boundary:
|
|
106
|
+
|
|
107
|
+
| Profile | Tools | Contents |
|
|
108
|
+
|---|---:|---|
|
|
109
|
+
| `minimal` | 72 | http, convert, admin |
|
|
110
|
+
| `standard` (default) | 177 | + github, search, extract, auth |
|
|
111
|
+
| `smart` | 10 | the Smart System above |
|
|
112
|
+
| `full` | 571 | everything |
|
|
113
|
+
|
|
114
|
+
Real access control lives in the environment: `PRO_FETCH_ALLOWED_TOOLS`, `PRO_FETCH_DENIED_TOOLS`, `PRO_FETCH_DENIED_CATEGORIES`, `PRO_FETCH_READ_ONLY`, `PRO_FETCH_MUTATION_ALLOWLIST`, `PRO_FETCH_OUTPUT_ROOT` — enforced on every call, including calls made through the meta-executor.
|
|
115
|
+
|
|
116
|
+
## Security model
|
|
117
|
+
|
|
118
|
+
- **SSRF guard** — outbound HTTP(S) resolves and verifies DNS, pins the connection; `HTTP_PROXY`/`HTTPS_PROXY` require an explicit opt-in because a remote proxy resolves DNS itself.
|
|
119
|
+
- **Workspace sandbox** — with `PRO_FETCH_OUTPUT_ROOT`, every `output_path` and browser `storage_state_path` write is contained (symlinks and junctions are followed and rejected on escape).
|
|
120
|
+
- **GitHub input guard** — `owner`/`repo`/`path`/`gist_id`/SHAs are validated centrally; traversal, deep paths and API-relevant characters are rejected.
|
|
121
|
+
- **Redirect safety** — credentials are stripped on cross-origin hops; HTTPS→HTTP downgrades are blocked; redirect *loops* are reported as bot protection, not as a hop count.
|
|
122
|
+
- **Process hardening** — media bytes are identified by signature *before* any decoder sees them (a hostile file cannot crash a worker thread), every `import().then()` chain carries a `.catch()`, and `uncaughtException`/`unhandledRejection` handlers log to stderr instead of killing the server.
|
|
123
|
+
- **Secrets** — diagnostics report only whether a credential is present and its source, never its value.
|
|
124
|
+
|
|
125
|
+
Full boundary list: [SECURITY.md](SECURITY.md).
|
|
126
|
+
|
|
127
|
+
## Requirements & graceful degradation
|
|
128
|
+
|
|
129
|
+
**Node.js ≥ 22.13** (required by `pdfjs-dist@6`). Everything else is optional:
|
|
130
|
+
|
|
131
|
+
| Optional | Effect when absent |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `sharp`, `@napi-rs/canvas`, `tesseract.js` binaries | media tools fail individually; server boots and serves the rest |
|
|
134
|
+
| `git`, `docker`, `kubectl`, `terraform`, `psql`, `redis-cli` | those tools answer `COMMAND_NOT_FOUND` with a precise message |
|
|
135
|
+
| Playwright browsers | browser pack reports it needs `npx playwright install --with-deps chromium` |
|
|
136
|
+
| npm build scripts (`--ignore-scripts`) | SQLite tools report `SQLITE_UNAVAILABLE` with the fix (`npm rebuild better-sqlite3`) |
|
|
137
|
+
|
|
138
|
+
SQLite needs **no system binary** — it uses the bundled `better-sqlite3` driver (the `sqlite3` CLI is only a fallback). On Windows, npm tools invoke `npm-cli.js` through `process.execPath`, so `npm audit`, `npm outdated` and license reports work there too.
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm ci
|
|
144
|
+
npm run check # verify:static → verify:registry → build → test → verify:package → format:check
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **242 tests** (Vitest): SSRF, redirects, permission policy, output sandbox, timeouts, every tool's input contract, and live provider-failure behaviour.
|
|
148
|
+
- `verify:registry` boots the real registry and asserts **571 tools / 26 categories / all four profile counts**.
|
|
149
|
+
- `verify:package` proves the published tarball has the shebang, the `files` allowlist, and **zero credentials or source files**.
|
|
150
|
+
- The MCP protocol itself was exercised live: `initialize`, `tools/list` (571/571 unique, valid schemas), `tools/call` for every smart tool, hidden tools refused, clean JSON-RPC on stdout.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
[MIT](LICENSE)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
[O'zbekcha versiya](README.uz.md) · [Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md)
|
package/README.uz.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# pro-fetch-mcp
|
|
2
|
+
|
|
3
|
+
Professional fetch, deep-research va GitHub MCP serveri — **571 tool, 26 kategoriya, bitta xavfsizlik enginei**.
|
|
4
|
+
|
|
5
|
+
Modelga kerak bo'lgan tool beriladi: standart `smart` profil **10 ta meta-tool** orqali barcha 571 ni tarkibiy tarzda ochadi — MCP mijoz schema'lar botinishiga yo'l qo'ymaydi.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Nima uchun
|
|
13
|
+
|
|
14
|
+
- **571 ishlaydigan tool** — fetch, crawl, ekstraksiya, konvertatsiya, OCR, qidiruv, tadqiqot, git, GitHub, GitLab/Gitea/Forgejo/Bitbucket, SQLite, xavfsizlik, Slack/Jira/Linear/Notion, storage va yana. Har biri haqiqiy amalga oshirilgan, stub emas.
|
|
15
|
+
- **Smart System** — 10 ta meta-tool (`pro_capability_call`, `pro_capability_map`, `pro_research_deep`, …) barcha katalogni bitta round trip'da ishga tushiradi. Batch ijro, BM25 vazifa→tool discovery va `detail` rejimi 17-qadamli auditni 43 KB dan 3.8 KB ga qisqartirdi (**o'lchangan: 91% token tejash**).
|
|
16
|
+
- **Xavfsizlik — ogohlantirish emas, engine** — DNS pinning'li SSRF himoyasi, symlink kuzatiladigan workspace sandboxi, har bir chaqiruvda permission siyosati, cross-origin redirect'larda credential stripping, HTTPS→HTTP downgrade blokirovkasi. Har bir kompozit chaqiruv bir xil `dispatch()` darvozasidan o'tadi.
|
|
17
|
+
- **Nobud bo'lmaydi** — native binary'lar (sharp, canvas, tesseract) lazy yuklanadi; git/docker/kubectl yo'qligida aniq `COMMAND_NOT_FOUND`; hech biri o'rnatilmagan hostda ham server ishga tushib 500+ tool xizmat qiladi.
|
|
18
|
+
|
|
19
|
+
## Tez boshlash
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y pro-fetch-mcp # stdio MCP server, nol konfiguratsiya
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Istalgan MCP mijoz — Claude Desktop, Cursor, Qwen, VS Code, sizning harness'ingiz:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"pro-fetch": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "pro-fetch-mcp"],
|
|
33
|
+
"env": { "PRO_FETCH_PROFILE": "smart" }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Tayyor nusxa: [`mcp.example.json`](mcp.example.json).
|
|
40
|
+
|
|
41
|
+
Kalitlar server yonidagi `.env` da (yoki qiymat o'rnini ko'rsatuvchi `*_FILE` o'zgaruvchilarda) saqlanadi. `.env` hech qachon commit qilinmaydi va npm paketiga kirmaydi.
|
|
42
|
+
|
|
43
|
+
| Credential | Nima ochadi |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `GITHUB_TOKEN` | code search, private repo, yuqori rate limit |
|
|
46
|
+
| `SERPER_API_KEY` | Google asosli web search |
|
|
47
|
+
| `OPENAI_API_KEY` | audio transkripsiya, embedding hybrid retrieval |
|
|
48
|
+
| `SEARCH_API_KEY` | Brave search (yo'q bo'lsa DuckDuckGo) |
|
|
49
|
+
| `GITLAB_TOKEN`, `SLACK_BOT_TOKEN`, `JIRA_TOKEN`, … | mos adapter pack — [`.env.example`](.env.example) |
|
|
50
|
+
|
|
51
|
+
## Smart System
|
|
52
|
+
|
|
53
|
+
Ko'p MCP mijoz yuzlab tool schema'iga chidamaydi. `smart` (standart) modelga **10 ta tool** ko'rsatadi, ular hammasini tarkib qiladi:
|
|
54
|
+
|
|
55
|
+
| Tool | Nima qiladi |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `pro_capability_call` | **Batch executor** — `{tool, arguments}` ro'yxatini bitta chaqiruvda bajaradi; natijada har biri alohida `ok`/`error` |
|
|
58
|
+
| `pro_capability_map` | Oddiy tildagi vazifa → aniq tool va uning schema'si (BM25 + morfologik kengaytirish) |
|
|
59
|
+
| `pro_fetch_tool_execute` | Aniq nom bilan bitta tool chaqirish |
|
|
60
|
+
| `pro_research_deep` | Qidiruv → o'qish → faktlar → tekshiruv → hisobot |
|
|
61
|
+
| `pro_fetch_ingest` | Istalgan URL → toza tuzilgan ma'lumot (sahifa, PDF, CSV, feed) |
|
|
62
|
+
| `pro_audit_page` | Bitta sahifa → barcha tegishli ekstraksiyalar |
|
|
63
|
+
| `pro_repo_audit` | Repo → to'liq hisobot (metadata, README, tree, issues, PR, release) |
|
|
64
|
+
| `pro_pr_review` | PR → to'liq review (diff, checks, reviews, izohlar) |
|
|
65
|
+
| `pro_site_scan` | Saytni crawl qilib tushuntirish |
|
|
66
|
+
| `pro_data_pipeline` | Datasetni yuklash, profillash va qayta ishlash |
|
|
67
|
+
|
|
68
|
+
3 ta round trip 1 taga aylanadi:
|
|
69
|
+
|
|
70
|
+
```jsonc
|
|
71
|
+
{ "tool": "pro_capability_call", "arguments": {
|
|
72
|
+
"calls": [
|
|
73
|
+
{ "tool": "pro_fetch_web_search", "arguments": { "query": "RAG arxitekturasi 2025" }, "label": "search" },
|
|
74
|
+
{ "tool": "pro_fetch_academic_search", "arguments": { "query": "retrieval augmented generation" }, "label": "papers" },
|
|
75
|
+
{ "tool": "pro_fetch_news_search", "arguments": { "query": "RAG news" }, "label": "news" }
|
|
76
|
+
]
|
|
77
|
+
}}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Tarkibiyat xavfsizlikni zaiflashtirmaydi.** Har bir ichki chaqiruv markaziy `dispatch()` orqali o'tadi, shuning uchun `PRO_FETCH_ALLOWED_TOOLS`, `PRO_FETCH_READ_ONLY`, SSRF tekshiruvi, output sandboxi va timeout o'zgarmagan holda qo'llaniladi. `pro_capability_call` ozi allowlistda bo'lmasa, u umuman ishga tushmaydi.
|
|
81
|
+
|
|
82
|
+
## Tool katalogi
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary><b>Barcha 26 kategoriya — 571 tool</b></summary>
|
|
86
|
+
|
|
87
|
+
| Kategoriya | Tool | Kategoriya | Tool |
|
|
88
|
+
|---|---:|---|---:|
|
|
89
|
+
| github | 49 | crawl | 22 |
|
|
90
|
+
| browser (Playwright) | 41 | search | 20 |
|
|
91
|
+
| convert | 30 | http | 19 |
|
|
92
|
+
| collaboration (Slack/Linear/Jira/Notion) | 28 | knowledge (local store) | 18 |
|
|
93
|
+
| research | 26 | productivity (Gmail/Calendar/Todoist) | 18 |
|
|
94
|
+
| data | 26 | storage (S3/Drive/Dropbox/OneDrive) | 16 |
|
|
95
|
+
| codehost (GitLab/Gitea/Forgejo/Bitbucket) | 25 | media (sharp/EXIF/QR/OCR/PDF) | 15 |
|
|
96
|
+
| extract (CSS/XPath/JSONPath/OG) | 24 | archive | 15 |
|
|
97
|
+
| devops (docker/kubectl/terraform/npm) | 24 | docs (arXiv/npm/PyPI/RFC/PubMed) | 15 |
|
|
98
|
+
| database (SQLite/Postgres/MySQL/Redis) | 24 | auth (session va kalitlar, faqat xotirada) | 12 |
|
|
99
|
+
| security (OSV/secret scan/SBOM) | 24 | apitest (OpenAPI/GraphQL/WSDL) | 12 |
|
|
100
|
+
| admin (discovery, metrics, policy) | 23 | i18n | 12 |
|
|
101
|
+
| git | 23 | monitoring | 10 |
|
|
102
|
+
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
**Profillar** modelga qancha schema ko'rinishini boshqaradi — xavfsizlik chegarasi emas:
|
|
106
|
+
|
|
107
|
+
| Profil | Tool | Tarkibi |
|
|
108
|
+
|---|---:|---|
|
|
109
|
+
| `minimal` | 72 | http, convert, admin |
|
|
110
|
+
| `standard` (default) | 177 | + github, search, extract, auth |
|
|
111
|
+
| `smart` | 10 | yuqoridagi Smart System |
|
|
112
|
+
| `full` | 571 | hammasi |
|
|
113
|
+
|
|
114
|
+
Haqiqiy kirish nazorati environment'da: `PRO_FETCH_ALLOWED_TOOLS`, `PRO_FETCH_DENIED_TOOLS`, `PRO_FETCH_DENIED_CATEGORIES`, `PRO_FETCH_READ_ONLY`, `PRO_FETCH_MUTATION_ALLOWLIST`, `PRO_FETCH_OUTPUT_ROOT` — har bir chaqiruvda, meta-executor orqali chaqirilganlarda ham, qo'llaniladi.
|
|
115
|
+
|
|
116
|
+
## Xavfsizlik modeli
|
|
117
|
+
|
|
118
|
+
- **SSRF himoyasi** — chiquvchi HTTP(S) DNS'ni resolve qilib tekshiradi va connection'ni pin'laydi; `HTTP_PROXY`/`HTTPS_PROXY` faqat ataylab yoqiladi, chunki uzoq proxy target DNS'ini o'zi resolve qiladi.
|
|
119
|
+
- **Workspace sandboxi** — `PRO_FETCH_OUTPUT_ROOT` berilganda har bir `output_path` va browser `storage_state_path` yozuvi shu papka ichida saqlanadi (symlink va junction'lar kuzatilib, qochish rad etiladi).
|
|
120
|
+
- **GitHub kiritma himoyasi** — `owner`/`repo`/`path`/`gist_id`/SHA markaziy ravishda tekshiriladi; traversal, chuqur path va API'ni o'zgartiradigan belgilar rad etiladi.
|
|
121
|
+
- **Redirect xavfsizligi** — cross-origin o'tishlarda credential'lar o'chiriladi; HTTPS→HTTP downgrade bloklanadi; redirect **loop'lari** bot himoyasi sifatida xabarlanadi, hop soni emas.
|
|
122
|
+
- **Jarayon barqarorligi** — media baytlari dekoder ko'rishidan oldin belgi bilan aniqlanadi (dushman fayl worker thread'ni ag'dara olmaydi), har bir `import().then()` zanjirida `.catch()` bor, `uncaughtException`/`unhandledRejection` handler'lari serverni o'ldirish o'rniga stderr'ga yozadi.
|
|
123
|
+
- **Secretlar** — diagnostika faqat credential bor-yo'qligi va manbasini ko'rsatadi, qiymatini yo'q.
|
|
124
|
+
|
|
125
|
+
To'liq chegara ro'yxati: [SECURITY.md](SECURITY.md).
|
|
126
|
+
|
|
127
|
+
## Talablar va yumshoq degradatsiya
|
|
128
|
+
|
|
129
|
+
**Node.js ≥ 22.13** (`pdfjs-dist@6` shuni talab qiladi). Qolgan barchasi ixtiyoriy:
|
|
130
|
+
|
|
131
|
+
| Ixtiyoriy | Yo'q bo'lgandagi ta'sir |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `sharp`, `@napi-rs/canvas`, `tesseract.js` binary'lari | media tool'lari alohida xato beradi; server ishlayveradi |
|
|
134
|
+
| `git`, `docker`, `kubectl`, `terraform`, `psql`, `redis-cli` | o'sha tool'lar aniq xabar bilan `COMMAND_NOT_FOUND` |
|
|
135
|
+
| Playwright brauzerlari | browser pack `npx playwright install --with-deps chromium` kerakligini aytadi |
|
|
136
|
+
| npm build skriptlari (`--ignore-scripts`) | SQLite tool'lari `SQLITE_UNAVAILABLE` va tuzatish buyrug'ini (`npm rebuild better-sqlite3`) aytadi |
|
|
137
|
+
|
|
138
|
+
SQLite uchun **sistem binary kerak emas** — paket ichidagi `better-sqlite3` drayver ishlatiladi (`sqlite3` CLI faqat zaxira). Windows'da npm tool'lari `npm-cli.js` ni `process.execPath` orqali chaqiradi, shuning uchun `npm audit`, `npm outdated` va litsensiya hisoboti u yerda ham ishlaydi.
|
|
139
|
+
|
|
140
|
+
## Dasturlash
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm ci
|
|
144
|
+
npm run check # verify:static → verify:registry → build → test → verify:package → format:check
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **242 ta test** (Vitest): SSRF, redirectlar, permission siyosati, output sandboxi, timeout'lar, har bir tool'ing kiritma shartnomasi va jonli provider-failure xatti-harakati.
|
|
148
|
+
- `verify:registry` haqiqiy registry'ni yuklab **571 tool / 26 kategoriya / barcha 4 profil sonini** tekshiradi.
|
|
149
|
+
- `verify:package` nashr paketida shebang, `files` allowlist va **nol credential/manba fayl** ekanligini isbotlaydi.
|
|
150
|
+
- MCP protokoli o'zi jonli sinovdan o'tkazildi: `initialize`, `tools/list` (571/571 unique, valid schemalar), har bir smart tool uchun `tools/call`, yashirin tool'lar rad etildi, stdout toza JSON-RPC.
|
|
151
|
+
|
|
152
|
+
## Litsenziya
|
|
153
|
+
|
|
154
|
+
[MIT](LICENSE)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
[English version](README.md) · [O'zgarishlar](CHANGELOG.md) · [Hissa qo'shish](CONTRIBUTING.md)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { getCredential } from './credentials.js';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { load } from 'cheerio';
|
|
4
|
+
import { cache } from './cache.js';
|
|
5
|
+
import { fetchUrl } from './fetcher.js';
|
|
6
|
+
import { fetchWithOptions } from './http-client.js';
|
|
7
|
+
import { assertSafeUrl } from './ssrf-guard.js';
|
|
8
|
+
import { result } from './format.js';
|
|
9
|
+
import { parseUpstreamJson } from './json-response.js';
|
|
10
|
+
function str(input, ...keys) {
|
|
11
|
+
for (const key of keys)
|
|
12
|
+
if (typeof input[key] === 'string' && String(input[key]).trim())
|
|
13
|
+
return String(input[key]).trim();
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
function list(input, ...keys) {
|
|
17
|
+
for (const key of keys) {
|
|
18
|
+
const value = input[key];
|
|
19
|
+
if (Array.isArray(value))
|
|
20
|
+
return value;
|
|
21
|
+
if (typeof value === 'string' && value.trim()) {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(value);
|
|
24
|
+
if (Array.isArray(parsed))
|
|
25
|
+
return parsed;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return value.split(/\r?\n/).filter(Boolean);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
function keyFor(name, id) {
|
|
35
|
+
return `monitor:${name}:${createHash('sha256').update(id).digest('hex').slice(0, 24)}`;
|
|
36
|
+
}
|
|
37
|
+
async function fetchSnapshot(url) {
|
|
38
|
+
const safe = await assertSafeUrl(url);
|
|
39
|
+
const response = await fetchWithOptions(safe.toString());
|
|
40
|
+
return { status: response.status, text: response.text, finalUrl: safe.toString() };
|
|
41
|
+
}
|
|
42
|
+
export async function runArchiveMonitoringTool(toolName, input) {
|
|
43
|
+
const name = toolName.replace(/^pro_fetch_/, '');
|
|
44
|
+
const url = str(input, 'url');
|
|
45
|
+
if (name === 'archive_org_fetch' || name === 'google_cache_fetch') {
|
|
46
|
+
if (!url)
|
|
47
|
+
return result('url parametri kerak.');
|
|
48
|
+
await assertSafeUrl(url);
|
|
49
|
+
const archiveUrl = name === 'google_cache_fetch'
|
|
50
|
+
? 'https://webcache.googleusercontent.com/search?q=cache:' + encodeURIComponent(url)
|
|
51
|
+
: 'https://web.archive.org/web/2/' + encodeURIComponent(url);
|
|
52
|
+
try {
|
|
53
|
+
const snapshot = await fetchUrl(archiveUrl);
|
|
54
|
+
if (snapshot.status < 400)
|
|
55
|
+
return result(`# Archived copy\n\nSource: ${url}\nArchive URL: ${snapshot.url}\n\n${snapshot.markdown}`);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* try Wayback fallback below */
|
|
59
|
+
}
|
|
60
|
+
if (name === 'google_cache_fetch') {
|
|
61
|
+
const fallback = await fetchUrl('https://web.archive.org/web/2/' + encodeURIComponent(url));
|
|
62
|
+
return result(`# Wayback fallback (Google cache is unavailable)\n\n${fallback.markdown}`);
|
|
63
|
+
}
|
|
64
|
+
throw new Error('Internet Archive’dan snapshot topilmadi.');
|
|
65
|
+
}
|
|
66
|
+
if (name === 'archive_org_save') {
|
|
67
|
+
if (!url)
|
|
68
|
+
return result('url parametri kerak.');
|
|
69
|
+
const safe = await assertSafeUrl(url);
|
|
70
|
+
const response = await fetchWithOptions('https://web.archive.org/save/' + encodeURIComponent(safe.toString()), {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
timeoutMs: 60000,
|
|
73
|
+
retries: 0,
|
|
74
|
+
});
|
|
75
|
+
if (response.status >= 400)
|
|
76
|
+
throw new Error('Wayback save HTTP ' + response.status + ': ' + response.text.slice(0, 500));
|
|
77
|
+
const archiveUrl = response.headers['content-location'] ??
|
|
78
|
+
response.headers.location ??
|
|
79
|
+
'https://web.archive.org/web/' + encodeURIComponent(safe.toString());
|
|
80
|
+
return result(JSON.stringify({ source: safe.toString(), status: response.status, archiveUrl }, null, 2));
|
|
81
|
+
}
|
|
82
|
+
if (name === 'digest_build') {
|
|
83
|
+
const items = list(input, 'items', 'sources', 'results').map((item) => typeof item === 'string' ? item : JSON.stringify(item));
|
|
84
|
+
const text = str(input, 'text', 'content');
|
|
85
|
+
const body = [...items, ...text.split(/\r?\n/)].filter(Boolean);
|
|
86
|
+
const selected = [...new Set(body)].slice(0, Number(input.limit ?? 30));
|
|
87
|
+
return result(`# Digest${str(input, 'title') ? ': ' + str(input, 'title') : ''}\n\n${selected.map((item) => '- ' + item.slice(0, 1200)).join('\n') || 'Digest uchun items yoki text bering.'}`);
|
|
88
|
+
}
|
|
89
|
+
if (name === 'feed_subscribe' || name === 'jobs_watch' || name === 'keyword_alert' || name === 'price_watch') {
|
|
90
|
+
if (!url)
|
|
91
|
+
return result('url parametri kerak.');
|
|
92
|
+
const fetched = await fetchSnapshot(url);
|
|
93
|
+
const id = str(input, 'id', 'name', 'selector') || url;
|
|
94
|
+
const key = keyFor(name, id);
|
|
95
|
+
let value = fetched.text;
|
|
96
|
+
if (name === 'feed_subscribe') {
|
|
97
|
+
const $ = load(fetched.text, { xmlMode: true });
|
|
98
|
+
value = JSON.stringify($('item,entry')
|
|
99
|
+
.toArray()
|
|
100
|
+
.slice(0, 50)
|
|
101
|
+
.map((item) => ({
|
|
102
|
+
title: $(item).find('title').first().text().trim(),
|
|
103
|
+
link: $(item).find('link').first().attr('href') ?? $(item).find('link').first().text().trim(),
|
|
104
|
+
date: $(item).find('pubDate,published,updated').first().text().trim(),
|
|
105
|
+
})));
|
|
106
|
+
}
|
|
107
|
+
else if (name === 'price_watch') {
|
|
108
|
+
const $ = load(fetched.text);
|
|
109
|
+
const selector = str(input, 'selector');
|
|
110
|
+
const selected = selector ? $(selector).first().text() : fetched.text;
|
|
111
|
+
const match = selected.replace(/,/g, '').match(/-?\d+(?:\.\d+)?/);
|
|
112
|
+
value = match?.[0] ?? '';
|
|
113
|
+
if (!value)
|
|
114
|
+
return result('Narx raqami topilmadi; selector yoki regex bering.');
|
|
115
|
+
}
|
|
116
|
+
else if (name === 'keyword_alert') {
|
|
117
|
+
const keywords = list(input, 'keywords', 'terms').map(String);
|
|
118
|
+
const lower = fetched.text.toLowerCase();
|
|
119
|
+
value = JSON.stringify(keywords.filter((keyword) => lower.includes(keyword.toLowerCase())));
|
|
120
|
+
}
|
|
121
|
+
const previous = cache.get(key)?.value;
|
|
122
|
+
cache.put(key, value, Number(input.ttl_ms ?? 7 * 86_400_000), { url: fetched.finalUrl, status: fetched.status });
|
|
123
|
+
return result(JSON.stringify({
|
|
124
|
+
type: name,
|
|
125
|
+
id,
|
|
126
|
+
url: fetched.finalUrl,
|
|
127
|
+
status: fetched.status,
|
|
128
|
+
changed: previous !== undefined && previous !== value,
|
|
129
|
+
previous: previous?.slice(0, 2000),
|
|
130
|
+
current: value.slice(0, 5000),
|
|
131
|
+
initialized: previous === undefined,
|
|
132
|
+
}, null, 2));
|
|
133
|
+
}
|
|
134
|
+
if (name === 'release_watch') {
|
|
135
|
+
const repository = str(input, 'repository', 'repo') || (url.match(/github\.com\/([^/]+\/[^/]+)/)?.[1] ?? '');
|
|
136
|
+
if (!repository || !repository.includes('/'))
|
|
137
|
+
return result('repository owner/repo yoki GitHub URL kerak.');
|
|
138
|
+
const [owner, repo] = repository.replace(/\.git$/, '').split('/');
|
|
139
|
+
const headers = { accept: 'application/vnd.github+json' };
|
|
140
|
+
if (getCredential('GITHUB_TOKEN'))
|
|
141
|
+
headers.authorization = 'Bearer ' + getCredential('GITHUB_TOKEN');
|
|
142
|
+
const response = await fetchWithOptions(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/latest`, { headers });
|
|
143
|
+
if (response.status >= 400)
|
|
144
|
+
throw new Error('GitHub release API HTTP ' + response.status);
|
|
145
|
+
const release = parseUpstreamJson(response, 'GitHub release API');
|
|
146
|
+
const key = keyFor(name, repository);
|
|
147
|
+
const previous = cache.get(key)?.value;
|
|
148
|
+
cache.put(key, String(release.tag_name ?? ''), Number(input.ttl_ms ?? 7 * 86_400_000));
|
|
149
|
+
return result(JSON.stringify({ repository, ...release, changed: previous !== undefined && previous !== release.tag_name, previous }, null, 2));
|
|
150
|
+
}
|
|
151
|
+
return result('Archive/monitoring operation not recognized: ' + toolName);
|
|
152
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { downloadToBuffer } from './http-client.js';
|
|
2
|
+
import { assertSafeUrl } from './ssrf-guard.js';
|
|
3
|
+
export async function readBinarySource(input, label, defaultMaxBytes = 100 * 1024 * 1024) {
|
|
4
|
+
const maxBytesValue = Number(input.max_bytes ?? defaultMaxBytes);
|
|
5
|
+
const maxBytes = Number.isFinite(maxBytesValue)
|
|
6
|
+
? Math.max(1, Math.min(defaultMaxBytes, Math.floor(maxBytesValue)))
|
|
7
|
+
: defaultMaxBytes;
|
|
8
|
+
const encoded = typeof input.base64 === 'string' ? input.base64 : typeof input.data_base64 === 'string' ? input.data_base64 : '';
|
|
9
|
+
if (encoded) {
|
|
10
|
+
const normalized = encoded.replace(/\s+/g, '');
|
|
11
|
+
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(normalized))
|
|
12
|
+
throw new Error(`${label}: base64 qiymati noto‘g‘ri.`);
|
|
13
|
+
const bytes = Buffer.from(normalized, 'base64');
|
|
14
|
+
if (bytes.byteLength > maxBytes)
|
|
15
|
+
throw new Error(`${label}: fayl max_bytes limitdan katta.`);
|
|
16
|
+
return bytes;
|
|
17
|
+
}
|
|
18
|
+
const rawUrl = typeof input.url === 'string' ? input.url.trim() : '';
|
|
19
|
+
if (!rawUrl)
|
|
20
|
+
throw new Error(`${label}: url yoki base64 kerak.`);
|
|
21
|
+
const safeUrl = await assertSafeUrl(rawUrl);
|
|
22
|
+
return (await downloadToBuffer(safeUrl.toString(), maxBytes, Number(input.timeout_ms ?? 30_000))).bytes;
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Numeric environment parsing with a bounded range.
|
|
3
|
+
*
|
|
4
|
+
* This lives apart from `security-policy.ts` on purpose. `security-policy` needs to read the
|
|
5
|
+
* active profile from `loader.ts`, and `loader.ts` imports every tool index, which imports
|
|
6
|
+
* `core/tool.ts`, which imports `execution-engine.ts` — which needs `boundedEnv`. Keeping
|
|
7
|
+
* `boundedEnv` inside `security-policy` therefore closed an import cycle and made the module
|
|
8
|
+
* evaluate to `undefined` at load time ("boundedEnv is not a function").
|
|
9
|
+
*
|
|
10
|
+
* `boundedEnv` has no dependency on the policy rules, so it belongs in its own leaf module that
|
|
11
|
+
* both `security-policy` and the concurrency gates can import without creating a cycle.
|
|
12
|
+
*/
|
|
13
|
+
/** Read a positive integer from the environment, clamped to `[min, max]`.
|
|
14
|
+
*
|
|
15
|
+
* Returns `fallback` when the variable is unset, non-numeric, zero, or negative — so a typo in
|
|
16
|
+
* `.env` degrades to a safe default instead of disabling a limit.
|
|
17
|
+
*/
|
|
18
|
+
export function boundedEnv(name, fallback, min, max) {
|
|
19
|
+
const parsed = Number(process.env[name]);
|
|
20
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.max(min, Math.min(Math.floor(parsed), max)) : fallback;
|
|
21
|
+
}
|