Choose one bounded tool.
Start with an operation that has a clear input, a clear result, and a safe test environment. A weather lookup, a read-only catalog query, or a structured calculation is a better first tool than a generic execute command. Name the tool after the user outcome and document what it will not do.
Write the input schema before writing the handler. Decide which fields are required, which values are allowed, how missing data is reported, and what evidence belongs in the result. The schema is part of the interface a client and model will use.
Validate and fail at the server boundary.
Do not rely on the model or client to enforce the contract. Validate types, ranges, identifiers, permissions, and downstream assumptions inside the server. Return a structured error that tells the caller whether the request was invalid, unauthorized, unavailable, or partially completed.
Keep external calls behind a small adapter so tests can exercise the tool without reaching production. If the tool calls an API, set timeouts, avoid logging credentials, and make retry behavior explicit instead of allowing a client to repeat an unsafe action blindly.
- Reject unknown or dangerous inputs early.
- Use stderr for local diagnostics rather than corrupting stdio protocol output.
- Return enough status and evidence for a human to review the result.
Inspect discovery before you test the action.
Connect the server to MCP Inspector and verify that initialization succeeds, the tool appears with the expected name and schema, and the description does not overclaim. Then call it with a normal input, a missing field, an invalid value, and a dependency failure.
Keep those cases as a small regression set. A server that works once in a client UI is not finished; the team should be able to reproduce the discovery and call behavior after a dependency or SDK update.
Add a transport and credential boundary deliberately.
Use a local transport while the capability is being designed and inspected. Move to a remote HTTP deployment only after deciding how the server authenticates clients, scopes access, stores secrets, limits rate, and records requests. The deployment step is a change in exposure, not just a different command.
Document the client configuration and a safe shutdown path. A reader should know how to remove the server, rotate a credential, and tell whether a call reached the upstream system.