{"apiVersion":"v1","directorySlug":"phillyinkz-mcp-c72af2f05f","title":"PhillyInkz","description":"Tattoo shop in Ocala, FL. Walk-ins welcome at PhillyInkz — custom realism, fine line, black & grey and cover-ups. Free consultations, book online.","pageUrl":"https://www.mcpbundles.com/skills/phillyinkz-mcp-c72af2f05f","connectPath":"importable","connectAction":"import_server","catalogListing":false,"bundleSlug":null,"listingKind":"remote_mcp","kind":"provider","transportUrl":"https://phillyinkz.com/api/mcp","hostedMcpUrl":null,"toolCount":47,"toolInventoryStatus":"observed","refreshedAt":"2026-11-03T13:26:00.516172+00:00","registryName":"com.phillyinkz/phillyinkz-mcp-c72af2f05f","registryVersion":"2026.11.3","registryEligible":true,"tools":[{"name":"get_artists","description":"Get information about tattoo artists at PhillyInkz. Returns profiles including bio, specialty, experience, services, schedule, social links, email, and phone number for SMS/email alerts.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"artistId":{"type":"string"}}},"logicalName":"get_artists","displayName":"get_artists","title":"get_artists","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_public_artists","description":"Get a public, client-safe directory of active tattoo artists at PhillyInkz. Returns each artist's avatar image, portfolio image links, specialty, experience, bio, whether they are a guest artist, their social links, and a public profile/portfolio page link. Guest artists have their personal contact/social channels hidden. Does NOT include private contact info (no email/phone) — use get_artists for admin contact details.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"artistId":{"type":"string"}}},"logicalName":"get_public_artists","displayName":"get_public_artists","title":"get_public_artists","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"check_availability","description":"Check available booking time slots for a tattoo artist. Can check a specific date (returns time slots) or an entire month (returns available days with slots). Considers existing appointments, blocked slots, and artist schedule. Cancelled appointments do NOT block time slots.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"date":{"type":"string"},"month":{"type":"string"},"artistId":{"type":"string"},"duration":{"type":"number"},"serviceName":{"type":"string"},"overrideHours":{"type":"boolean"}}},"logicalName":"check_availability","displayName":"check_availability","title":"check_availability","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"book_appointment","description":"Book a tattoo appointment with an artist. Creates the booking, calculates deposit, sends notifications. If the client does not have an account, one is created automatically with a temp password and welcome email. Deposit can be skipped or set to a custom amount if already paid. When clientEmail is omitted, the tool attempts to find the client by full name; if no match or multiple matches are found, it returns an error asking for more info.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["clientName","date","time","duration","skipDeposit","depositPaid"],"properties":{"date":{"type":"string"},"size":{"type":"string"},"time":{"type":"string"},"notes":{"type":"string"},"price":{"type":"number"},"artistId":{"type":"string"},"duration":{"type":"number"},"clientName":{"type":"string"},"clientEmail":{"type":"string","pattern":"^[A-Za-z0-9_'+\\-.]{1,64}@[A-Za-z0-9\\-.]{1,253}\\.[A-Za-z]{2,24}$"},"clientPhone":{"type":"string"},"depositPaid":{"type":"boolean"},"serviceName":{"type":"string"},"skipDeposit":{"type":"boolean"},"bodyPlacement":{"type":"string"},"depositAmount":{"type":"number"},"overrideHours":{"type":"boolean"},"tattooDetails":{"type":"string"},"referenceImageUrl":{"type":"string"}}},"logicalName":"book_appointment","displayName":"book_appointment","title":"book_appointment","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_appointments","description":"Get appointment details by ID, or list upcoming appointments filtered by client email, artist, or status.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"status":{"type":"string"},"artistId":{"type":"string"},"clientEmail":{"type":"string"},"appointmentId":{"type":"string"}}},"logicalName":"get_appointments","displayName":"get_appointments","title":"get_appointments","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_services","description":"Get available tattoo services. Can be filtered by artist or category (CUSTOM_TATTOO, FLASH_TATTOO, COVER_UP, TOUCH_UP, CONSULTATION, PIERCING, REMOVAL_CONSULTATION, TAPOUT_SESSION, FLASH_DEALS).","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"artistId":{"type":"string"},"category":{"type":"string"}}},"logicalName":"get_services","displayName":"get_services","title":"get_services","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_studio_info","description":"Get public information about the PhillyInkz studio including location, business hours, contact info, policies, payment methods, and branding.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{}},"logicalName":"get_studio_info","displayName":"get_studio_info","title":"get_studio_info","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"send_sms","description":"Send an SMS text message to a phone number. Uses the studio's configured SMS provider (Twilio or Textbelt). Include country code in phone number.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["phone","message"],"properties":{"phone":{"type":"string"},"message":{"type":"string"}}},"logicalName":"send_sms","displayName":"send_sms","title":"send_sms","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"send_email","description":"Send an email to a recipient. Can be used for alerts, reminders, or custom messages. Uses the studio's configured email provider.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["to","subject","message"],"properties":{"to":{"type":"string","pattern":"^[A-Za-z0-9_'+\\-.]{1,64}@[A-Za-z0-9\\-.]{1,253}\\.[A-Za-z]{2,24}$"},"html":{"type":"string"},"message":{"type":"string"},"subject":{"type":"string"}}},"logicalName":"send_email","displayName":"send_email","title":"send_email","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"mass_email_clients","description":"Send the same email to many clients one-by-one (no CC/BCC so recipients cannot see each other). Provide subject and body (message and/or html). Target by: artist (artistId or artistName — partial/substring match supported, e.g. \"philly\" finds \"Philly\"), data source (appointments, waivers, or both), minAppointments, minSpend, or explicit emails list. This tool may take a while for large recipient lists — it sends each email individually and returns results when done. Respects marketing opt-in by","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["subject","message"],"properties":{"html":{"type":"string"},"emails":{"type":"array","items":{"type":"string","pattern":"^[A-Za-z0-9_'+\\-.]{1,64}@[A-Za-z0-9\\-.]{1,253}\\.[A-Za-z]{2,24}$"}},"source":{"enum":["appointments","waivers","both"],"type":"string"},"message":{"type":"string"},"subject":{"type":"string"},"artistId":{"type":"string"},"minSpend":{"type":"number","minimum":0},"artistName":{"type":"string"},"skipDuplicates":{"type":"boolean"},"minAppointments":{"type":"integer","maximum":9007199254740991,"minimum":0},"respectMarketingOptIn":{"type":"boolean"}}},"logicalName":"mass_email_clients","displayName":"mass_email_clients","title":"mass_email_clients","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"mass_sms_clients","description":"Send the same SMS text message to many clients one-by-one. Target by: artist (artistId or artistName — partial/substring match supported, e.g. \"philly\" finds \"Philly\"), data source (appointments, waivers, or both), minAppointments, minSpend, or explicit phones list. This tool may take a while for large recipient lists — it sends each SMS individually and returns results when done. SMS consent is NOT enforced by default (most walk-in clients won't have a consent record). DUPLICATE PROTECTION: By","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["message"],"properties":{"phones":{"type":"array","items":{"type":"string"}},"source":{"enum":["appointments","waivers","both"],"type":"string"},"message":{"type":"string"},"artistId":{"type":"string"},"minSpend":{"type":"number","minimum":0},"artistName":{"type":"string"},"skipDuplicates":{"type":"boolean"},"minAppointments":{"type":"integer","maximum":9007199254740991,"minimum":0},"respectSmsConsent":{"type":"boolean"}}},"logicalName":"mass_sms_clients","displayName":"mass_sms_clients","title":"mass_sms_clients","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"send_appointment_reminder","description":"Send a reminder notification for an upcoming appointment. Sends via the unified notification system (WebSocket + Email) and SMS if the client has a phone number on file.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["appointmentId"],"properties":{"appointmentId":{"type":"string"},"customMessage":{"type":"string"}}},"logicalName":"send_appointment_reminder","displayName":"send_appointment_reminder","title":"send_appointment_reminder","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"manage_appointment_status","description":"Update the status of an existing appointment. Handles transitions like PENDING → CONFIRMED → DEPOSIT_PAID → IN_PROGRESS → COMPLETED, or CANCELLED/NO_SHOW. Updates timestamps and sends notifications to all parties.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["appointmentId","status"],"properties":{"notes":{"type":"string"},"status":{"type":"string"},"cancelReason":{"type":"string"},"appointmentId":{"type":"string"}}},"logicalName":"manage_appointment_status","displayName":"manage_appointment_status","title":"manage_appointment_status","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_artist_stats","description":"Get comprehensive statistics for an artist including appointment counts, revenue, reviews, popular services, and upcoming schedule. Look up by artist ID or name.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"artistId":{"type":"string"},"artistName":{"type":"string"}}},"logicalName":"get_artist_stats","displayName":"get_artist_stats","title":"get_artist_stats","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_artist_appointments","description":"Get detailed appointment list for an artist. Look up by artist ID or name. Optionally filter by status or upcoming only. Returns full appointment details including client info, pricing, and tattoo details.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"status":{"type":"string"},"artistId":{"type":"string"},"upcoming":{"type":"boolean"},"artistName":{"type":"string"}}},"logicalName":"get_artist_appointments","displayName":"get_artist_appointments","title":"get_artist_appointments","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_member_appointments","description":"Get appointment details for a client/member. Search by email, name, or phone. Returns member account info and full appointment history with artist details and pricing.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"status":{"type":"string"},"upcoming":{"type":"boolean"},"clientName":{"type":"string"},"clientEmail":{"type":"string"},"clientPhone":{"type":"string"}}},"logicalName":"get_member_appointments","displayName":"get_member_appointments","title":"get_member_appointments","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"search_waivers","description":"Search waiver forms by customer name, email, phone, or artist name. Returns detailed waiver records including tattoo description, placement, size, payment info, medical history, emergency contacts, and linked appointments. Useful for looking up past tattoo sessions and client history.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"signed":{"type":"boolean"},"artistName":{"type":"string"},"clientName":{"type":"string"},"clientEmail":{"type":"string"},"clientPhone":{"type":"string"}}},"logicalName":"search_waivers","displayName":"search_waivers","title":"search_waivers","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_unsigned_artist_waivers","description":"List one artist’s client-signed waivers that have no artist signature yet — the set an admin could bulk-apply the artist’s existing signature to, with the artist’s authorization. Read-only: this tool cannot apply signatures.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["artistName"],"properties":{"to":{"type":"string"},"from":{"type":"string"},"limit":{"type":"number"},"artistName":{"type":"string"}}},"logicalName":"list_unsigned_artist_waivers","displayName":"list_unsigned_artist_waivers","title":"list_unsigned_artist_waivers","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_incomplete_waivers","description":"List client-signed waivers that would NOT pass a Florida 64E-28.009 inspection, with exactly what each lacks (artist signature, procedure date, ID/age verification, notarised consent for 16–17s, etc.). Optionally for one artist and a number of days back (default 365). Read-only.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"days":{"type":"number"},"limit":{"type":"number"},"artistName":{"type":"string"}}},"logicalName":"list_incomplete_waivers","displayName":"list_incomplete_waivers","title":"list_incomplete_waivers","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"email_waiver_records","description":"Email the most recent waiver records as ONE printable PDF, for a named artist or for all artists. Each waiver is followed by the notarised parental consent that authorised it where one is on file. Built for a health inspection: ask for \"the last 5 waivers for Nora\" and the packet arrives in the inbox ready to print. The cover names anything missing — waivers with no artist signature, clients under 18 at signing with no consent attached, and consents staff have not accepted.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"toEmail":{"type":"string","pattern":"^[A-Za-z0-9_'+\\-.]{1,64}@[A-Za-z0-9\\-.]{1,253}\\.[A-Za-z]{2,24}$"},"artistName":{"type":"string"},"includeUnapproved":{"type":"boolean"},"requireArtistSigned":{"type":"boolean"}}},"logicalName":"email_waiver_records","displayName":"email_waiver_records","title":"email_waiver_records","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"update_waiver_status","description":"Update waiver verification status by artist name. Can mark waivers as verified, signed, ID verified, or age verified. Finds the waiver by ID, client name, or client email. Logs all changes in the audit trail.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["artistName"],"properties":{"notes":{"type":"string"},"isSigned":{"type":"boolean"},"waiverId":{"type":"string"},"artistName":{"type":"string"},"clientName":{"type":"string"},"idVerified":{"type":"boolean"},"isVerified":{"type":"boolean"},"ageVerified":{"type":"boolean"},"clientEmail":{"type":"string"}}},"logicalName":"update_waiver_status","displayName":"update_waiver_status","title":"update_waiver_status","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_customer_stats","description":"Get comprehensive stats for a customer/client. Search by name, email, or phone. Returns profile info, appointment history with status breakdown, all artists who tattooed them (with counts), tattoo history from waivers (descriptions, placements, sizes), financial summary (spend, invoices, outstanding balance), reviews, medical flags, and upcoming appointments.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"clientName":{"type":"string"},"clientEmail":{"type":"string"},"clientPhone":{"type":"string"}}},"logicalName":"get_customer_stats","displayName":"get_customer_stats","title":"get_customer_stats","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_upcoming_events","description":"Get upcoming events, flash sales, active deals, and giveaway campaigns for PhillyInkz. Returns events (flash days, guest artists, conventions, workshops), active Deal-or-No-Deal listings, and running giveaway campaigns with code availability stats.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"daysAhead":{"type":"number"},"eventType":{"type":"string"},"includeDeals":{"type":"boolean"},"includeGiveaways":{"type":"boolean"}}},"logicalName":"get_upcoming_events","displayName":"get_upcoming_events","title":"get_upcoming_events","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_artist_earnings","description":"Get how much an artist has earned in a time period by summing prices from signed waivers. Returns total earnings, breakdown by estimated price / deposits / additional cash / touchup charges, and a per-waiver row. Look up by artistId or artistName (partial match). startDate and endDate are optional YYYY-MM-DD filters.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"period":{"enum":["today","this_week","last_week","week","this_month","last_month","month","this_year","last_year","year"],"type":"string"},"endDate":{"type":"string"},"artistId":{"type":"string"},"startDate":{"type":"string"},"artistName":{"type":"string"}}},"logicalName":"get_artist_earnings","displayName":"get_artist_earnings","title":"get_artist_earnings","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_artists","description":"List artists on the compliance roster with a freshly computed work-authorization verdict on every row. Filter by name (q), studioId, employmentStatus, state, complianceStatus, authStatus, missingCategory, expiringWithinDays and paymentStatus. Paginated. Compliance, authorization and missing-credential filters are computed per artist, so those responses may come back with truncated:true — treat that list as PARTIAL, not as a clean roster.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"q":{"type":"string"},"page":{"type":"number"},"state":{"type":"string"},"pageSize":{"type":"number"},"studioId":{"type":"string"},"authStatus":{"type":"string"},"actingUserId":{"type":"string"},"paymentStatus":{"type":"string"},"actingUserEmail":{"type":"string"},"missingCategory":{"type":"string"},"complianceStatus":{"type":"string"},"employmentStatus":{"type":"string"},"expiringWithinDays":{"type":"number"}}},"logicalName":"list_artists","displayName":"list_artists","title":"list_artists","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_artist_compliance_profile","description":"One artist's full compliance file: profile, credentials with recomputed statuses, a fresh work-authorization verdict, and a summary (active, expiring, expired, missing, outstanding payments, pending renewals, recent activity). Emergency contact and internal notes are omitted unless the acting user is permitted to see them — the `visibility` field says which were withheld.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"userId":{"type":"string"},"profileId":{"type":"string"},"artistName":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"get_artist_compliance_profile","displayName":"get_artist_compliance_profile","title":"get_artist_compliance_profile","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_artist_credentials","description":"Every credential covering one artist, including group permits that name them. `effectiveStatus` is recomputed from the dates on every read and is the one to trust; the stored `status` column is returned only so you can see where the two disagree.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"userId":{"type":"string"},"profileId":{"type":"string"},"artistName":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"list_artist_credentials","displayName":"list_artist_credentials","title":"list_artist_credentials","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"create_artist_credential","description":"File a licence, permit or certification, optionally linked to an artist. The credential is ALWAYS created as PENDING_VERIFICATION — you cannot assert that a licence is valid by saying so here. It becomes usable only via verify_artist_credential.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["category","name"],"properties":{"name":{"type":"string"},"notes":{"type":"string"},"userId":{"type":"string"},"category":{"type":"string"},"issuedAt":{"type":"string"},"studioId":{"type":"string"},"expiresAt":{"type":"string"},"profileId":{"type":"string"},"artistName":{"type":"string"},"renewalFee":{"type":"number"},"effectiveAt":{"type":"string"},"actingUserId":{"type":"string"},"jurisdiction":{"type":"string"},"paymentDueAt":{"type":"string"},"renewalDueAt":{"type":"string"},"restrictions":{"type":"string"},"issuingAgency":{"type":"string"},"licenseNumber":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"create_artist_credential","displayName":"create_artist_credential","title":"create_artist_credential","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"update_artist_credential","description":"Correct a credential's details. CAUTION: passing `status` is not an edit — it clears or blocks an artist for work exactly as a verification does, so it additionally requires confirm:true and the privilege to set a status. Do NOT use a status write to work around a refused authorization override.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId"],"properties":{"name":{"type":"string"},"notes":{"type":"string"},"status":{"type":"string"},"confirm":{"type":"boolean"},"archived":{"type":"boolean"},"issuedAt":{"type":"string"},"studioId":{"type":"string"},"expiresAt":{"type":"string"},"renewalFee":{"type":"number"},"effectiveAt":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"jurisdiction":{"type":"string"},"paymentDueAt":{"type":"string"},"renewalDueAt":{"type":"string"},"restrictions":{"type":"string"},"issuingAgency":{"type":"string"},"licenseNumber":{"type":"string"},"paymentStatus":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"update_artist_credential","displayName":"update_artist_credential","title":"update_artist_credential","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"link_credential_to_artist","description":"Add an artist to a credential's coverage — a group permit gaining a named party, or restoring a previously unlinked artist. Their work authorization is recomputed and recorded afterwards.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId"],"properties":{"userId":{"type":"string"},"profileId":{"type":"string"},"artistName":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"link_credential_to_artist","displayName":"link_credential_to_artist","title":"link_credential_to_artist","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"unlink_credential_from_artist","description":"Remove a credential's coverage of an artist. REQUIRES confirm:true — if this was the only document satisfying a requirement, the artist becomes non-compliant and unable to work the instant it lands. The link is soft-unlinked, so the record of who was covered when survives.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId"],"properties":{"userId":{"type":"string"},"confirm":{"type":"boolean"},"profileId":{"type":"string"},"artistName":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"unlink_credential_from_artist","displayName":"unlink_credential_from_artist","title":"unlink_credential_from_artist","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"upload_artist_credential_document","description":"Attach a supporting file (a scanned licence, a course certificate) to a credential. Content is base64. Allowed: PDF, JPEG, PNG, WEBP, HEIC, up to 10MB. Do NOT put government ID or work-authorization scans here — those belong in the encrypted personnel vault.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId","fileName","mimeType","contentBase64"],"properties":{"label":{"type":"string"},"fileName":{"type":"string"},"mimeType":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"contentBase64":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"upload_artist_credential_document","displayName":"upload_artist_credential_document","title":"upload_artist_credential_document","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"get_studio_compliance","description":"The establishment’s own compliance standing (admin only): establishment licence and biomedical waste registration with status and expiry, studio authorization, last health-department inspection and next due date, and whether the monthly spore-test log is current. Read-only.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"get_studio_compliance","displayName":"get_studio_compliance","title":"get_studio_compliance","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_status","description":"Whether the studio’s TikTok account is connected, its granted scopes (video.publish needed to post), token expiry, and how many videos sit in each queue state. Admin only.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_status","displayName":"tiktok_status","title":"tiktok_status","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_domain_status","description":"Whether the studio’s website domain is verified with TikTok for video URLs, and the DNS TXT record to add if it is not. Read-only. Admin only.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_domain_status","displayName":"tiktok_domain_status","title":"tiktok_domain_status","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_queue_video","description":"Queue a video for the studio’s TikTok account as a DRAFT. videoUrl must be a public https URL on a domain verified with TikTok (or TikTok’s test URL). Nothing is posted until an admin approves and publishes it.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["videoUrl","caption"],"properties":{"caption":{"type":"string"},"videoUrl":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"},"importToStorage":{"type":"boolean"}}},"logicalName":"tiktok_queue_video","displayName":"tiktok_queue_video","title":"tiktok_queue_video","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_list_posts","description":"List queued/published TikTok videos with their status (DRAFT, APPROVED, PUBLISHING, PUBLISHED, FAILED), post ids and any TikTok error.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"limit":{"type":"number"},"status":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_list_posts","displayName":"tiktok_list_posts","title":"tiktok_list_posts","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_approve_post","description":"Approve a DRAFT for publishing (DRAFT → APPROVED). Explicit: requires confirm: true from the admin after reviewing the caption and video.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["postId"],"properties":{"postId":{"type":"string"},"confirm":{"type":"boolean"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_approve_post","displayName":"tiktok_approve_post","title":"tiktok_approve_post","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_publish_post","description":"Publish an APPROVED video to the studio’s TikTok account, publicly. Explicit: requires confirm: true. Returns TikTok’s share_id; call tiktok_check_post for the post id (up to three minutes).","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["postId"],"properties":{"postId":{"type":"string"},"confirm":{"type":"boolean"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_publish_post","displayName":"tiktok_publish_post","title":"tiktok_publish_post","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"tiktok_check_post","description":"Ask TikTok where a submitted video stands (PROCESSING_DOWNLOAD, PUBLISH_COMPLETE, FAILED with reason) and record it.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["postId"],"properties":{"postId":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"tiktok_check_post","displayName":"tiktok_check_post","title":"tiktok_check_post","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_expiring_artist_credentials","description":"Credentials falling due inside a window: 30, 60, 90, 120 or 180 days (defaults to 30). An artist calling this sees only their own.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"days":{"type":"number"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"list_expiring_artist_credentials","displayName":"list_expiring_artist_credentials","title":"list_expiring_artist_credentials","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"list_artists_missing_credentials","description":"Artists who hold nothing at all against a requirement that applies to them. May come back with truncated:true, which means the list is PARTIAL — narrow it by studio rather than reporting it as complete.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"category":{"type":"string"},"studioId":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"},"includeInactive":{"type":"boolean"}}},"logicalName":"list_artists_missing_credentials","displayName":"list_artists_missing_credentials","title":"list_artists_missing_credentials","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"check_artist_work_authorization","description":"Whether an artist may legally work right now, recomputed from their credentials and the requirements that apply to them — never a stored verdict. The result is appended to the authorization history so it stays answerable later; pass persist:false for a hypothetical check that leaves no trace.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","properties":{"userId":{"type":"string"},"persist":{"type":"boolean"},"studioId":{"type":"string"},"profileId":{"type":"string"},"artistName":{"type":"string"},"actingUserId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"check_artist_work_authorization","displayName":"check_artist_work_authorization","title":"check_artist_work_authorization","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"record_artist_license_payment","description":"Log a licence fee payment against a credential. The credential's own payment status is kept in step. A payment with paidAt and no explicit status is recorded as PAID.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId","amount"],"properties":{"dueAt":{"type":"string"},"notes":{"type":"string"},"amount":{"type":"number"},"method":{"type":"string"},"paidAt":{"type":"string"},"status":{"type":"string"},"reference":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"record_artist_license_payment","displayName":"record_artist_license_payment","title":"record_artist_license_payment","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"record_artist_license_renewal","description":"Log a renewal, in progress or completed. A completed renewal with newExpiresAt also moves the credential's expiry date. It deliberately does NOT set the status — a renewed licence still has to be verified before it clears anyone for work.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId"],"properties":{"notes":{"type":"string"},"outcome":{"type":"string"},"reference":{"type":"string"},"startedAt":{"type":"string"},"completedAt":{"type":"string"},"submittedAt":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"newExpiresAt":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"record_artist_license_renewal","displayName":"record_artist_license_renewal","title":"record_artist_license_renewal","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"verify_artist_credential","description":"Record that a named person checked a credential against its issuing agency, and what they found. REQUIRES confirm:true — the outcome changes the credential status and can clear or block an artist for work immediately. An artist can NEVER verify their own credential, whoever is asking.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId","outcome"],"properties":{"notes":{"type":"string"},"source":{"type":"string"},"confirm":{"type":"boolean"},"outcome":{"type":"string"},"sourceUrl":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"verify_artist_credential","displayName":"verify_artist_credential","title":"verify_artist_credential","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"acknowledge_artist_license_reminder","description":"Record that a named person has seen the expiry/renewal warning on a credential. Keyed by credential id, because reminders are derived from the expiry date and the requirement's warn window rather than stored as rows. This acknowledges the warning; it does NOT renew, verify or extend anything.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["credentialId"],"properties":{"note":{"type":"string"},"actingUserId":{"type":"string"},"credentialId":{"type":"string"},"actingUserEmail":{"type":"string"}}},"logicalName":"acknowledge_artist_license_reminder","displayName":"acknowledge_artist_license_reminder","title":"acknowledge_artist_license_reminder","annotations":{"untrustedContentHint":true,"readOnlyHint":true}}],"toolSource":"directory_preview","agentAction":"both","installLinks":[{"id":"cursor","label":"Cursor","href":"cursor://anysphere.cursor-deeplink/mcp/install?name=PhillyInkz&config=eyJ1cmwiOiAiaHR0cHM6Ly9waGlsbHlpbmt6LmNvbS9hcGkvbWNwIn0%3D"},{"id":"vscode","label":"VS Code","href":"vscode:mcp/install?%7B%22name%22%3A%22PhillyInkz%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fphillyinkz.com%2Fapi%2Fmcp%22%7D"},{"id":"vscode-insiders","label":"VS Code Insiders","href":"vscode-insiders:mcp/install?%7B%22name%22%3A%22PhillyInkz%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fphillyinkz.com%2Fapi%2Fmcp%22%7D"},{"id":"claude-web","label":"Claude.ai","href":"https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=PhillyInkz&connectorUrl=https%3A%2F%2Fphillyinkz.com%2Fapi%2Fmcp"},{"id":"codex","label":"Codex","copyText":"codex mcp add \"PhillyInkz\" --url \"https://phillyinkz.com/api/mcp\""},{"id":"chatgpt","label":"ChatGPT","href":"https://www.mcpbundles.com/docs/integrations/chatgpt"}],"catalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/phillyinkz-mcp-c72af2f05f","callUrl":"https://www.mcpbundles.com/api/directory/v1/servers/phillyinkz-mcp-c72af2f05f/tools/{tool}","mcpServerUrl":"https://phillyinkz.com/api/mcp","liveCatalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/phillyinkz-mcp-c72af2f05f?live=1"}