mcp

fossick as an MCP server for coding agents

Same surface as the Python API / CLI, over stdio (or --http). Tool results are truncated for context limits.

Search & research


source

lookup_doi

def lookup_doi(
    title:str
)->str:

Return the doi.org URL for the first Crossref match on a paper title.


source

research

def research(
    query:str, n:int=5, google:bool=False, region:str='auto', timelimit:str | None=None, sel:str | None=None,
    chars:int=4000
)->dict:

Question -> cited answer: search, read the top n readable* results in parallel (auto-escalating past bot walls, skipping bot-wall/empty pages and backfilling), return {query, sources, digest, dropped, region}. digest is cited markdown, one ## section per source, trimmed to the passages that answer the query and headed with the date the source says it was published. region is a ddgs ‘country-lang’ code, or ‘auto’ to read the country off the query — set it whenever the answer depends on jurisdiction or market. timelimit d|w|m|y keeps only recent sources.*


source

Fetch & crawl


source

crawl_site

def crawl_site(
    url:str, sel:str | None=None, follow_sel:str='a[href]', max_pages:int=10, same_domain:bool=True,
    heavy:bool=False, stealthy:bool=False, max_chars:int=4000
)->list:

Crawl from a start URL following follow_sel links (docs sites, blogs, multi-page content); returns [{url, status, markdown}] per page.


source

fetch_pages

def fetch_pages(
    urls:list, sel:str | None=None, max_chars:int=4000
)->list:

Fetch many known URLs in parallel; returns [{url, status, markdown}] in the same order as urls.


source

fetch_page

def fetch_page(
    url:str, sel:str | None=None, heavy:bool=False, stealthy:bool=False, session:bool=False, auto:bool=False,
    max_chars:int=8000
)->dict:

Fetch a URL as markdown. Always pass sel (CSS selector) to skip nav/ads. heavy=JS rendering; stealthy=anti-bot fetcher; session=reuse the logged-in debug Chrome’s cookies; auto=escalate plain->heavy->stealthy->session (winning tier in result).

Readers


source

pdf_to_notebook

def pdf_to_notebook(
    src:str, path:str | None=None, ocr:str='auto'
)->str:

Convert a PDF (URL or local path) to a notebook — one markdown cell per page. ocr: auto|on|off.


source

url_to_notebook

def url_to_notebook(
    url:str, path:str | None=None
)->str:

Convert a URL (HTML page, PDF, or arXiv paper) to a Jupyter notebook; returns the notebook path.


source

read_github_repo

def read_github_repo(
    url:str, globs:list | None=None, limit:int | None=None, max_chars_per_file:int=8000
)->dict:

Read files from a GitHub repo (URL, SSH address, or local path) filtered by glob patterns (default: README, pyproject.toml, .py). Returns {path: content}.


source

read_github_file

def read_github_file(
    url:str, max_chars:int=20000
)->str:

Read a single file from a GitHub blob URL.


source

download_youtube

def download_youtube(
    url:str, format:str='audio', save_dir:str='.'
)->str:

Download YouTube audio or video. format: audio|video|any yt-dlp format string. Returns the saved file path.


source

search_youtube

def search_youtube(
    query:str, n:int=10
)->list:

Search YouTube; returns [{title, url, channel, duration, description}].


source

read_youtube

def read_youtube(
    url:str, chars:int=20000
)->dict:

YouTube video (URL or ID) -> metadata + full English transcript (in ‘source’).


source

read_arxiv

def read_arxiv(
    url:str, include_source:bool=False, chars:int=8000, save_dir:str='.'
)->dict:

arXiv paper (ID or any arXiv URL) -> {title, authors, published, summary, pdf_path}. include_source adds the full text (30-100k chars total — raise chars only when needed).

Hidden APIs


source

paginate_api

def paginate_api(
    url:str, payload:dict | None=None, page_field:str='pageNumber', size_field:str='pageSize',
    results_field:str | None=None, method:str='POST', max_pages:int=10, page_start:int=1, max_items:int=500
)->list:

Paginate a JSON API, collecting all items across pages. payload is the base body (POST) or params (GET); page_field is the key incremented per page; results_field is auto-detected if None.


source

replay_capture

def replay_capture(
    capture_id:int, data:str | None=None, max_chars:int=8000
)->dict:

Re-issue a captured request (by capture_id from find_hidden_apis/capture_network) as a fast plain-HTTP call, reusing the browser’s cookies. data overrides the request body.


source

find_hidden_apis

def find_hidden_apis(
    url:str, pattern:str='*', session:bool=False, preview_chars:int=500
)->list:

Visit a page with a browser and capture the JSON/XHR API calls it makes (glob/regex pattern filters URLs). session=True captures through the logged-in debug Chrome. Each hit has a capture_id for replay_capture.

Browser & shop


source

capture_network

def capture_network(
    url:str, pattern:str='.*', tail:int=3, port:int=9223, preview_chars:int=300
)->list:

Navigate the debug Chrome to a URL and capture outgoing network requests matching pattern (listens tail seconds after load). Each request gets a capture_id for replay_capture.


source

page_markdown

def page_markdown(
    sel:str | None=None, max_chars:int=8000
)->str:

Read the current page’s live post-JS DOM as markdown, optionally narrowed by a CSS selector.


source

page_act

def page_act(
    steps:list
)->dict:

Run a declarative flow on the current page. Steps (JSON arrays): [‘goto’,url] [‘fill’,label,value] [‘click’,label] [‘select’,label,option] [‘wait’,text] [‘wait_sel’,css] [‘read’,css] or [‘read’,css,label]. Returns {label: markdown} for every read step.


source

page_fill_form

def page_fill_form(
    fields:dict, submit:str | None=None
)->str:

Fill form fields on the current page by visible label ({label: value}; handles