# MediaShare Full Technical Documentation & LLM Agent Ingestion Specification > Complete technical reference, OpenAPI contracts, Model Context Protocol (MCP) tool schemas, and executable SKILL.md documents for autonomous AI agents. ## System Architecture & Overview MediaShare is an independent, API-first ecosystem of specialized microservices designed for autonomous agents, software backends, and developers. Every service is isolated, operates with independent authentication and release cadence, and strictly enforces server-side request forgery (SSRF) defenses. --- ## 1. Services & Live API Endpoints ### wine.mediashare.ro (wine) - **Status**: LIVE - **Category**: data - **Website**: https://wine.mediashare.ro - **Default Endpoint**: https://wine.mediashare.ro/api/wine/search - **OpenAPI 3.0 Contract**: https://wine.mediashare.ro/openapi/direct.json - **Agent Skill URL**: https://wine.mediashare.ro/skills/claude-api #### Sample Request (cURL): ```bash curl -G "https://wine.mediashare.ro/api/wine/search" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json" \ --data-urlencode "q=Purcari Malbec 2020" ``` #### Sample Response (200 OK): ```json { "name": "Malbec", "winery": "Purcari", "year": 2020, "score": 4.3, "reviews": 250, "avg_price": "99.99", "currency": "EUR" } ``` ### geo.mediashare.ro (geo) - **Status**: LIVE - **Category**: utility - **Website**: https://geo.mediashare.ro - **Default Endpoint**: https://geo.mediashare.ro/ - **OpenAPI 3.0 Contract**: https://geo.mediashare.ro/openapi.json - **Agent Skill URL**: https://geo.mediashare.ro/skills/ip-geolocation #### Sample Request (cURL): ```bash curl -X GET "https://geo.mediashare.ro/" \ -H "Accept: application/json" ``` #### Sample Response (200 OK): ```json { "status": "success", "country": "Romania", "countryCode": "RO", "region": "B", "regionName": "Bucharest", "city": "Bucharest", "zip": "050011", "lat": 44.4022, "lon": 26.0624, "timezone": "Europe/Bucharest", "query": "90.84.236.18" } ``` ### ro-finance.mediashare.ro (finance) - **Status**: LIVE - **Category**: market - **Website**: https://ro-finance.mediashare.ro - **Default Endpoint**: https://ro-finance.mediashare.ro/v1/fx-rates - **OpenAPI 3.0 Contract**: https://ro-finance.mediashare.ro/openapi.json - **Agent Skill URL**: https://ro-finance.mediashare.ro/skills/market-reference/SKILL.md #### Sample Request (cURL): ```bash curl -X GET "https://ro-finance.mediashare.ro/v1/fx-rates" \ -H "Accept: application/json" ``` #### Sample Response (200 OK): ```json { "source": "BNR", "observed_at": "2026-03-01T13:00:00Z", "rates": { "EUR": 4.9775, "USD": 4.612, "GBP": 5.823 } } ``` ### meta.mediashare.ro (meta) - **Status**: PROGRESS - **Category**: data - **Default Endpoint**: https://meta.mediashare.ro/v1/extract #### Sample Request (cURL): ```bash curl -X GET "https://meta.mediashare.ro/v1/extract" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"url":"https://example.com/article"}' ``` #### Sample Response (200 OK): ```json { "url": "https://example.com/article", "title": "Example Article", "description": "An example page used for testing.", "language": "en", "author": "Example Team", "published_at": "2024-05-12T10:20:30Z", "text": "Example content extracted from the page..." } ``` ### mock.mediashare.ro (mock) - **Status**: PLANNED - **Category**: developer - **Default Endpoint**: https://mock.mediashare.ro/v1/generate #### Sample Request (cURL): ```bash curl -X GET "https://mock.mediashare.ro/v1/generate?schema=user&count=3&seed=42" \ -H "Accept: application/json" ``` #### Sample Response (200 OK): ```json { "seed": 42, "locale": "ro-RO", "records": [ { "id": "usr_1", "name": "Andrei Popescu", "email": "andrei.popescu@example.ro" }, { "id": "usr_2", "name": "Elena Dumitrescu", "email": "elena.dumitrescu@example.ro" }, { "id": "usr_3", "name": "Radu Ionescu", "email": "radu.ionescu@example.ro" } ] } ``` ### seo.mediashare.ro (seo) - **Status**: PLANNED - **Category**: developer - **Default Endpoint**: https://seo.mediashare.ro/v1/audit #### Sample Request (cURL): ```bash curl -X GET "https://seo.mediashare.ro/v1/audit?url=https%3A%2F%2Fexample.com" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" ``` #### Sample Response (200 OK): ```json { "url": "https://example.com", "status_code": 200, "checks": [ { "id": "title_tag", "passed": true, "evidence": "Example Domain" }, { "id": "canonical_present", "passed": true, "evidence": "https://example.com" }, { "id": "meta_description", "passed": false, "remedy": "Add a concise tag." } ] } ``` --- ## 2. Agent Skills (Executable SKILL.md Documents) ### Skill: vivino-api (wine.mediashare.ro) - **Service ID**: wine - **Description**: Search and fetch wine details, community ratings, review counts, prices, and vintage information from the Vivino API using Claude, Codex, OpenClaw, Hermes, or other AI agents. #### When to Use: Use this skill when you need to query wine information, community ratings, review counts, average prices, and vintage details from the Vivino API in any LLM assistant, coding agent, or autonomous agent workflow (Claude, Codex, OpenClaw, Hermes, Cursor, Windsurf, Pi, etc.). #### Procedure: - **Primary Endpoint:** `GET /api/wine/search?q={query}` - **Authentication:** Bearer token - `Authorization: Bearer {YOUR_API_KEY}` - `Accept: application/json` - **Base URL:** `https://wine.mediashare.ro` - **OpenAPI Schema:** `/openapi/direct.json` #### Pitfalls & Edge Cases: - **Constructing Search Queries:** - Include producer, wine name, and vintage year when known (e.g., `Chateau Margaux 2015`, `Catena Zapata Malbec 2019`). - For general exploration, pass the brand or appellation (e.g., `Tignanello Antinori`). - **Output Shaping for Users:** - Always highlight the wine name, winery, vintage, rating (e.g., `⭐ 4.3/5 based on 250 reviews`), average price if available, and provide the direct Vivino URL for further reading. - **Multi-Agent Setup:** - **Claude**: Upload the skill ZIP via *Customize > Skills* or place in `.claude/skills/`. - **Codex / Hermes / Pi**: Save this file as `SKILL.md` under `~/.agents/skills/vivino-api/SKILL.md`. - **OpenClaw**: Place under `~/.openclaw/skills/vivino-api/SKILL.md` or fetch raw markdown. #### Verification Steps: - HTTP status is 200 OK with valid JSON structure. - Response record contains expected fields matching the query. #### Full Raw SKILL.md Definition: ```markdown --- name: vivino-api description: Search and fetch wine details, community ratings, review counts, prices, and vintage information from the Vivino API using Claude, Codex, OpenClaw, Hermes, or other AI agents. --- # Vivino API Skill for AI Agents (Claude, Codex, OpenClaw, Hermes & more) Use this skill when you need to query wine information, community ratings, review counts, average prices, and vintage details from the Vivino API in any LLM assistant, coding agent, or autonomous agent workflow (Claude, Codex, OpenClaw, Hermes, Cursor, Windsurf, Pi, etc.). ## Base Guidance - **Primary Endpoint:** `GET /api/wine/search?q={query}` - **Authentication:** Bearer token - `Authorization: Bearer {YOUR_API_KEY}` - `Accept: application/json` - **Base URL:** `https://wine.mediashare.ro` - **OpenAPI Schema:** `/openapi/direct.json` ## Example Request ```bash curl -G 'https://wine.mediashare.ro/api/wine/search' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Accept: application/json' \ --data-urlencode 'q=Purcari Malbec 2020' ``` ## Response Fields The API responds with normalized wine information: - `id` (integer) - Internal database identifier - `name` (string) - Wine / cuvée name - `winery` (string) - Producer / winery name - `year` (integer|null) - Vintage year - `score` (float) - Community average score (1.0 - 5.0) - `reviews` (integer) - Total number of community ratings - `url` (string) - Direct Vivino wine webpage - `grapes` (string|null) - Grape varietal(s) - `type` (integer|null) - Wine classification (1: Red, 2: White, 3: Sparkling, 4: Rosé, 7: Dessert, 24: Fortified) - `avg_price` (string|null) - Computed average price - `currency` (string|null) - Currency (e.g. `EUR`, `USD`, `RON`) ## Agent Usage & Best Practices 1. **Constructing Search Queries:** - Include producer, wine name, and vintage year when known (e.g., `Chateau Margaux 2015`, `Catena Zapata Malbec 2019`). - For general exploration, pass the brand or appellation (e.g., `Tignanello Antinori`). 2. **Output Shaping for Users:** - Always highlight the wine name, winery, vintage, rating (e.g., `⭐ 4.3/5 based on 250 reviews`), average price if available, and provide the direct Vivino URL for further reading. 3. **Multi-Agent Setup:** - **Claude**: Upload the skill ZIP via *Customize > Skills* or place in `.claude/skills/`. - **Codex / Hermes / Pi**: Save this file as `SKILL.md` under `~/.agents/skills/vivino-api/SKILL.md`. - **OpenClaw**: Place under `~/.openclaw/skills/vivino-api/SKILL.md` or fetch raw markdown. ``` ### Skill: ip-geolocation (geo.mediashare.ro) - **Service ID**: geo - **Description**: Perform IP geolocation lookups, address geocoding, proxy/threat detection, and Geoname geographic hierarchy queries using the geo.mediashare.ro service. #### When to Use: Use when you need to resolve an IP address to location details, geocode street addresses, detect proxies/VPNs/Tor exit nodes, or query parent/child geoname administrative regions. #### Procedure: - Get Visitor IP Geolocation (GET /): Retrieves geolocation metadata for the caller's IP address. - Advanced Proxy & Threat Detection (GET /proxy) - API Key Required: Performs multi-layered proxy, VPN, Tor, and datacenter threat analysis for an IP address. - Geocode IP or Address (GET /get): Geocodes a specific IP address or physical location/street address. Basic geocoding is free and rate-limited. Pass proxy=1 to enrich the response with proxy detection data (requires an API key). - Geoname Child Hierarchy (GET /children): Fetches administrative or geographic child subdivisions for a given parent Geoname ID. - Linear Distance Calculation (GET /distance): Calculates great-circle linear (Haversine) distance and compass bearing between two locations. - Location Search (GET /search): Performs fast location search to find any location (country, city, county, etc.) and return its details including Geoname ID, feature code description, and coordinates. Supports multiple languages and warm caching. #### Pitfalls & Edge Cases: - **Documentation & Skills**: OpenAPI specification (`/openapi.json`) and agent skills (`/skills/*`) are public resources and are **not rate limited**. - **Free API Access (Keyless)**: Keyless API requests for free endpoints (`/`, `/get`, `/children`, `/distance`, `/search`) are available without an API key and are rate limited to **60 requests per minute** by client IP. Unauthenticated geocoding requests rely on free providers (GeoNames, GeoPlugin, IpInfo, local MaxMind) and never call paid upstream geocoders. - **Protected Features (API Key Required)**: The proxy & threat detection feature (`GET /proxy`, `?proxy=1`, `?check_proxy=1`), extended telecom metadata (`GET /?full=1`), and paid geocoder fallback are **not available without an API key**. Keyless requests to these features return `401 Unauthorized`. - **Private API Access (Bearer Token)**: Send your API key in the `Authorization` header (`Authorization: Bearer `) with `Accept: application/json`. Bearer token requests unlock protected features and receive higher rate limits (default 1000 req/min). - `401 Unauthorized`: Sent when accessing protected features (such as `/proxy` or `?proxy=1`) without an API key, or when an invalid/expired key is provided. - `422 Unprocessable Entity`: Sent when invalid parameters or malformed IP addresses are supplied. - `429 Too Many Requests`: Sent when request rate limits are exceeded (60 req/min for public IP access, custom/1000 req/min for API keys). - `501 Not Implemented`: Sent if external IP lookup fails for `GET /`. #### Verification Steps: - HTTP GET / with header 'Accept: application/json' returns 200 OK with visitor IP geolocation. - HTTP GET /distance returns 200 OK with linear distance calculations and compass bearing. - Protected endpoints (GET /proxy, ?proxy=1) return HTTP 401 Unauthorized without an API key. - Public OpenAPI specification is accessible at https://geo.mediashare.ro/openapi.json. #### Full Raw SKILL.md Definition: ```markdown --- name: ip-geolocation description: Perform IP geolocation lookups, address geocoding, proxy/threat detection, and Geoname geographic hierarchy queries using the geo.mediashare.ro service. Use when you need to resolve an IP address to location details, geocode street addresses, detect proxies/VPNs/Tor exit nodes, or query parent/child geoname administrative regions. --- # IP Geolocation & Geonames Skill This skill provides instructions and examples for interacting with the geo.mediashare.ro API service running at `https://geo.mediashare.ro`. ## Authentication & Rate Limits - **Documentation & Skills**: OpenAPI specification (`/openapi.json`) and agent skills (`/skills/*`) are public resources and are **not rate limited**. - **Free API Access (Keyless)**: Keyless API requests for free endpoints (`/`, `/get`, `/children`, `/distance`, `/search`) are available without an API key and are rate limited to **60 requests per minute** by client IP. Unauthenticated geocoding requests rely on free providers (GeoNames, GeoPlugin, IpInfo, local MaxMind) and never call paid upstream geocoders. - **Protected Features (API Key Required)**: The proxy & threat detection feature (`GET /proxy`, `?proxy=1`, `?check_proxy=1`), extended telecom metadata (`GET /?full=1`), and paid geocoder fallback are **not available without an API key**. Keyless requests to these features return `401 Unauthorized`. - **Private API Access (Bearer Token)**: Send your API key in the `Authorization` header (`Authorization: Bearer `) with `Accept: application/json`. Bearer token requests unlock protected features and receive higher rate limits (default 1000 req/min). ### Requesting an API Key Need an API key for proxy detection, extended telecom intelligence, or higher rate limits? Submit a request via the contact form at: `https://geo.mediashare.ro/contact` ```bash # Public keyless request (free endpoints) curl -H "Accept: application/json" https://geo.mediashare.ro/ # Authenticated Bearer request (unlocks proxy detection & high rate limits) curl -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" https://geo.mediashare.ro/proxy?ip=8.8.8.8 ``` ## Endpoints & Usage ### 1. Get Visitor IP Geolocation (`GET /`) Retrieves geolocation metadata for the caller's IP address. **Request:** ```bash curl -s -H "Accept: application/json" https://geo.mediashare.ro/ ``` **Response Example (`200 OK`):** ```json { "status": "success", "country": "Romania", "countryCode": "RO", "region": "B", "regionName": "Bucharest", "city": "Bucharest", "zip": "010001", "lat": 44.4323, "lon": 26.1063, "timezone": "Europe/Bucharest", "isp": "Example ISP", "org": "Example Org", "as": "AS12345 Example", "query": "1.2.3.4" } ``` --- ### 2. Advanced Proxy & Threat Detection (`GET /proxy`) - *API Key Required* Performs multi-layered proxy, VPN, Tor, and datacenter threat analysis for an IP address. > **Note:** The proxy detection feature requires a valid API key. Keyless requests will return `401 Unauthorized`. If you need an API key, please request one using the contact form at `https://geo.mediashare.ro/contact`. **Parameters:** - `ip` *(optional)*: IP address string to analyze (defaults to caller's IP if omitted). **Request (Authenticated):** ```bash # Analyze a specific IP address with Bearer token curl -s -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" "https://geo.mediashare.ro/proxy?ip=8.8.8.8" # Analyze caller's IP address with Bearer token curl -s -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" "https://geo.mediashare.ro/proxy" ``` **Response Example (`200 OK`):** ```json { "ip": "8.8.8.8", "is_proxy": true, "is_vpn": false, "is_tor": false, "is_datacenter": true, "is_public_proxy": false, "is_residential_proxy": false, "is_relay": false, "is_crawler": false, "proxy_type": "datacenter", "risk_score": 60, "threat_level": "medium", "confidence": 0.85, "details": { "asn": 15169, "as_org": "Google LLC", "isp": "Google LLC", "country_code": "US", "datacenter_provider": "Google Cloud", "crawler_name": null, "matched_detectors": [ "known_datacenter_heuristic" ], "detected_headers": {}, "cached": false } } ``` --- ### 3. Geocode IP or Address (`GET /get`) Geocodes a specific IP address or physical location/street address. Basic geocoding is free and rate-limited. Pass `proxy=1` to enrich the response with proxy detection data (*requires an API key*). **Parameters:** - `ip` *(optional)*: IP address string to geocode (defaults to client IP if omitted). - `addr` *(optional)*: Street address or location string to geocode (takes precedence over `ip`). - `proxy` *(optional)*: Set to `1` or `true` to attach proxy intelligence (*requires API key; returns 401 if keyless*). **Examples:** ```bash # Free: Geocode an IP address (keyless) curl -s "https://geo.mediashare.ro/get?ip=8.8.8.8" # Free: Geocode a physical address (keyless, uses free GeoNames/GeoPlugin providers) curl -s "https://geo.mediashare.ro/get?addr=Mountain+View,+CA" # Protected: Geocode with attached proxy intelligence (requires API key) curl -s -H "Authorization: Bearer YOUR_API_KEY" -H "Accept: application/json" "https://geo.mediashare.ro/get?ip=8.8.8.8&proxy=1" ``` **Response Example (`200 OK`):** ```json { "city": "Mountain View", "county": "Santa Clara County", "country": "United States", "country_code": "US", "is_eu": false, "isEu": false, "languages": [ "en-US", "es-US", "haw", "fr" ], "latitude": 37.3860, "longitude": -122.0838 } ``` --- ### 4. Geoname Child Hierarchy (`GET /children`) Fetches administrative or geographic child subdivisions for a given parent Geoname ID. **Parameters:** - `id` *(optional, default: `6255149`)*: Geoname ID (e.g. Earth parent ID `6255149`, continent IDs, country IDs, or administrative divisions). - `lang` *(optional, default: `"en"`)*: Two-letter language code. **Examples:** ```bash # List top-level geographic regions (default parent: Earth 6255149) curl -s "https://geo.mediashare.ro/children?id=6255149&lang=en" ``` **Response Example (`200 OK`):** ```json [ { "name": "Europe", "geonameId": 6255148, "fcodeName": "continent", "latitude": 48.69, "longitude": 9.14 } ] ``` --- ### 5. Linear Distance Calculation (`GET /distance`) Calculates great-circle linear (Haversine) distance and compass bearing between two locations. **Parameters:** - `from` / `origin` *(optional)*: Origin location (coordinates `"lat,lng"`, IP address, or address string). Defaults to caller's IP address. - `to` / `destination` *(required)*: Destination location (coordinates `"lat,lng"`, IP address, or address string). **Examples:** ```bash # Calculate distance between coordinate pairs curl -s "https://geo.mediashare.ro/distance?from=44.4323,26.1063&to=45.6579,25.6012" # Calculate distance from caller IP to an address curl -s "https://geo.mediashare.ro/distance?to=Brasov,+Romania" ``` **Response Example (`200 OK`):** ```json { "status": "success", "method": "haversine_great_circle", "origin": { "query": "44.4323,26.1063", "resolved": "44.4323, 26.1063", "latitude": 44.4323, "longitude": 26.1063 }, "destination": { "query": "45.6579,25.6012", "resolved": "45.6579, 25.6012", "latitude": 45.6579, "longitude": 25.6012 }, "distance": { "kilometers": 141.28, "miles": 87.79, "meters": 141280.0, "feet": 463517.0, "nautical_miles": 76.28 }, "bearing_degrees": 341.2 } ``` ### 6. Location Search (`GET /search`) Performs fast location search to find any location (country, city, county, etc.) and return its details including Geoname ID, feature code description, and coordinates. Supports multiple languages and warm caching. **Parameters:** - `q` *(required)*: Location name, country code, or query string (e.g. `Romania`, `Paris`, `RO`). - `lang` *(optional, default: `"en"`)*: Two-letter language code for localized results (e.g. `en`, `ro`, `de`, `fr`). - `all` *(optional, default: `false`)*: Set to `1` or `true` to return an array of multiple matching locations. - `limit` *(optional, default: `10`)*: Maximum number of results when `all=1`. **Examples:** ```bash # Search for a country curl -s "https://geo.mediashare.ro/search?q=Romania&lang=en" # Localized search curl -s "https://geo.mediashare.ro/search?q=Romania&lang=ro" # Search for a city curl -s "https://geo.mediashare.ro/search?q=Paris&lang=en" ``` **Response Example (`200 OK`):** ```json { "name": "Romania", "geonameId": 798549, "fcodeName": "independent political entity", "latitude": 46, "longitude": 25 } ``` --- ## Error Handling - `401 Unauthorized`: Sent when accessing protected features (such as `/proxy` or `?proxy=1`) without an API key, or when an invalid/expired key is provided. ```json { "error": "Unauthorized", "message": "An API key is required to access the proxy detection feature." } ``` *(To request an API key, use the contact form at `https://geo.mediashare.ro/contact`.)* - `422 Unprocessable Entity`: Sent when invalid parameters or malformed IP addresses are supplied. - `429 Too Many Requests`: Sent when request rate limits are exceeded (60 req/min for public IP access, custom/1000 req/min for API keys). - `501 Not Implemented`: Sent if external IP lookup fails for `GET /`. ## OpenAPI Specification The complete OpenAPI 3.0 specification for this API is available at: `https://geo.mediashare.ro/openapi.json` ``` ### Skill: romanian-finance (ro-finance.mediashare.ro) - **Service ID**: finance - **Description**: Query BNR official exchange rates and mutual-fund reference data. #### When to Use: Use when an agent requires official Romanian National Bank (BNR) FX rates, reference currency multipliers, or mutual-fund NAVs. #### Procedure: - Call GET https://ro-finance.mediashare.ro/v1/fx-rates with Accept: application/json. - For a specific currency history, request /v1/fx-rates/{currency}/history?from=YYYY-MM-DD. - Verify the source field ('BNR') and the observed_at ISO timestamp. - Calculate conversions using the explicit ron_per_unit multiplier without rounding. #### Pitfalls & Edge Cases: - BNR rates are reference rates published once per business day around 13:00 EET; they are not live tradable market quotes. - Do not execute trades or provide financial advice based on reference snapshot feeds. #### Verification Steps: - Response contains observed_at timestamp and rates map with EUR, USD, GBP values. - Source attribution is explicitly marked as 'BNR'. #### Full Raw SKILL.md Definition: ```markdown # Romanian Finance Skill ## When to Use Use when an agent requires official Romanian National Bank (BNR) FX rates, reference currency multipliers, or mutual-fund NAVs. ## Procedure 1. Call GET https://ro-finance.mediashare.ro/v1/fx-rates with Accept: application/json. 2. For a specific currency history, request /v1/fx-rates/{currency}/history?from=YYYY-MM-DD. 3. Verify the source field ('BNR') and the observed_at ISO timestamp. 4. Calculate conversions using the explicit ron_per_unit multiplier without rounding. ## Pitfalls - BNR rates are reference rates published once per business day around 13:00 EET; they are not live tradable market quotes. - Do not execute trades or provide financial advice based on reference snapshot feeds. ## Verification - Response contains observed_at timestamp and rates map with EUR, USD, GBP values. - Source attribution is explicitly marked as 'BNR'. ``` ### Skill: url-metadata (meta.mediashare.ro) - **Service ID**: meta - **Description**: Safely extract OpenGraph tags, article text, and web page metadata. #### When to Use: Use when an agent needs to inspect a web URL, extract article title, description, author, publication date, and OpenGraph tags safely. #### Procedure: - Validate that the target URL uses http:// or https:// schemes. - Send POST or GET to https://meta.mediashare.ro/v1/extract with target URL and Bearer token. - Check the response for title, description, og:image, and clean markdown text extraction. - Inspect the provenance metadata for cache freshness and extraction timestamp. #### Pitfalls & Edge Cases: - Internal, private (RFC 1918), loopback, and cloud metadata URLs are blocked by SSRF defense layers. - Responses exceeding maximum content length (e.g. 5MB) will be truncated. #### Verification Steps: - Response contains valid extracted title and canonical URL. - Provenance object confirms HTTP fetch status and extraction timestamp. #### Full Raw SKILL.md Definition: ```markdown # URL Metadata Skill ## When to Use Use when an agent needs to inspect a web URL, extract article title, description, author, publication date, and OpenGraph tags safely. ## Procedure 1. Validate that the target URL uses http:// or https:// schemes. 2. Send POST or GET to https://meta.mediashare.ro/v1/extract with target URL and Bearer token. 3. Check the response for title, description, og:image, and clean markdown text extraction. 4. Inspect the provenance metadata for cache freshness and extraction timestamp. ## Pitfalls - Internal, private (RFC 1918), loopback, and cloud metadata URLs are blocked by SSRF defense layers. - Responses exceeding maximum content length will be truncated. ## Verification - Response contains valid extracted title and canonical URL. - Provenance object confirms HTTP fetch status and extraction timestamp. ``` --- ## 3. Model Context Protocol (MCP) Server Registry ### Wine Search MCP (`@mediashare/mcp-wine`) - **Domain**: wine.mediashare.ro - **Description**: Search and resolve wine metadata, ratings, wineries, and vintage pricing. - **Installation**: `npx -y @mediashare/mcp-wine` - **Environment Variables**: - `MEDIASHARE_WINE_API_KEY` (Required): Bearer API key for wine search service #### Tools Exposed: ##### `wine_search` Search the wine database by natural-language query and optional vintage. Parameters: - `q` (string, required): Wine title, winery, or natural query (e.g. 'Purcari Malbec 2020') - `vintage` (number, optional): Specific harvest year Returns: Wine object with winery, year, rating score, reviews, and average price ### IP Geolocation MCP (`@mediashare/mcp-geo`) - **Domain**: geo.mediashare.ro - **Description**: IP address geolocation, geocoding, proxy & threat intelligence, distance calculation, and Geonames hierarchy. - **Installation**: `npx -y @mediashare/mcp-geo` - **Environment Variables**: - `MEDIASHARE_GEO_API_KEY` (Optional): Bearer API key to unlock proxy/threat detection and higher rate limits #### Tools Exposed: ##### `geo_lookup` Resolve caller IP or targeted IP address to geographic location, coordinates, timezone, and network ASN details. Parameters: - `addr` (string, optional): IP address or location to lookup. If omitted, resolves caller's client IP. Returns: Location record with IP, country ISO code, region, city, coordinates, timezone, and ASN network details ##### `geo_proxy_check` Analyze IP address for proxy, VPN, Tor, and datacenter threat intelligence (requires API key). Parameters: - `ip` (string, optional): Target IP address to analyze (defaults to caller IP if omitted) Returns: Threat intelligence record with is_proxy, is_vpn, is_tor, risk_score, and threat_level ##### `geo_distance` Calculate great-circle linear (Haversine) distance and compass bearing between two locations. Parameters: - `from` (string, optional): Origin location (coordinates 'lat,lng', IP, or address string; defaults to caller IP) - `to` (string, required): Destination location (coordinates 'lat,lng', IP, or address string) Returns: Distance breakdown in kilometers, miles, meters, and compass bearing degrees ### Romanian Market Data MCP (`@mediashare/mcp-finance`) - **Domain**: ro-finance.mediashare.ro - **Description**: BNR official currency exchange rates, mutual fund NAVs, and bond references. - **Installation**: `npx -y @mediashare/mcp-finance` #### Tools Exposed: ##### `finance_fx_rates` Get National Bank of Romania (BNR) daily exchange rates. Parameters: - `currency` (string, optional): 3-letter currency code (e.g. 'EUR', 'USD') - `date` (string, optional): ISO date format (YYYY-MM-DD) for historical lookup Returns: Observed rates with multiplier, source attribution, and freshness timestamp ### URL Metadata MCP (`@mediashare/mcp-meta`) - **Domain**: meta.mediashare.ro - **Description**: Safely extract OpenGraph tags, title, description, and structured text from URLs. - **Installation**: `npx -y @mediashare/mcp-meta` - **Environment Variables**: - `MEDIASHARE_META_API_KEY` (Required): Bearer API key for URL extraction #### Tools Exposed: ##### `meta_extract` Fetch a public URL and extract its OpenGraph tags and article content safely. Parameters: - `url` (string, required): Public web URL to inspect - `include_content` (boolean, optional): Whether to return readable article text Returns: Structured metadata payload with title, description, author, and OpenGraph tags ### Client Configuration Snippets #### claudeDesktop Config file: `claude_desktop_config.json` ```json { "mcpServers": { "mediashare-wine": { "command": "npx", "args": ["-y", "@mediashare/mcp-wine"], "env": { "MEDIASHARE_WINE_API_KEY": "YOUR_API_KEY" } }, "mediashare-geo": { "command": "npx", "args": ["-y", "@mediashare/mcp-geo"] }, "mediashare-finance": { "command": "npx", "args": ["-y", "@mediashare/mcp-finance"] } } } ``` #### cursor Config file: `.cursor/mcp.json` ```json { "mcpServers": { "mediashare": { "command": "npx", "args": ["-y", "@mediashare/mcp-wine"], "env": { "MEDIASHARE_WINE_API_KEY": "${env:MEDIASHARE_WINE_API_KEY}" } } } } ``` #### pi Config file: `settings.json` ```json { "mcp": { "servers": { "mediashare-wine": { "command": "npx", "args": ["-y", "@mediashare/mcp-wine"], "env": { "MEDIASHARE_WINE_API_KEY": "YOUR_API_KEY" } }, "mediashare-geo": { "command": "npx", "args": ["-y", "@mediashare/mcp-geo"] } } } } ``` --- ## 4. Architecture & Security Baseline ### Getting Started Connect to MediaShare services in three steps via REST, MCP, or Agent Skills. #### 1. Three ways to connect MediaShare is designed around an API-first philosophy. Every service is an independent HTTP API, wrapped by a thin Model Context Protocol (MCP) server and documented with an agent-ready skill. You choose how to integrate depending on your architecture: ```text Direct HTTP API ──> For backend microservices, scripts, and applications MCP Server ──> For AI agent platforms (Claude Desktop, Cursor, Pi, Codex) Agent Skill ──> For prompt engineering and procedural workflow instructions ``` #### 2. Making your first HTTP request Services with public tiers (such as IP Geolocation) can be called directly without credentials. Authenticated services require a Bearer token in the standard Authorization header. ```bash # Public lookup example curl -X GET "https://geo.mediashare.ro/" \ -H "Accept: application/json" # Authenticated service example curl -G "https://wine.mediashare.ro/api/wine/search" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json" \ --data-urlencode "q=Purcari Malbec 2020" ``` ### Architecture & Principles Core architectural decisions and operating constraints across all MediaShare services. #### Independent product boundaries Each subdomain (wine.mediashare.ro, geo.mediashare.ro, etc.) is a distinct product boundary with its own runtime, monitoring, and release cadence. We do not route traffic through a monolithic API gateway, ensuring zero single point of failure and allowing each service to evolve independently. #### OpenAPI 3.1 is canonical Every service ships an OpenAPI 3.1 specification before implementation. The HTTP contract is canonical; MCP wrappers and skills are thin translation layers that never duplicate or modify business logic. > **undefined**: OpenAPI specifications are hosted at /openapi.json on each service domain. #### Deterministic & low maintenance We prioritize deterministic transformations, scheduled snapshot refreshes (e.g. daily BNR market feeds), and cached responses over editorial workflows that require routine human curation. ### Authentication & Quotas API keys, headers, and rate limiting policies. #### API Key Authentication Pass your API key as a Bearer token in the HTTP Authorization header. > **undefined**: Never commit API keys into version control or expose them in client-side frontends. ```http GET /v1/extract HTTP/1.1 Host: meta.mediashare.ro Authorization: Bearer ms_live_xxxxxxxxxxxxxxxxxxxx Accept: application/json ``` #### Standard Response Headers All API responses include standard tracing and rate-limiting metadata headers: ```text X-Request-Id: Unique UUID for distributed request tracing RateLimit-Limit: Maximum allowed requests in the current window RateLimit-Remaining: Number of available requests remaining RateLimit-Reset: Unix timestamp when the rate limit window resets ``` ### Security & SSRF Baseline Defenses, bounded fetching, and privacy policies for data-fetching services. #### SSRF Protection Layer Services that fetch external URLs (such as meta.mediashare.ro and seo.mediashare.ro) enforce rigorous Server-Side Request Forgery (SSRF) defenses: 1. Pre-DNS resolution checks: Reject private schemes (file://, gopher://), non-standard ports, and localhost hostnames. 2. Post-DNS resolution validation: Resolve all IP addresses and verify they do not fall within RFC 1918 private ranges, loopback (127.0.0.0/8), link-local (169.254.0.0/16), or cloud metadata networks (169.254.169.254). 3. Strict timeouts (max 5s) and bounded response sizes (max 5MB) to protect against memory exhaustion and slow-loris attacks. #### Data Privacy & Minimal Logging MediaShare services log only operational telemetry (request ID, HTTP status code, latency, error classification). We do not record or retain user-submitted payloads or extracted document content by default.