Skip to main content
Glama
Charley-Forey-AI

ProjectSight MCP Server

ProjectSight MCP Server

A scalable, maintainable MCP (Model Context Protocol) server that provides access to the ProjectSight API via 425 tools across 48 domainsβ€”including portfolios, projects, action items, RFIs, submittals, contracts, budgets, applications for payment, change orders, daily reports, drawings, files, meetings, and more.

This server has been refactored into a modular, teachable structure that demonstrates best practices for building MCP servers. It's designed to be both production-ready and an excellent learning resource.

🎯 Features

  • 425 tools across 48 domains: Full ProjectSight API coverageβ€”ActionItems, RFIs, Submittals, Projects, Portfolios, Contracts, Budgets, Applications for Payment, Change Orders (potential/prime/sub), Daily Reports, Field Work Directives, Drawings, Drawing Sets, Files/Folders, Meetings, Notices, Safety Notices, Punch Lists, Issues, Checklists, Forecasts, Job Costs, Purchase Orders, Invoicing, ERP read-only, Users, Roles, Companies, Contacts, and more.

  • Intelligent gateway: By default the server exposes a single projectsight tool with intent matching and 35+ named capabilities (multi-tool workflows) defined in mcp/yaml/capabilities.yaml. Set MCP_GATEWAY_ONLY=0 to expose all 425 tools.

  • Server policy: Deletes never run by default; optional approval for create/update via mcp/yaml/policy.yaml and env overrides (MCP_DELETE_POLICY, MCP_REQUIRE_APPROVAL_FOR_MUTATIONS).

  • OAuth2 Authentication: Automatic token management with caching and refresh; client credentials (STDIO) or On-Behalf token exchange (e.g. Agent Studio).

  • Modular Architecture: Clean separation of concerns, registry-driven gateway, easy to extend.

  • Debug Tools: Test connection, debug tokens, get context requirements, test different scopes.

πŸ“ Project Structure

projectsight-mcp/ β”œβ”€β”€ mcp/ β”‚ β”œβ”€β”€ main.py # Entry point (STDIO or --http) β”‚ β”œβ”€β”€ config.py # Env config; portfolio/scope resolution β”‚ β”œβ”€β”€ request_context.py # Per-request context (actor token, X-* headers) β”‚ β”œβ”€β”€ auth.py # OAuth2 client credentials + On-Behalf exchange β”‚ β”œβ”€β”€ client.py # ProjectSight API client (retry, token refresh) β”‚ β”œβ”€β”€ utils.py # Helpers (e.g. resolve_project) β”‚ β”œβ”€β”€ registry.py # Load tool_registry.yaml; HANDLER_REGISTRY β”‚ β”œβ”€β”€ policy.py # Delete/mutation policy from policy.yaml + env β”‚ β”œβ”€β”€ yaml/ β”‚ β”‚ β”œβ”€β”€ policy.yaml # delete_policy, mutation_approval β”‚ β”‚ β”œβ”€β”€ tool_registry.yaml # Tool metadata for gateway (425 tools) β”‚ β”‚ └── capabilities.yaml # Named multi-tool workflows (35+ capabilities) β”‚ β”œβ”€β”€ scripts/ β”‚ β”‚ └── build_registry.py # Generate tool_registry.yaml from tool modules β”‚ β”œβ”€β”€ docs/ β”‚ β”‚ β”œβ”€β”€ TOOL_STANDARD.md # Docstring and registry standards β”‚ β”‚ └── TOOL_REGISTRY_MAINTENANCE.md # How to maintain/regenerate registry β”‚ β”œβ”€β”€ tools/ # MCP tools organized by domain β”‚ β”‚ β”œβ”€β”€ __init__.py # register_tools(); gateway-only vs all-tools β”‚ β”‚ β”œβ”€β”€ gateway.py # projectsight(user_request, context, prefer_discovery) β”‚ β”‚ β”œβ”€β”€ debug.py # test_connection, debug_token, get_mcp_context_requirements β”‚ β”‚ β”œβ”€β”€ projects.py, portfolio.py β”‚ β”‚ β”œβ”€β”€ action_items.py, rfis.py, submittals.py, workflow.py, workflow_states.py β”‚ β”‚ β”œβ”€β”€ application_for_payment.py, budget.py, budget_code_structure.py, budget_group.py, budget_snapshot.py β”‚ β”‚ β”œβ”€β”€ change_order_request.py, potential_co.py, prime_contract_co.py, sub_contract_co.py β”‚ β”‚ β”œβ”€β”€ checklist.py, company.py, contact.py, contract.py, contract_invoice.py β”‚ β”‚ β”œβ”€β”€ daily_report.py, drawing.py, drawing_set.py, erp_read_only.py β”‚ β”‚ β”œβ”€β”€ field_work_directive.py, file.py, folder.py, forecast.py, general_invoice.py β”‚ β”‚ β”œβ”€β”€ issue.py, job_costs.py, lookup_list.py, meeting.py, notice.py β”‚ β”‚ β”œβ”€β”€ photo.py, po_catalog.py, purchase_order.py, records.py, report_generator.py β”‚ β”‚ β”œβ”€β”€ role.py, safety_notice.py, submittal_package.py, transmittal.py, user.py β”‚ β”‚ └── punch_list.py β”‚ └── tests/ β”‚ └── test_gateway_intent.py # Registry + intent-matching tests β”œβ”€β”€ README.md β”œβ”€β”€ pyproject.toml └── .env # Create this; not committed

Tool modules register with the MCP instance and with HANDLER_REGISTRY so the gateway can execute them by name.

πŸš€ Quick Start

1. Install Dependencies

pip install fastmcp python-dotenv aiohttp uvicorn pyyaml

Or using a virtual environment:

python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install fastmcp python-dotenv aiohttp uvicorn pyyaml

(Pyyaml is used by the registry and policy modules.)

2. Configure Credentials

Create a .env file in the mcp/ directory (or project root) with your ProjectSight API credentials:

APPLICATION_NAME=your_app_name CLIENT_ID=your_client_id CLIENT_SECRET=your_client_secret PROJECTSIGHT_API_URL=https://cloud.api.trimble.com/projectsight/us1/1.0 PROJECTSIGHT_SCOPE=ProjectSight_-_US1 # Optional: PORTFOLIO_ID=your_portfolio_guid (UUID). If unset, the server discovers a default via GET /accounts and GET /accounts/{accountId}/portfolios at startup. # Optional: for stage or other envs use TRIMBLE_TOKEN_URL=https://stage.id.trimblecloud.com/oauth/token

Note on PORTFOLIO_ID: PORTFOLIO_ID is optional. If unset, the server calls the ProjectSight API (GET /accounts and GET /accounts/{accountId}/portfolios) at startup and uses the first (or only) portfolio found. You can also discover accounts and portfolios with get_accounts and get_portfolios_for_account, then set PORTFOLIO_ID in .env to a Portfolio GUID (UUID) or pass portfolio_guid on tool calls. The API base URL is unchanged (PROJECTSIGHT_API_URL); all requests, including account/portfolio discovery, use it.

Getting Credentials:

  1. Sign in to API Cloud with your Trimble account

  2. On the Discover API page, select ProjectSight or ProjectSight-EU

  3. Select Subscriptions and subscribe your application

  4. Select Get Key and copy:

    • Application Name

    • Consumer Key (CLIENT_ID)

    • Consumer Secret (CLIENT_SECRET)

For more information, email ProjectSightAPISupport@trimble.com to request API access.

Note on Scope: The PROJECTSIGHT_SCOPE should match your API subscription region:

  • ProjectSight_-_US1 for US region

  • ProjectSight_-_EU1 for EU region

  • ProjectSight_-_US2 for Azure US region

3. Run the Server

Run from the mcp/ directory so that .env and imports resolve correctly (or set PYTHONPATH and ensure .env is loaded from the right place).

STDIO Mode (default for MCP clients):

cd mcp python main.py

HTTP Streaming Mode:

cd mcp python main.py --http

With custom host/port:

# Windows PowerShell $env:MCP_HOST="0.0.0.0" $env:MCP_PORT="8000" python main.py --http # Linux/Mac export MCP_HOST=0.0.0.0 export MCP_PORT=8000 python main.py --http

Gateway-only mode (default):
The server defaults to exposing only the intelligent projectsight gateway tool so the agent is not overwhelmed by hundreds of tools. No configuration needed. To expose all tools instead (e.g. for debugging), set MCP_GATEWAY_ONLY=0 before starting. See "Intelligent Gateway Tool" below.

Port already in use (10048): If you see "port already in use" or error 10048 when running python main.py --http, use another port: set MCP_PORT=8001 (PowerShell: $env:MCP_PORT="8001"), then start the server again and use http://localhost:8001/mcp in your client. To free port 8000 on Windows: run netstat -ano | findstr :8000, note the PID (last column), then taskkill /PID <pid> /F.

πŸ”§ MCP Client Configuration

STDIO Mode (Cursor, Claude Desktop, etc.)

{ "mcpServers": { "projectsight": { "command": "python", "args": ["C:\\Users\\cforey\\Desktop\\projectsight-mcp\\mcp\\main.py"], "env": { "APPLICATION_NAME": "your_app_name", "CLIENT_ID": "your_client_id", "CLIENT_SECRET": "your_client_secret", "PORTFOLIO_ID": "your-portfolio-guid", "MCP_GATEWAY_ONLY": "1" } } } }

Note: You can also use a .env file instead of setting environment variables in the config. The script will automatically load variables from a .env file in the mcp/ directory. PORTFOLIO_ID can be omitted; the server will discover a default portfolio at startup. MCP_GATEWAY_ONLY=1 is the default (single-tool mode); including it in env makes the behavior explicit for Cursor and other clients.

HTTP Mode

For MCP clients that support HTTP transport, configure the connection URL:

http://localhost:8000/mcp

On behalf of actor token (Agent Studio)

When the MCP is used from Trimble Agent Studio (or any client that sends the signed-in user's Trimble ID token), you can configure the MCP with "On behalf of actor token" instead of static credentials. The client sends the user's TID token as Authorization: Bearer <token> on each request. The MCP then exchanges that token for a ProjectSight-scoped token via Trimble Identity's On Behalf / Token Exchange grant and uses it for API calls, so requests run as that user.

Token format: The Bearer token must be a JWT (e.g. Trimble ID token). The MCP detects JWT shape and sends the correct subject_token_type for the exchange. If you see an error like subject_token type 'urn:ietf:params:oauth:token-type:access_token' not supported, ensure the client sends a JWT in Authorization: Bearer, not an opaque access token.

Setup in Agent Studio:

  • Authentication: Select On behalf of actor token.

  • URL: Your MCP endpoint (e.g. https://your-mcp-host/mcp). The MCP must be reachable over HTTPS when used from Studio.

  • Scopes (informational): Required scopes for the user's token typically include:

    • openid

    • ProjectSight scope for your region: ProjectSight_-_US1 (US), ProjectSight_-_EU1 (EU), or ProjectSight_-_US2 (Azure US).

Confirm exact scope names with Trimble Identity and API Endpoints for your environment (stage vs prod).

Server-side: The MCP still needs CLIENT_ID and CLIENT_SECRET in .env (or environment) to perform the On Behalf token exchange. Set APPLICATION_NAME, PROJECTSIGHT_SCOPE, PORTFOLIO_ID, and PROJECTSIGHT_API_URL as defaults; they can be overridden per request via headers (see below).

Optional per-request headers (when a gateway or client sends them):

  • X-Portfolio-Id β€” Portfolio GUID for the request (overrides PORTFOLIO_ID for that request).

  • X-API-Base-URL β€” ProjectSight API base URL (e.g. for a different region).

  • X-ProjectSight-Scope β€” Scope used for token exchange (e.g. ProjectSight_-_US1).

  • X-Application-Name β€” Application name for token/scope.

If these headers are not sent, the MCP uses .env defaults and tool parameters (e.g. portfolio_guid) as today.

Fallback: When no Authorization: Bearer token is present (e.g. STDIO or "None" auth in Studio), the MCP uses client credentials from .env as before.

Troubleshooting On Behalf exchange:

Error

Cause

What to do

JWT error: Signature verification failed

The Bearer token was not issued by (or cannot be verified by) the same Trimble Identity environment the MCP is using.

Ensure TRIMBLE_TOKEN_URL in .env matches the IdP that issued the token. For stage (e.g. studio.stage.trimble-ai.com) use the stage token URL (e.g. https://stage.id.trimblecloud.com/oauth/token or per Trimble docs); for production use https://id.trimble.com/oauth/token. The client must obtain the token from that same environment.

Caller is not the intended audience of subject token

The JWT was issued for a different application; Trimble Identity will not exchange it for a token for this MCP's CLIENT_ID.

Ensure the MCP's CLIENT_ID (in .env) is the application the user signs into, or that the token requested by the client (e.g. Agent Studio) has audience (or resource) that includes this MCP's application. Configure the client/IdP so the subject token's aud includes the MCP's CLIENT_ID.

subject_token type 'access_token' not supported

IdP expects a JWT.

The MCP now sends JWT type when the token looks like a JWT. Ensure the client sends a JWT in Authorization: Bearer.

Automatic fallback when On Behalf fails: If On Behalf token exchange fails (e.g. signature verification or intended audience), the MCP automatically falls back to client credentials so API requests can still be made. Set PORTFOLIO_ID in .env if discovery does not find a portfolio or you need a specific portfolio. Requests then run with the application identity (not the signed-in user).

Workaround when On Behalf is not configured: Omit the Bearer token (use client credentials only), set PORTFOLIO_ID in .env, and the MCP will use the cached client_credentials token for discovery and all tools.

🧠 Intelligent Gateway Tool (Single-Tool Mode)

By default (or when MCP_GATEWAY_ONLY=1), the server exposes a single tool projectsight so the agent is not overwhelmed by hundreds of tools. Set MCP_GATEWAY_ONLY=0 to expose all tools.

Named capabilities: The gateway can run named capabilities (e.g. project_overview, contract_and_budget_summary, quality_and_issues) that execute a fixed sequence of tools with shared context. The list is in mcp/yaml/capabilities.yaml.

Parameters:

  • user_request (required): Natural language request (e.g. "List submittals for Downtown project", "Get projects", "Test connection").

  • context (optional): Dict with known context from prior turns: portfolio_guid, project_id, project_name, contract_id, etc.

  • prefer_discovery (optional): If true, returns only a plan (which tools would run) without executing.

Responses:

  • action: "need_more_info" β€” Ask the user questions_for_user, then call again with context updated (e.g. user says "Downtown" β†’ send context: { "project_name": "Downtown" }).

  • action: "plan" β€” When prefer_discovery=true, returns the steps that would run (no execution).

  • action: "result" β€” The result from the executed tool(s).

  • action: "policy_blocked" β€” A delete was requested; this server does not run delete commands (delete actions require triple check).

  • action: "approval_required" β€” A create/update was requested and the server is configured to require approval; call again with the same request and context plus approved: true or confirm_mutation: true to execute.

  • action: "error" β€” Error and suggestion.

Server policy (no deletes; optional approval for create/update):

  • Deletes: The server does not execute delete commands. Delete requests return action: "policy_blocked" with a message that delete actions require triple check; use the ProjectSight UI or API for deletions.

  • Create/Update: You can require approval before running create/update tools by setting MCP_REQUIRE_APPROVAL_FOR_MUTATIONS=1. Then the first call returns action: "approval_required" with a plan; the agent or user can confirm by calling again with the same context plus approved: true or confirm_mutation: true. Policy is configured in mcp/yaml/policy.yaml and overridden by MCP_DELETE_POLICY and MCP_REQUIRE_APPROVAL_FOR_MUTATIONS in .env.

Recommended workflow for the agent:

  1. User sends a message.

  2. Agent calls projectsight(user_request=user_message, context={}).

  3. If response is need_more_info β†’ agent asks the user the returned questions, then calls projectsight(user_request=..., context={ ... user answers ... }).

  4. If response is plan (with prefer_discovery=true) β†’ agent can confirm with user, then call again without prefer_discovery to execute.

  5. If response is result β†’ agent presents the result to the user.

  6. If response is error β†’ agent shows the error and suggestion.

Context continuity (multi-turn conversations): The gateway is stateless: each call receives only the user_request and context for that call. Successful responses include resolved_context (e.g. project_id, project_name, portfolio_guid, and when relevant record IDs such as rfi_id). Clients should retain this so that follow-up requests (e.g. "change the due date to Feb 19" after listing RFIs) work without the user re-specifying project or RFI. When the user refers to a specific item from a prior result (e.g. "that one", "RFI 005"), the client should add the corresponding ID (e.g. rfi_id: 5) to the context it sends.

No multi-tool sequencing is required by the agent; the gateway resolves project/portfolio context and runs the right internal tools server-side. Tool metadata is in mcp/yaml/tool_registry.yaml; handlers are registered at startup in HANDLER_REGISTRY for execution.

πŸ“š Available Tools

The server provides 425 tools across 48 domains. Full tool list and metadata: mcp/yaml/tool_registry.yaml. Named multi-tool capabilities (e.g. project_overview, contract_and_budget_summary, quality_and_issues): mcp/yaml/capabilities.yaml. When using the gateway, call get_mcp_context_requirements() for required context and tools grouped by domain.

Domains (48): action_items, application_for_payment, budget, budget_code_structure, budget_group, budget_snapshot, change_order_request, checklist, company, contact, contract, contract_invoice, daily_report, debug, drawing, drawing_set, erp_read_only, field_work_directive, file, folder, forecast, general_invoice, issue, job_costs, lookup_list, meeting, notice, photo, po_catalog, portfolio, potential_co, prime_contract_co, projects, punch_list, purchase_order, records, report_generator, rfis, role, safety_notice, sub_contract_co, submittal_package, submittals, transmittal, user, workflow, workflow_states.

Common tools (when not using gateway-only mode): get_projects, list_action_items, list_rfis, list_submittals, test_connection, get_mcp_context_requirements. Use the corresponding list/get tools to discover IDs (e.g. list_contracts, list_budgets) when a tool asks for project_id, contract_id, etc. Portfolio-level tools use portfolio_guid from the parameter or PORTFOLIO_ID from .env (must be a Portfolio GUID/UUID).

πŸ—οΈ Architecture & Best Practices

This MCP server uses a scalable, maintainable structure with a registry-driven gateway.

Architecture and data flow

  • Startup: main.py loads Config, creates Auth and ProjectSightClient, and calls register_tools(mcp, client). In tools/__init__.py, if MCP_GATEWAY_ONLY=1 (default), internal tool modules register with a no-op MCP so they don't appear as tools to the client, but they still register handlers in HANDLER_REGISTRY. The gateway always registers the single projectsight tool on the real MCP.

  • Gateway flow: The user calls projectsight(user_request, context?, prefer_discovery?) β†’ keyword-based intent matching against mcp/yaml/tool_registry.yaml and mcp/yaml/capabilities.yaml β†’ resolve portfolio_guid/project_id (and project name) via utils.resolve_project and Config/request context β†’ policy check (delete blocked; mutation approval if required) β†’ execute handler(s) from HANDLER_REGISTRY β†’ return need_more_info | plan | result | policy_blocked | approval_required | error.

  • Request context (HTTP): request_context.py holds per-request actor token and overrides (X-Portfolio-Id, X-API-Base-URL, X-ProjectSight-Scope, X-Application-Name). Auth and Config use these when present (e.g. Agent Studio).

  • Policy: policy.py reads mcp/yaml/policy.yaml; env vars MCP_DELETE_POLICY and MCP_REQUIRE_APPROVAL_FOR_MUTATIONS override. Deletes are never run by default; create/update can require context.approved or context.confirm_mutation.

flowchart LR User --> projectsight projectsight --> IntentMatch IntentMatch --> ContextResolve ContextResolve --> PolicyCheck PolicyCheck --> Handlers Handlers --> Response
  • Modular Design: Each component in its own file with clear responsibilities.

  • Separation of Concerns: Configuration, authentication, API client, registry, policy, and tools are separated.

  • Organized Tools: Tools grouped by domain; gateway uses registry and capabilities for intent matching.

πŸ“– Documentation

  • TOOL_STANDARD.md: Docstring and registry standards for tools; body/Dict expectations.

  • TOOL_REGISTRY_MAINTENANCE.md: How to maintain or regenerate mcp/yaml/tool_registry.yaml (e.g. run python scripts/build_registry.py from mcp/).

Testing

Gateway intent-matching tests live in mcp/tests/. Run them from the mcp directory:

cd mcp python -m unittest tests.test_gateway_intent -v

Tests cover registry loading, intent matching for common phrases (e.g. "list submittals", "get projects"), and capability-hint summary.

πŸŽ“ Learning Resource

This structure is designed to be a teaching example - use it as a reference when building your own MCP servers! The code demonstrates:

  • βœ… Single Responsibility Principle

  • βœ… Separation of Concerns

  • βœ… Dependency Injection

  • βœ… DRY (Don't Repeat Yourself)

  • βœ… Clear Naming Conventions

  • βœ… Comprehensive Documentation

  • βœ… Type Hints

  • βœ… Error Handling Patterns

πŸ” Authentication

The server uses OAuth2 client credentials flow with Trimble Identity:

  • Tokens are automatically cached and refreshed

  • Token cache is stored at ~/.cache/projectsight/token_cache.json

  • Tokens are refreshed automatically when expired

πŸ“ Important Notes

  • Portfolio ID: Optional in .env. When unset, the server discovers a default portfolio at startup via the accounts/portfolios API. Use get_accounts and get_portfolios_for_account to list accounts and portfolios, then set PORTFOLIO_ID to a Portfolio GUID (UUID) or pass portfolio_guid to tools. If PORTFOLIO_ID is an integer (Account ID), you must pass portfolio_guid per request or set PORTFOLIO_ID to a UUID.

  • Server behavior (env): MCP_GATEWAY_ONLY (default 1 = only projectsight tool; 0 = expose all 425 tools). MCP_DELETE_POLICY (default never_run; deletes are never executed). MCP_REQUIRE_APPROVAL_FOR_MUTATIONS (set to 1 to require context.approved or context.confirm_mutation before create/update tools run). Optional: MCP_REQUEST_TIMEOUT_SECONDS, MCP_CLIENT_RETRY_COUNT.

  • Project Lookup: Many tools support finding projects by name (case-insensitive, partial match) if you don't know the project ID.

  • RFI Creation: The create_or_update_rfi tool is highly flexible and will:

    • Auto-detect workflow states from existing RFIs

    • Auto-generate RFI numbers

    • Normalize dates from various formats ("today", "tomorrow", "2026-01-26", etc.)

    • Map importance text ("high", "normal", "low") to importance IDs

    • Use existing RFI settings as defaults when appropriate

🌐 Exposing via Public URL (Tunneling)

To make your local server accessible via a public URL, use a tunneling service:

  1. Install ngrok on Windows:

    winget install ngrok.ngrok
  2. Start your MCP server:

    cd mcp python main.py --http
  3. Create a tunnel (in a separate terminal):

    ngrok http 8000
  4. Use the public URL: ngrok will provide a public URL like https://abc123.ngrok-free.dev. The MCP endpoint is at /mcp:

    https://abc123.ngrok-free.dev/mcp

Option 2: Cloudflare Tunnel (cloudflared)

  1. Install cloudflared: Download from developers.cloudflare.com

  2. Start your MCP server:

    cd mcp python main.py --http
  3. Create a tunnel (in a separate terminal):

    cloudflared tunnel --url http://localhost:8000
  4. Use the public URL: Cloudflare will provide a public URL like https://random-subdomain.trycloudflare.com. Your MCP endpoint will be:

    https://random-subdomain.trycloudflare.com/mcp

πŸ”’ Security Note

When exposing your server publicly, consider:

  • Adding authentication/API keys if your MCP server handles sensitive data

  • Using HTTPS (all tunneling services above provide HTTPS)

  • Limiting access to specific IPs if possible

  • Monitoring usage and rate limiting

πŸ“Š Rate Limits

Based on updated guidance from Trimble Cloud, you don't need to pass the x-API-key to the trimblepaas.com endpoints. If you do pass it, there is a limit of 50 requests per second.

πŸ“– API Documentation

For detailed API documentation, refer to:

πŸ”„ Migration from Old Structure

If you were using the old projectsight.py file directly:

  1. Update command: Use python main.py instead of python projectsight.py

  2. Configuration: Same .env file format (place in mcp/ directory)

  3. MCP Client Config: Update path to point to mcp/main.py

  4. Tools: All tools work the same, just organized better

The old projectsight.py file is still available for reference but the new modular structure is recommended.

πŸ› οΈ Extending the Server

  • New tools live under mcp/tools/<domain>.py. Each tool module defines register(mcp, handler_registry) and registers both the FastMCP tool and an async handler: handler_registry[name] = my_async_handler. The gateway executes tools by name via get_handler(name) from the registry.

  • Gateway intent matching: Add (or regenerate) the tool's entry in mcp/yaml/tool_registry.yaml (name, description, domain, required_context, optional_context, keywords; optionally examples, follow_ups). Run python scripts/build_registry.py from the mcp/ directory to regenerate the registry from docstrings; see TOOL_REGISTRY_MAINTENANCE.md.

  • Wiring: Add the new module to the imports and register(...) calls in mcp/tools/__init__.py. Optional: if the tool is part of a multi-step workflow, add or extend an entry in mcp/yaml/capabilities.yaml.

Example pattern:

# mcp/tools/my_domain.py from fastmcp import FastMCP _client = None def register(mcp: FastMCP, handler_registry: dict): @mcp.tool() async def my_tool(portfolio_guid: str, param: str) -> dict: """One-line summary. Args: portfolio_guid: ... param: ... Returns: ...""" return await _run_my_tool(portfolio_guid, param) handler_registry["my_tool"] = _run_my_tool # gateway executes by name async def _run_my_tool(portfolio_guid: str, param: str) -> dict: result = await _client.get(f"/{portfolio_guid}/endpoint/{param}") return {"result": result} def set_client(client): global _client _client = client

πŸ“„ License

This project is provided as-is for use with the ProjectSight API.


Built with best practices in mind - Use this structure as a reference for building your own MCP servers! πŸš€

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Charley-Forey-AI/ProjectSight-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server