🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@ttctl/mcp

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ttctl/mcp

TTCtl MCP server exposing Toptal Talent operations to AI assistants

Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

@ttctl/mcp

npm License

Model Context Protocol server exposing your Toptal Talent profile to AI assistants. Powers ttctl mcp in the TTCtl umbrella binary.

Unofficial. TTCtl is NOT affiliated with, endorsed by, or supported by Toptal LLC. See the project README for the full use policy and disclaimer.

Audience

End users should install the ttctl umbrella package and configure their MCP client to spawn ttctl mcp — see the project README's MCP Integration section for Claude Desktop, Claude Code, and Cursor configurations.

This package is published separately for embedders who want to host the MCP server inside their own process, or wire a non-stdio transport (SSE/HTTP) around buildServer().

Install

npm install @ttctl/mcp

Requires Node.js ≥ 22.19.0, ESM only.

API Surface

  • runMcpStdio(opts?) — start the MCP server on stdio (used by ttctl mcp).
  • buildServer(opts?) — construct the underlying McpServer without binding a transport. For SSE/HTTP transports or tests.
  • BuildServerOptions{ configPath?: string; logger?: McpDiagnosticLogger }. configPath is captured ONCE at construction; subsequent tool invocations read AND write that exact path regardless of mid-session TTCTL_CONFIG_FILE shifts (see path-capture-on-startup, issue #113).
  • Error mappingttctlErrorToToolResponse, ttctlErrorToToolResponseOrNull, ToolErrorResponse.
  • Diagnostics (issue #224) — setMcpDiagnosticLogger, getMcpDiagnosticLogger, resetMcpDiagnosticLogger, wrapToolHandler, redactToolArgs, emitMcpDebug, emitMcpAuthResolve, isTransportError, extractTransportStatus, extractTransportSurface.

Tool catalog

The server registers 139 tools spanning the full Toptal Talent surface that TTCtl exposes — read AND mutation paths (per-domain counts below sum to the total):

  • profile.* (69 tools) — basic, skills, industries, education, certifications, employment, portfolio, visas, resume, external, reviews, specializations, countries
  • jobs (24 tools) — browse (list / show / show-many / match-quality / rate-insight / recommended / dashboard / dashboard-count) + saved / viewed / not-interested signals + search subscription + apply funnel
  • payments (10 tools) — summary + show-many + payouts (list / show) + methods (list / show) + rate (current / show / questions / change)
  • engagements (9 tools) — list / show / stats + breaks (list / add / remove / reschedule / reasons) + payments (list)
  • applications (7 tools) — list / show / stats + interview detail (show / notes / guide) + availability-request detail
  • availability (5 tools) — show + working-hours (show / set) + allocated-hours (show / set)
  • timesheet (5 tools) — list / pending-list / show / submit / update
  • interest_requests (4 tools) — list + accept / reject / reject-reasons (the ON_RECRUITER_REVIEW write surface)
  • surveys (3 tools) — list (pending) / submit (answers) / feedback (free-text)
  • contracts (2 tools) — list / show (talent-level contracts surface)
  • me (1 tool) — actions list (viewer performed-actions audit log)

Tools use canonical sub-domain names — CLI aliases (certs, experience) are CLI-only and do NOT appear in the MCP catalog. The full registry is wired in tools/index.ts; the authoritative tool count and per-name set are asserted by the registration tests (src/tools/__tests__/registration.test.ts, src/__tests__/tools.test.ts) — re-derive from there when the surface changes.

Glossary — Toptal portal label → MCP / API enum

Tool descriptions reference wire-canonical names (AVAILABILITY_REQUEST_PENDING, eligibleJobs, …); the Toptal portal surfaces the same concepts with user-facing labels. This table is the cross-reference.

Activity items (ttctl_applications_*)

The Toptal portal sidebar groups activity rows by status group; each row also carries a finer-grained status. The MCP ttctl_applications_list --statusGroups flag takes the status-group enum. Group assignment is server-side — the statusV2.value examples below are representative (✓ = observed in research captures; others inferred from portal observation and enum semantics).

Portal labelstatusGroups enumRepresentative statusV2.value
Interest Requests / Job Interest RequestON_RECRUITER_REVIEWAVAILABILITY_REQUEST_PENDING (verbose: "Job Interest Request")
On Client ReviewON_CLIENT_REVIEWPROFILE_SENT_TO_CLIENT, APPLIED, INTERVIEW_*
Active EngagementACTIVE_ENGAGEMENTACTIVE; also ON_TRIAL, ON_BREAK, PENDING_START
Closed EngagementCLOSED_ENGAGEMENTCOMPLETED, REJECTED_AFTER_TRIAL
Archive / ArchivedARCHIVEDAVAILABILITY_REQUEST_EXPIRED, ✓ AVAILABILITY_REQUEST_REJECTED, ✓ JOB_CANCELED, ✓ POSITION_FULFILLED

Each response row's statusV2.verbose is the exact label the portal renders ("Job Interest Request", "Active", "Archived", …); statusV2.value is the wire enum.

Jobs (ttctl_jobs_*)

Portal conceptMCP toolNotes
Job board "N of M" counterttctl_jobs_list returns the N (eligible) poolM − N = already-applied + position-fulfilled + not-interested + apply-blocked (skill / specialization mismatch, missing ID verification, insufficient hours, legacy-client restriction, etc. — see JobOperationsApplyErrorsEnum for the apply-error taxonomy); the M − N remainder is not exposed by this tool.
Saved jobsttctl_jobs_savedServer-side saved=true filter on eligibleJobs.
Not-interested jobsttctl_jobs_not_interested_listServer-side notInterested=true filter.
Viewed jobsttctl_jobs_viewedBest-effort: wire has no viewed filter; client-side filter over a paginated eligibleJobs fetch (see the tool's R1 caveat).
Job-search subscriptionttctl_jobs_search_*Single subscription per user (wire cardinality R2).

Trust model

Process-level: any process that can spawn ttctl mcp gets full access to the user's Toptal Talent session via the configured config file. The 139-tool catalog includes destructive surfaces (timesheet submit, timesheet update, profile mutations, job-interest signals, rate-change requests, etc.) — the blast radius is the user's full profile and platform-side activity, not just reads. Don't grant MCP access to untrusted AI agents — see the project SECURITY.md.

Debug instrumentation

Set TTCTL_DEBUG_MCP=1 to emit one JSON object per line on stderr for: tool invocation (mcp_tool_invoke_start / mcp_tool_invoke_end), auth resolution (mcp_auth_resolve), and transport errors (mcp_transport_error). Bearer tokens are NEVER in any allowlisted shape (type-system enforcement + runtime substring assertion). The stdout JSON-RPC channel is untouched.

TTCTL_DEBUG_MCP=1 ttctl mcp 2> mcp-debug.log
jq -c 'select(.event == "mcp_tool_invoke_end") | {tool, duration_ms, status}' mcp-debug.log

Example

Embed the stdio server with an explicit config path:

import { runMcpStdio } from "@ttctl/mcp";

await runMcpStdio({
  configPath: process.env["TTCTL_CONFIG_FILE"] ?? `${process.env["HOME"]}/.ttctl.yaml`,
});

Or build the server, install a custom logger, and bind your own transport:

import { buildServer, setMcpDiagnosticLogger } from "@ttctl/mcp";

setMcpDiagnosticLogger((record) => myAuditSink.write(record));
const server = buildServer({ configPath: "/etc/ttctl/config.yaml" });
// ...bind server to your chosen MCP transport (SSE, HTTP, custom)

License

AGPL-3.0-only. Importing @ttctl/mcp into your own code means the combined work is covered by AGPL-3.0; if you operate a public MCP server backed by this package, AGPL § 13 source-disclosure to remote users applies. See the project README's License section.

FAQs

Package last updated on 16 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts